diff options
-rw-r--r-- | build/b.cxx | 2 | ||||
-rw-r--r-- | build/buildfile | 3 | ||||
-rw-r--r-- | build/config/utility | 7 | ||||
-rw-r--r-- | build/install/module | 21 | ||||
-rw-r--r-- | build/install/module.cxx | 105 | ||||
-rw-r--r-- | build/install/operation | 18 | ||||
-rw-r--r-- | build/install/operation.cxx | 34 | ||||
-rw-r--r-- | build/variable | 12 | ||||
-rw-r--r-- | tests/install/simple/build/bootstrap.build | 4 | ||||
-rw-r--r-- | tests/install/simple/buildfile | 6 | ||||
-rw-r--r-- | tests/install/simple/driver.cxx | 2 |
11 files changed, 207 insertions, 7 deletions
diff --git a/build/b.cxx b/build/b.cxx index 21e72cf..fea5690 100644 --- a/build/b.cxx +++ b/build/b.cxx @@ -45,6 +45,7 @@ using namespace std; #include <build/cxx/module> #include <build/cli/module> #include <build/test/module> +#include <build/install/module> using namespace build; @@ -96,6 +97,7 @@ main (int argc, char* argv[]) builtin_modules["cxx"] = &cxx::cxx_init; builtin_modules["cli"] = &cli::cli_init; builtin_modules["test"] = &test::test_init; + builtin_modules["install"] = &install::install_init; // Figure out work and home directories. // diff --git a/build/buildfile b/build/buildfile index a6715de..ceda4eb 100644 --- a/build/buildfile +++ b/build/buildfile @@ -9,11 +9,12 @@ bin = bin/{target rule module} cxx = cxx/{target compile link module utility} cli = cli/{target rule module} test = test/{operation rule module} +install = install/{operation module} exe{b}: cxx{b algorithm name operation spec scope variable target \ prerequisite rule file module context search diagnostics token \ lexer parser path-io utility dump options $config $bin $cxx $cli \ - $test} $libs + $test $install} $libs #@@ TODO # diff --git a/build/config/utility b/build/config/utility index e1d81a7..713ab01 100644 --- a/build/config/utility +++ b/build/config/utility @@ -41,6 +41,13 @@ namespace build const T* optional (scope& root, const char* name); + template <typename T> + inline const T* + optional (scope& root, const std::string& name) + { + return optional<T> (root, name.c_str ()); + } + // Add all the values from a variable to the C-string list. T is // either target or scope. // diff --git a/build/install/module b/build/install/module new file mode 100644 index 0000000..240d034 --- /dev/null +++ b/build/install/module @@ -0,0 +1,21 @@ +// file : build/install/module -*- C++ -*- +// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#ifndef BUILD_INSTALL_MODULE +#define BUILD_INSTALL_MODULE + +#include <build/types> +#include <build/module> + +namespace build +{ + namespace install + { + extern "C" void + install_init ( + scope&, scope&, const location&, std::unique_ptr<module>&, bool); + } +} + +#endif // BUILD_INSTALL_MODULE diff --git a/build/install/module.cxx b/build/install/module.cxx new file mode 100644 index 0000000..dc88ec2 --- /dev/null +++ b/build/install/module.cxx @@ -0,0 +1,105 @@ +// file : build/install/module.cxx -*- C++ -*- +// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#include <build/install/module> + +#include <build/scope> +#include <build/target> +#include <build/rule> +#include <build/diagnostics> + +#include <build/config/utility> + +#include <build/install/operation> + +using namespace std; +using namespace butl; + +namespace build +{ + namespace install + { + // Set install.<name> values based on config.install.<name> values + // or the defaults. + // + static void + set_dir (scope& r, const char* name, const char* path, const char* mode) + { + string vn ("config.install."); + vn += name; + + const list_value* pv (config::optional<list_value> (r, vn)); + + vn += ".mode"; + const list_value* mv (config::optional<list_value> (r, vn)); + + vn = "install."; + vn += name; + auto p (r.assign (vn)); + + if (pv != nullptr && !pv->empty ()) + p = *pv; + else if (path != nullptr) + p = path; + + vn += ".mode"; + auto m (r.assign (vn)); + + if (mv != nullptr && !mv->empty ()) + p = *mv; + else if (mode != nullptr) + p = mode; + } + + extern "C" void + install_init (scope& root, + scope& base, + const location& l, + unique_ptr<build::module>&, + bool first) + { + tracer trace ("install::init"); + + if (&root != &base) + fail (l) << "install module must be initialized in bootstrap.build"; + + if (!first) + { + warn (l) << "multiple install module initializations"; + return; + } + + const dir_path& out_root (root.path ()); + level4 ([&]{trace << "for " << out_root;}); + + // Register the install operation. + // + operation_id install_id (root.operations.insert (install)); + + { + auto& rs (base.rules); + + // Register the standard alias rule for the install operation. + // + rs.insert<alias> (install_id, "alias", alias_rule::instance); + } + + // Configuration. + // + // Note that we don't use any defaults -- the location must + // be explicitly specified or the installer will complain if + // and when we try to install. + // + if (first) + { + set_dir (root, "root", nullptr, nullptr); + set_dir (root, "data_root", "root", "644"); + set_dir (root, "exec_root", "root", "755"); + + set_dir (root, "bin", "exec_root/bin", nullptr); + set_dir (root, "sbin", "exec_root/sbin", nullptr); + } + } + } +} diff --git a/build/install/operation b/build/install/operation new file mode 100644 index 0000000..2763d10 --- /dev/null +++ b/build/install/operation @@ -0,0 +1,18 @@ +// file : build/install/operation -*- C++ -*- +// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#ifndef BUILD_INSTALL_OPERATION +#define BUILD_INSTALL_OPERATION + +#include <build/operation> + +namespace build +{ + namespace install + { + extern operation_info install; + } +} + +#endif // BUILD_INSTALL_OPERATION diff --git a/build/install/operation.cxx b/build/install/operation.cxx new file mode 100644 index 0000000..1ba001f --- /dev/null +++ b/build/install/operation.cxx @@ -0,0 +1,34 @@ +// file : build/install/operation.cxx -*- C++ -*- +// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#include <build/install/operation> + +#include <build/config/operation> + +using namespace std; +using namespace butl; + +namespace build +{ + namespace install + { + static operation_id + install_pre (meta_operation_id mo) + { + // Run update as a pre-operation, unless we are disfiguring. + // + return mo != config::disfigure_id ? update_id : 0; + } + + operation_info install { + "install", + "install", + "installing", + "has nothing to install", // We cannot "be installed". + execution_mode::first, + &install_pre, + nullptr + }; + } +} diff --git a/build/variable b/build/variable index 368b2f8..809e7d2 100644 --- a/build/variable +++ b/build/variable @@ -166,20 +166,20 @@ namespace build // template <typename T> bool - belongs (const T& x) const {return map == &x.vars;} + belongs (const T& x) const {return vars == &x.vars;} // Implementation details. // - const variable_map* map; // Variable map to which this value belongs. + const variable_map* vars; // Variable map to which this value belongs. - value_proxy (): map (nullptr), p (nullptr) {} - value_proxy (value_ptr* p, const variable_map* m): map (m), p (p) {} + value_proxy (): vars (nullptr), p (nullptr) {} + value_proxy (value_ptr* p, const variable_map* v): vars (v), p (p) {} template <typename T> - value_proxy (value_ptr& p, const T& x): map (&x.vars), p (&p) {} + value_proxy (value_ptr& p, const T& x): vars (&x.vars), p (&p) {} void - rebind (const value_proxy& x) {map = x.map; p = x.p;} + rebind (const value_proxy& x) {vars = x.vars; p = x.p;} private: value_ptr* p; diff --git a/tests/install/simple/build/bootstrap.build b/tests/install/simple/build/bootstrap.build new file mode 100644 index 0000000..40e665b --- /dev/null +++ b/tests/install/simple/build/bootstrap.build @@ -0,0 +1,4 @@ +project = install-simple +amalgamation = # Disabled. +using config +using install diff --git a/tests/install/simple/buildfile b/tests/install/simple/buildfile new file mode 100644 index 0000000..986f391 --- /dev/null +++ b/tests/install/simple/buildfile @@ -0,0 +1,6 @@ +using cxx + +hxx.ext = hxx +cxx.ext = cxx + +exe{driver}: cxx{driver} diff --git a/tests/install/simple/driver.cxx b/tests/install/simple/driver.cxx new file mode 100644 index 0000000..a444f13 --- /dev/null +++ b/tests/install/simple/driver.cxx @@ -0,0 +1,2 @@ +int main () {} + |