From 49d5628e35593a5300d39596286c768d7aa435b6 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 7 Jul 2015 09:18:22 +0200 Subject: Rework module architecture Now the target type and rule maps are in scopes (builtins -- in global scope). We also now have the map of loaded modules in the root scope of each project. --- build/cli/module | 4 +-- build/cli/module.cxx | 72 +++++++++++++++++++++++++++++----------------------- 2 files changed, 42 insertions(+), 34 deletions(-) (limited to 'build/cli') diff --git a/build/cli/module b/build/cli/module index c2bc0ab..cf6258f 100644 --- a/build/cli/module +++ b/build/cli/module @@ -12,8 +12,8 @@ namespace build { namespace cli { - void - init (scope&, scope&, const location&); + extern "C" void + cli_init (scope&, scope&, const location&, std::unique_ptr&, bool); } } diff --git a/build/cli/module.cxx b/build/cli/module.cxx index d3fa87d..c1d0aab 100644 --- a/build/cli/module.cxx +++ b/build/cli/module.cxx @@ -13,7 +13,6 @@ #include #include -#include #include @@ -29,54 +28,62 @@ namespace build { static compile compile_; - void - init (scope& root, scope& base, const location& l) + extern "C" void + cli_init (scope& root, + scope& base, + const location& l, + std::unique_ptr&, + bool first) { - //@@ TODO: avoid multiple inits (generally, for modules). - // tracer trace ("cli::init"); + level4 ([&]{trace << "for " << base.path ();}); - //@@ Should it be this way? + // Make sure the cxx module has been loaded since we need its + // targets types (?xx{}). Note that we don't try to load it + // ourselves because of the non-trivial variable merging + // semantics. So it is better to let the user load cxx + // explicitly. // - if (&root != &base) - fail (l) << "cli module must be initialized in project root scope"; + if (base.find_target_type ("cxx") == nullptr) + fail (l) << "cxx module must be initialized before cli"; - // Initialize the cxx module. We need its targets types (?xx{}). - // @@ Or better require it? + // Register target types. // - cxx::init (root, base, l); - - const dir_path& out_root (root.path ()); - level4 ([&]{trace << "for " << out_root;}); + { + auto& tts (base.target_types); - // Register our target types. - // - target_types.insert (cli::static_type); - target_types.insert (cli_cxx::static_type); + tts.insert (); + tts.insert (); + } // Register our rules. // - rules[default_id][typeid (cli_cxx)].emplace ("cli.compile", compile_); - rules[update_id][typeid (cli_cxx)].emplace ("cli.compile", compile_); - rules[clean_id][typeid (cli_cxx)].emplace ("cli.compile", compile_); + { + auto& rs (base.rules); - rules[default_id][typeid (cxx::cxx)].emplace ("cli.compile", compile_); - rules[update_id][typeid (cxx::cxx)].emplace ("cli.compile", compile_); - rules[clean_id][typeid (cxx::cxx)].emplace ("cli.compile", compile_); + rs.insert (default_id, "cli.compile", compile_); + rs.insert (update_id, "cli.compile", compile_); + rs.insert (clean_id, "cli.compile", compile_); - rules[default_id][typeid (cxx::hxx)].emplace ("cli.compile", compile_); - rules[update_id][typeid (cxx::hxx)].emplace ("cli.compile", compile_); - rules[clean_id][typeid (cxx::hxx)].emplace ("cli.compile", compile_); + rs.insert (default_id, "cli.compile", compile_); + rs.insert (update_id, "cli.compile", compile_); + rs.insert (clean_id, "cli.compile", compile_); - rules[default_id][typeid (cxx::ixx)].emplace ("cli.compile", compile_); - rules[update_id][typeid (cxx::ixx)].emplace ("cli.compile", compile_); - rules[clean_id][typeid (cxx::ixx)].emplace ("cli.compile", compile_); + rs.insert (default_id, "cli.compile", compile_); + rs.insert (update_id, "cli.compile", compile_); + rs.insert (clean_id, "cli.compile", compile_); + + rs.insert (default_id, "cli.compile", compile_); + rs.insert (update_id, "cli.compile", compile_); + rs.insert (clean_id, "cli.compile", compile_); + } // Configure. // // config.cli // + if (first) { auto r (config::required (root, "config.cli", "cli")); @@ -132,10 +139,11 @@ namespace build // config.cli.options // // This one is optional. We also merge it into the corresponding - // cli.* variables. + // cli.* variables. See the cxx module for more information on + // this merging semantics and some of its tricky aspects. // if (auto* v = config::optional (root, "config.cli.options")) - root.append ("cli.options") += *v; + base.assign ("cli.options") += *v; } } } -- cgit v1.1