// file : build2/install/init.cxx -*- C++ -*- // copyright : Copyright (c) 2014-2016 Code Synthesis Ltd // license : MIT; see accompanying LICENSE file #include #include #include #include #include #include #include #include #include #include using namespace std; using namespace butl; namespace build2 { namespace install { // Set install..* values based on config.install..* ones // or the defaults. If none of config.install.* values were specified, // then we do omitted/delayed configuration. Note that we still need // to set all the install.* values to defaults, as if we had the // default configuration. // // If override is true, then override values that came from outer // configurations. We have to do this for paths that contain the // package name. // template static void set_var (bool spec, scope& r, const char* name, const char* var, const CT* dv, bool override = false) { string vn; const value* cv (nullptr); if (spec) { vn = "config.install."; vn += name; vn += var; const variable& vr (var_pool.insert (move (vn), true)); cv = dv != nullptr ? &config::required (r, vr, *dv, override).first.get () : &config::optional (r, vr); } vn = "install."; vn += name; vn += var; const variable& vr (var_pool.insert (move (vn))); // Not overridable. value& v (r.assign (vr)); if (spec) { if (*cv && !cv->empty ()) // @@ BC LT [null] v = cast (*cv); // Strip CT to T. } else { if (dv != nullptr) v = *dv; } } template static void set_dir (bool s, // specified scope& r, // root scope const char* n, // var name const T& p, // path bool o = false, // override const string& fm = string (), // file mode const string& dm = string (), // dir mode const build2::path& c = build2::path ()) // command { using build2::path; set_var (s, r, n, "", p.empty () ? nullptr : &p, o); set_var (s, r, n, ".mode", fm.empty () ? nullptr : &fm); set_var (s, r, n, ".dir_mode", dm.empty () ? nullptr : &dm); set_var (s, r, n, ".sudo", (string*) (nullptr)); set_var (s, r, n, ".cmd", c.empty () ? nullptr : &c); set_var (s, r, n, ".options", (strings*) (nullptr)); // This one doesn't have config.* value (only set in a buildfile). // var_pool.insert (string ("install.") + n + ".subdirs"); } static alias_rule alias_; static file_rule file_; void boot (scope& r, const location&, unique_ptr&) { tracer trace ("install::boot"); l5 ([&]{trace << "for " << r.out_path ();}); // Register the install operation. // r.operations.insert (install_id, install); } static const dir_path dir_root ("root"); static const dir_path dir_sbin (dir_path ("exec_root") /= "sbin"); static const dir_path dir_bin (dir_path ("exec_root") /= "bin"); static const dir_path dir_lib (dir_path ("exec_root") /= "lib"); static const dir_path dir_libexec (dir_path ("exec_root") /= "libexec"); static const dir_path dir_data (dir_path ("data_root") /= "share"); static const dir_path dir_include (dir_path ("data_root") /= "include"); static const dir_path dir_doc (dir_path (dir_data) /= "doc"); static const dir_path dir_man (dir_path (dir_data) /= "man"); static const dir_path dir_man1 (dir_path ("man") /= "man1"); bool init (scope& r, scope& b, const location& l, unique_ptr&, bool first, bool, const variable_map& config_hints) { tracer trace ("install::init"); if (!first) { warn (l) << "multiple install module initializations"; return true; } const dir_path& out_root (r.out_path ()); l5 ([&]{trace << "for " << out_root;}); assert (config_hints.empty ()); // We don't known any hints. // Enter module variables. // // Note that the set_dir() calls below enter some more. // { auto& v (var_pool); // Note: not overridable. // v.insert ("install"); v.insert ("install.mode"); } // Register our alias and file installer rule. // b.rules.insert (perform_install_id, "install.alias", alias_); b.rules.insert (perform_install_id, "install.file", file_); // Configuration. // // Note that we don't use any defaults for root -- the location // must be explicitly specified or the installer will complain // if and when we try to install. // { using build2::path; bool s (config::specified (r, "config.install")); // Adjust module priority so that the (numerous) config.install.* // values are saved at the end of config.build. // if (s) config::save_module (r, "install", INT32_MAX); const string& n (cast (r["project"])); set_dir (s, r, "root", abs_dir_path (), false, "", "755", path ("install")); set_dir (s, r, "data_root", dir_root, false, "644"); set_dir (s, r, "exec_root", dir_root, false, "755"); set_dir (s, r, "sbin", dir_sbin); set_dir (s, r, "bin", dir_bin); set_dir (s, r, "lib", dir_lib); set_dir (s, r, "libexec", dir_path (dir_libexec) /= n, true); set_dir (s, r, "data", dir_path (dir_data) /= n, true); set_dir (s, r, "include", dir_include); set_dir (s, r, "doc", dir_path (dir_doc) /= n, true); set_dir (s, r, "man", dir_man); set_dir (s, r, "man1", dir_man1); } // Configure "installability" for built-in target types. // install_path (b, dir_path ("doc")); // Install into install.doc. install_path (b, dir_path ("man")); // Install into install.man. install_path (b, dir_path ("man1")); // Install into install.man1. return true; } } }