diff options
-rw-r--r-- | build/bin/module.cxx | 53 | ||||
-rw-r--r-- | build/cli/module.cxx | 44 | ||||
-rw-r--r-- | build/config/module.cxx | 31 | ||||
-rw-r--r-- | build/context.cxx | 58 | ||||
-rw-r--r-- | build/cxx/module.cxx | 131 | ||||
-rw-r--r-- | build/dist/module.cxx | 40 | ||||
-rw-r--r-- | build/install/module.cxx | 22 | ||||
-rw-r--r-- | build/operation | 5 | ||||
-rw-r--r-- | build/rule-map | 8 | ||||
-rw-r--r-- | build/test/module.cxx | 44 |
10 files changed, 235 insertions, 201 deletions
diff --git a/build/bin/module.cxx b/build/bin/module.cxx index c7da647..0813433 100644 --- a/build/bin/module.cxx +++ b/build/bin/module.cxx @@ -43,30 +43,31 @@ namespace build // Register target types. // { - auto& tts (b.target_types); - tts.insert<obja> (); - tts.insert<objso> (); - tts.insert<obj> (); - tts.insert<exe> (); - tts.insert<liba> (); - tts.insert<libso> (); - tts.insert<lib> (); + auto& t (b.target_types); + + t.insert<obja> (); + t.insert<objso> (); + t.insert<obj> (); + t.insert<exe> (); + t.insert<liba> (); + t.insert<libso> (); + t.insert<lib> (); } // Register rules. // { - auto& rs (b.rules); + auto& r (b.rules); - rs.insert<obj> (perform_id, update_id, "bin", obj_); - rs.insert<obj> (perform_id, clean_id, "bin", obj_); + r.insert<obj> (perform_update_id, "bin.obj", obj_); + r.insert<obj> (perform_clean_id, "bin.obj", obj_); - rs.insert<lib> (perform_id, update_id, "bin", lib_); - rs.insert<lib> (perform_id, clean_id, "bin", lib_); + r.insert<lib> (perform_update_id, "bin.lib", lib_); + r.insert<lib> (perform_clean_id, "bin.lib", lib_); - // Configure members. + // Configure member. // - rs.insert<lib> (configure_id, update_id, "lib", lib_); + r.insert<lib> (configure_update_id, "bin.lib", lib_); //@@ Should we check if the install module was loaded // (by checking if install operation is registered @@ -75,22 +76,24 @@ namespace build // should enforce loading of all operation-defining // modules before all others? // - rs.insert<lib> (perform_id, install_id, "bin", lib_); + r.insert<lib> (perform_install_id, "bin.lib", lib_); } // Enter module variables. // if (first) { - var_pool.find ("config.bin.lib", string_type); - var_pool.find ("config.bin.exe.lib", strings_type); - var_pool.find ("config.bin.liba.lib", strings_type); - var_pool.find ("config.bin.libso.lib", strings_type); - - var_pool.find ("bin.lib", string_type); - var_pool.find ("bin.exe.lib", strings_type); - var_pool.find ("bin.liba.lib", strings_type); - var_pool.find ("bin.libso.lib", strings_type); + auto& v (var_pool); + + v.find ("config.bin.lib", string_type); + v.find ("config.bin.exe.lib", strings_type); + v.find ("config.bin.liba.lib", strings_type); + v.find ("config.bin.libso.lib", strings_type); + + v.find ("bin.lib", string_type); + v.find ("bin.exe.lib", strings_type); + v.find ("bin.liba.lib", strings_type); + v.find ("bin.libso.lib", strings_type); } // Configure. diff --git a/build/cli/module.cxx b/build/cli/module.cxx index c44d670..67e2137 100644 --- a/build/cli/module.cxx +++ b/build/cli/module.cxx @@ -52,25 +52,27 @@ namespace build fail (loc) << "cxx module must be loaded before cli"; } - // Register target types. + // Enter module variables. // + if (first) { - auto& tts (base.target_types); + auto& v (var_pool); + + v.find ("config.cli.configured", bool_type); + + v.find ("config.cli", string_type); //@@ VAR type - tts.insert<cli> (); - tts.insert<cli_cxx> (); + v.find ("config.cli.options", strings_type); + v.find ("cli.options", strings_type); } - // Enter module variables. + // Register target types. // - if (first) { - var_pool.find ("config.cli.configured", bool_type); - - var_pool.find ("config.cli", string_type); //@@ VAR type + auto& t (base.target_types); - var_pool.find ("config.cli.options", strings_type); - var_pool.find ("cli.options", strings_type); + t.insert<cli> (); + t.insert<cli_cxx> (); } // Configure. @@ -211,25 +213,25 @@ namespace build // Register our rules. // { - auto& rs (base.rules); + auto& r (base.rules); - rs.insert<cli_cxx> (perform_id, update_id, "cli", compile_); - rs.insert<cli_cxx> (perform_id, clean_id, "cli", compile_); + r.insert<cli_cxx> (perform_update_id, "cli.compile", compile_); + r.insert<cli_cxx> (perform_clean_id, "cli.compile", compile_); - rs.insert<cxx::hxx> (perform_id, update_id, "cli", compile_); - rs.insert<cxx::hxx> (perform_id, clean_id, "cli", compile_); + r.insert<cxx::hxx> (perform_update_id, "cli.compile", compile_); + r.insert<cxx::hxx> (perform_clean_id, "cli.compile", compile_); - rs.insert<cxx::cxx> (perform_id, update_id, "cli", compile_); - rs.insert<cxx::cxx> (perform_id, clean_id, "cli", compile_); + r.insert<cxx::cxx> (perform_update_id, "cli.compile", compile_); + r.insert<cxx::cxx> (perform_clean_id, "cli.compile", compile_); - rs.insert<cxx::ixx> (perform_id, update_id, "cli", compile_); - rs.insert<cxx::ixx> (perform_id, clean_id, "cli", compile_); + r.insert<cxx::ixx> (perform_update_id, "cli.compile", compile_); + r.insert<cxx::ixx> (perform_clean_id, "cli.compile", compile_); // Other rules (e.g., cxx::compile) may need to have the group // members resolved. Looks like a general pattern: groups should // resolve on configure(update). // - rs.insert<cli_cxx> (configure_id, update_id, "cli", compile_); + r.insert<cli_cxx> (configure_update_id, "cli.compile", compile_); } return true; diff --git a/build/config/module.cxx b/build/config/module.cxx index b95c6c7..77a786b 100644 --- a/build/config/module.cxx +++ b/build/config/module.cxx @@ -25,8 +25,8 @@ namespace build static const path config_file ("build/config.build"); extern "C" bool - config_init (scope& r, - scope& b, + config_init (scope& root, + scope& base, const location& l, std::unique_ptr<module>&, bool first, @@ -34,7 +34,7 @@ namespace build { tracer trace ("config::init"); - if (&r != &b) + if (&root != &base) fail (l) << "config module must be initialized in bootstrap.build"; if (!first) @@ -43,29 +43,36 @@ namespace build return true; } - const dir_path& out_root (r.out_path ()); + const dir_path& out_root (root.out_path ()); level5 ([&]{trace << "for " << out_root;}); // Register meta-operations. // - r.meta_operations.insert (configure_id, configure); - r.meta_operations.insert (disfigure_id, disfigure); + root.meta_operations.insert (configure_id, configure); + root.meta_operations.insert (disfigure_id, disfigure); // Register alias and fallback rule for the configure meta-operation. // - global_scope->rules.insert<file> ( - configure_id, 0, "file", file_rule::instance); + { + // We need this rule for out-of-any-project dependencies (e.g., + // libraries imported from /usr/lib). + // + global_scope->rules.insert<file> ( + configure_id, 0, "config.file", file_rule::instance); + + auto& r (root.rules); - r.rules.insert<alias> (configure_id, 0, "alias", alias_rule::instance); - r.rules.insert<file> (configure_id, 0, "", fallback_rule::instance); - r.rules.insert<target> (configure_id, 0, "", fallback_rule::instance); + r.insert<target> (configure_id, 0, "config", fallback_rule::instance); + r.insert<file> (configure_id, 0, "config.file", fallback_rule::instance); + r.insert<alias> (configure_id, 0, "config.alias", alias_rule::instance); + } // Load config.build if one exists. // path f (out_root / config_file); if (file_exists (f)) - source (f, r, r); + source (f, root, root); return true; } diff --git a/build/context.cxx b/build/context.cxx index 7f30c81..f98ca96 100644 --- a/build/context.cxx +++ b/build/context.cxx @@ -59,22 +59,26 @@ namespace build // Enter builtin variables. // - var_pool.find ("work", dir_path_type); - var_pool.find ("home", dir_path_type); + { + auto& v (var_pool); - var_pool.find ("src_root", dir_path_type); - var_pool.find ("out_root", dir_path_type); - var_pool.find ("src_base", dir_path_type); - var_pool.find ("out_base", dir_path_type); + v.find ("work", dir_path_type); + v.find ("home", dir_path_type); - var_pool.find ("project", string_type); - var_pool.find ("amalgamation", dir_path_type); + v.find ("src_root", dir_path_type); + v.find ("out_root", dir_path_type); + v.find ("src_base", dir_path_type); + v.find ("out_base", dir_path_type); - // Shouldn't be typed since the value requires pre-processing. - // - var_pool.find ("subprojects", nullptr, '='); + v.find ("project", string_type); + v.find ("amalgamation", dir_path_type); - var_pool.find ("extension", string_type); + // Shouldn't be typed since the value requires pre-processing. + // + v.find ("subprojects", nullptr, '='); + + v.find ("extension", string_type); + } // Create global scope. For Win32 this is not a "real" root path. // On POSIX, however, this is a real path. See the comment in @@ -89,29 +93,29 @@ namespace build // Register builtin target types. // { - target_type_map& tts (global_scope->target_types); - - tts.insert<file> (); - tts.insert<alias> (); - tts.insert<dir> (); - tts.insert<fsdir> (); - tts.insert<doc> (); - tts.insert<man> (); - tts.insert<man1> (); + target_type_map& t (global_scope->target_types); + + t.insert<file> (); + t.insert<alias> (); + t.insert<dir> (); + t.insert<fsdir> (); + t.insert<doc> (); + t.insert<man> (); + t.insert<man1> (); } // Register builtin rules. // { - rule_map& rs (global_scope->rules); + rule_map& r (global_scope->rules); - rs.insert<alias> (perform_id, 0, "alias", alias_rule::instance); + r.insert<alias> (perform_id, 0, "alias", alias_rule::instance); - rs.insert<fsdir> (perform_id, update_id, "fsdir", fsdir_rule::instance); - rs.insert<fsdir> (perform_id, clean_id, "fsdir", fsdir_rule::instance); + r.insert<fsdir> (perform_update_id, "fsdir", fsdir_rule::instance); + r.insert<fsdir> (perform_clean_id, "fsdir", fsdir_rule::instance); - rs.insert<file> (perform_id, update_id, "file", file_rule::instance); - rs.insert<file> (perform_id, clean_id, "file", file_rule::instance); + r.insert<file> (perform_update_id, "file", file_rule::instance); + r.insert<file> (perform_clean_id, "file", file_rule::instance); } } diff --git a/build/cxx/module.cxx b/build/cxx/module.cxx index 4c0e493..c704ab0 100644 --- a/build/cxx/module.cxx +++ b/build/cxx/module.cxx @@ -48,18 +48,57 @@ namespace build load_module (false, "bin", r, b, loc); } + // Enter module variables. + // + // @@ Probably should only be done on load; make sure reset() unloads + // modules. + // + // @@ Should probably cache the variable pointers so we don't have + // to keep looking them up. + // + if (first) + { + auto& v (var_pool); + + v.find ("config.cxx", string_type); //@@ VAR type + + v.find ("config.cxx.poptions", strings_type); + v.find ("config.cxx.coptions", strings_type); + v.find ("config.cxx.loptions", strings_type); + v.find ("config.cxx.libs", strings_type); + + v.find ("cxx.poptions", strings_type); + v.find ("cxx.coptions", strings_type); + v.find ("cxx.loptions", strings_type); + v.find ("cxx.libs", strings_type); + + v.find ("cxx.export.poptions", strings_type); + v.find ("cxx.export.coptions", strings_type); + v.find ("cxx.export.loptions", strings_type); + v.find ("cxx.export.libs", strings_type); + + v.find ("cxx.std", string_type); + + v.find ("h.ext", string_type); + v.find ("c.ext", string_type); + v.find ("hxx.ext", string_type); + v.find ("ixx.ext", string_type); + v.find ("txx.ext", string_type); + v.find ("cxx.ext", string_type); + } + // Register target types. // { - auto& tts (b.target_types); + auto& t (b.target_types); - tts.insert<h> (); - tts.insert<c> (); + t.insert<h> (); + t.insert<c> (); - tts.insert<cxx> (); - tts.insert<hxx> (); - tts.insert<ixx> (); - tts.insert<txx> (); + t.insert<cxx> (); + t.insert<hxx> (); + t.insert<ixx> (); + t.insert<txx> (); } // Register rules. @@ -67,74 +106,40 @@ namespace build { using namespace bin; - auto& rs (b.rules); + auto& r (b.rules); - rs.insert<obja> (perform_id, update_id, "cxx", compile::instance); - rs.insert<obja> (perform_id, clean_id, "cxx", compile::instance); + r.insert<obja> (perform_update_id, "cxx.compile", compile::instance); - rs.insert<objso> (perform_id, update_id, "cxx", compile::instance); - rs.insert<objso> (perform_id, clean_id, "cxx", compile::instance); + r.insert<obja> (perform_update_id, "cxx.compile", compile::instance); + r.insert<obja> (perform_clean_id, "cxx.compile", compile::instance); - rs.insert<exe> (perform_id, update_id, "cxx", link::instance); - rs.insert<exe> (perform_id, clean_id, "cxx", link::instance); + r.insert<objso> (perform_update_id, "cxx.compile", compile::instance); + r.insert<objso> (perform_clean_id, "cxx.compile", compile::instance); - rs.insert<liba> (perform_id, update_id, "cxx", link::instance); - rs.insert<liba> (perform_id, clean_id, "cxx", link::instance); + r.insert<exe> (perform_update_id, "cxx.link", link::instance); + r.insert<exe> (perform_clean_id, "cxx.link", link::instance); - rs.insert<libso> (perform_id, update_id, "cxx", link::instance); - rs.insert<libso> (perform_id, clean_id, "cxx", link::instance); + r.insert<liba> (perform_update_id, "cxx.link", link::instance); + r.insert<liba> (perform_clean_id, "cxx.link", link::instance); + + r.insert<libso> (perform_update_id, "cxx.link", link::instance); + r.insert<libso> (perform_clean_id, "cxx.link", link::instance); // Register for configure so that we detect unresolved imports // during configuration rather that later, e.g., during update. // - rs.insert<obja> (configure_id, update_id, "cxx", compile::instance); - rs.insert<objso> (configure_id, update_id, "cxx", compile::instance); - rs.insert<exe> (configure_id, update_id, "cxx", link::instance); - rs.insert<liba> (configure_id, update_id, "cxx", link::instance); - rs.insert<libso> (configure_id, update_id, "cxx", link::instance); + r.insert<obja> (configure_update_id, "cxx.compile", compile::instance); + r.insert<objso> (configure_update_id, "cxx.compile", compile::instance); + + r.insert<exe> (configure_update_id, "cxx.link", link::instance); + r.insert<liba> (configure_update_id, "cxx.link", link::instance); + r.insert<libso> (configure_update_id, "cxx.link", link::instance); //@@ Should we check if install module was loaded (see bin)? // - rs.insert<exe> (perform_id, install_id, "cxx", install::instance); - rs.insert<liba> (perform_id, install_id, "cxx", install::instance); - rs.insert<libso> (perform_id, install_id, "cxx", install::instance); - } - - // Enter module variables. - // - // @@ Probably should only be done on load; make sure reset() unloads - // modules. - // - // @@ Should probably cache the variable pointers so we don't have - // to keep looking them up. - // - if (first) - { - var_pool.find ("config.cxx", string_type); //@@ VAR type - - var_pool.find ("config.cxx.poptions", strings_type); - var_pool.find ("config.cxx.coptions", strings_type); - var_pool.find ("config.cxx.loptions", strings_type); - var_pool.find ("config.cxx.libs", strings_type); - - var_pool.find ("cxx.poptions", strings_type); - var_pool.find ("cxx.coptions", strings_type); - var_pool.find ("cxx.loptions", strings_type); - var_pool.find ("cxx.libs", strings_type); - - var_pool.find ("cxx.export.poptions", strings_type); - var_pool.find ("cxx.export.coptions", strings_type); - var_pool.find ("cxx.export.loptions", strings_type); - var_pool.find ("cxx.export.libs", strings_type); - - var_pool.find ("cxx.std", string_type); - - var_pool.find ("h.ext", string_type); - var_pool.find ("c.ext", string_type); - var_pool.find ("hxx.ext", string_type); - var_pool.find ("ixx.ext", string_type); - var_pool.find ("txx.ext", string_type); - var_pool.find ("cxx.ext", string_type); + r.insert<exe> (perform_install_id, "cxx.install", install::instance); + r.insert<liba> (perform_install_id, "cxx.install", install::instance); + r.insert<libso> (perform_install_id, "cxx.install", install::instance); } // Configure. diff --git a/build/dist/module.cxx b/build/dist/module.cxx index a624c20..f0a446b 100644 --- a/build/dist/module.cxx +++ b/build/dist/module.cxx @@ -44,37 +44,39 @@ namespace build const dir_path& out_root (r.out_path ()); level5 ([&]{trace << "for " << out_root;}); - // Register meta-operation. - // - r.meta_operations.insert (dist_id, dist); - - // Register our wildcard rule. Do it explicitly for the alias - // to prevent something like insert<target>(dist_id, test_id) - // taking precedence. - // - r.rules.insert<target> (dist_id, 0, "dist", rule_); - r.rules.insert<alias> (dist_id, 0, "alias", rule_); - // Enter module variables. // if (first) { - var_pool.find ("dist", bool_type); + auto& v (var_pool); + + v.find ("dist", bool_type); - var_pool.find ("dist.package", string_type); + v.find ("dist.package", string_type); - var_pool.find ("dist.root", dir_path_type); - var_pool.find ("config.dist.root", dir_path_type); + v.find ("dist.root", dir_path_type); + v.find ("config.dist.root", dir_path_type); //@@ VAR type // - var_pool.find ("dist.cmd", string_type); - var_pool.find ("config.dist.cmd", string_type); + v.find ("dist.cmd", string_type); + v.find ("config.dist.cmd", string_type); - var_pool.find ("dist.archives", strings_type); - var_pool.find ("config.dist.archives", strings_type); + v.find ("dist.archives", strings_type); + v.find ("config.dist.archives", strings_type); } + // Register meta-operation. + // + r.meta_operations.insert (dist_id, dist); + + // Register our wildcard rule. Do it explicitly for the alias + // to prevent something like insert<target>(dist_id, test_id) + // taking precedence. + // + r.rules.insert<target> (dist_id, 0, "dist", rule_); + r.rules.insert<alias> (dist_id, 0, "dist.alias", rule_); + // Configuration. // // Note that we don't use any defaults for root -- the location diff --git a/build/install/module.cxx b/build/install/module.cxx index 8711341..f8f7d73 100644 --- a/build/install/module.cxx +++ b/build/install/module.cxx @@ -121,24 +121,26 @@ namespace build const dir_path& out_root (r.out_path ()); level5 ([&]{trace << "for " << out_root;}); - // Register the install operation. - // - r.operations.insert (install_id, install); - - // Register our alias and file installer rule. - // - b.rules.insert<alias> (perform_id, install_id, "install.alias", alias_); - b.rules.insert<file> (perform_id, install_id, "install.file", file_); - // Enter module variables. // // Note that the set_dir() calls below enter some more. // if (first) { - var_pool.find ("install", dir_path_type); + auto& v (var_pool); + + v.find ("install", dir_path_type); } + // Register the install operation. + // + r.operations.insert (install_id, install); + + // Register our alias and file installer rule. + // + b.rules.insert<alias> (perform_install_id, "install.alias", alias_); + b.rules.insert<file> (perform_install_id, "install.file", file_); + // Configuration. // // Note that we don't use any defaults for root -- the location diff --git a/build/operation b/build/operation index 8aeede6..d8cbd07 100644 --- a/build/operation +++ b/build/operation @@ -105,10 +105,8 @@ namespace build // Id constants for build-in and pre-defined meta/operations. // const meta_operation_id perform_id = 1; - const meta_operation_id configure_id = 2; const meta_operation_id disfigure_id = 3; - const meta_operation_id dist_id = 4; // The default operation is a special marker that can be used to @@ -117,7 +115,6 @@ namespace build const operation_id default_id = 1; // Shall be first. const operation_id update_id = 2; const operation_id clean_id = 3; - const operation_id test_id = 4; const operation_id install_id = 5; @@ -126,6 +123,8 @@ namespace build const action_id perform_test_id = (perform_id << 4) | test_id; const action_id perform_install_id = (perform_id << 4) | install_id; + const action_id configure_update_id = (configure_id << 4) | update_id; + // Recipe execution mode. // // When a target is a prerequisite of another target, its recipe can be diff --git a/build/rule-map b/build/rule-map index d262ecd..74d1cfc 100644 --- a/build/rule-map +++ b/build/rule-map @@ -68,6 +68,14 @@ namespace build class rule_map { public: + + template <typename T> + void + insert (action_id a, const char* hint, rule& r) + { + insert<T> (a >> 4, a & 0x0F, hint, r); + } + template <typename T> void insert (meta_operation_id mid, operation_id oid, const char* hint, rule& r) diff --git a/build/test/module.cxx b/build/test/module.cxx index 167c09b..19a31d2 100644 --- a/build/test/module.cxx +++ b/build/test/module.cxx @@ -22,8 +22,8 @@ namespace build static rule rule_; extern "C" bool - test_init (scope& r, - scope& b, + test_init (scope& root, + scope& base, const location& l, unique_ptr<module>&, bool first, @@ -31,7 +31,7 @@ namespace build { tracer trace ("test::init"); - if (&r != &b) + if (&root != &base) fail (l) << "test module must be initialized in bootstrap.build"; if (!first) @@ -40,39 +40,41 @@ namespace build return true; } - const dir_path& out_root (r.out_path ()); + const dir_path& out_root (root.out_path ()); level5 ([&]{trace << "for " << out_root;}); + // Enter module variables. + // + { + auto& v (var_pool); + + v.find ("test", bool_type); + v.find ("test.input", name_type); + v.find ("test.output", name_type); + v.find ("test.roundtrip", name_type); + v.find ("test.options", strings_type); + v.find ("test.arguments", strings_type); + } + // Register the test operation. // - r.operations.insert (test_id, test); + root.operations.insert (test_id, test); // Register rules. // { - auto& rs (r.rules); + auto& r (root.rules); // Register our test running rule. // - rs.insert<target> (perform_id, test_id, "test", rule_); + r.insert<target> (perform_test_id, "test", rule_); // Register our rule for the dist meta-operation. We need - // to do this because we have "ad-hoc prerequisites", test - // input/output files, that need to be entered into the + // to do this because we have "ad-hoc prerequisites" (test + // input/output files) that need to be entered into the // target list. // - rs.insert<target> (dist_id, test_id, "test", rule_); - } - - // Enter module variables. - // - { - var_pool.find ("test", bool_type); - var_pool.find ("test.input", name_type); - var_pool.find ("test.output", name_type); - var_pool.find ("test.roundtrip", name_type); - var_pool.find ("test.options", strings_type); - var_pool.find ("test.arguments", strings_type); + r.insert<target> (dist_id, test_id, "test", rule_); } return true; |