diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2015-07-07 09:18:22 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2015-07-07 09:18:22 +0200 |
commit | 49d5628e35593a5300d39596286c768d7aa435b6 (patch) | |
tree | 43f20983a381c54aac7536e78e4f9543d8761aac /build/cli | |
parent | 16c19b739a58845af7f807c3dee8021a1c421006 (diff) |
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.
Diffstat (limited to 'build/cli')
-rw-r--r-- | build/cli/module | 4 | ||||
-rw-r--r-- | build/cli/module.cxx | 72 |
2 files changed, 42 insertions, 34 deletions
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<module>&, 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 <build/diagnostics> #include <build/cxx/target> -#include <build/cxx/module> #include <build/config/utility> @@ -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<module>&, + 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<cli> (); + tts.insert<cli_cxx> (); + } // 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<cli_cxx> (default_id, "cli.compile", compile_); + rs.insert<cli_cxx> (update_id, "cli.compile", compile_); + rs.insert<cli_cxx> (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<cxx::hxx> (default_id, "cli.compile", compile_); + rs.insert<cxx::hxx> (update_id, "cli.compile", compile_); + rs.insert<cxx::hxx> (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<cxx::cxx> (default_id, "cli.compile", compile_); + rs.insert<cxx::cxx> (update_id, "cli.compile", compile_); + rs.insert<cxx::cxx> (clean_id, "cli.compile", compile_); + + rs.insert<cxx::ixx> (default_id, "cli.compile", compile_); + rs.insert<cxx::ixx> (update_id, "cli.compile", compile_); + rs.insert<cxx::ixx> (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<list_value> (root, "config.cli.options")) - root.append ("cli.options") += *v; + base.assign ("cli.options") += *v; } } } |