aboutsummaryrefslogtreecommitdiff
path: root/build/cli
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2015-07-07 09:18:22 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2015-07-07 09:18:22 +0200
commit49d5628e35593a5300d39596286c768d7aa435b6 (patch)
tree43f20983a381c54aac7536e78e4f9543d8761aac /build/cli
parent16c19b739a58845af7f807c3dee8021a1c421006 (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/module4
-rw-r--r--build/cli/module.cxx72
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;
}
}
}