diff options
-rw-r--r-- | build2/cli/init.cxx | 10 | ||||
-rw-r--r-- | libbuild2/bash/init.cxx | 3 | ||||
-rw-r--r-- | libbuild2/bin/init.cxx | 51 | ||||
-rw-r--r-- | libbuild2/c/init.cxx | 36 | ||||
-rw-r--r-- | libbuild2/cc/init.cxx | 28 | ||||
-rw-r--r-- | libbuild2/cc/module.hxx | 4 | ||||
-rw-r--r-- | libbuild2/config/init.cxx | 23 | ||||
-rw-r--r-- | libbuild2/config/init.hxx | 12 | ||||
-rw-r--r-- | libbuild2/config/module.hxx | 2 | ||||
-rw-r--r-- | libbuild2/cxx/init.cxx | 36 | ||||
-rw-r--r-- | libbuild2/dist/init.cxx | 9 | ||||
-rw-r--r-- | libbuild2/dist/init.hxx | 12 | ||||
-rw-r--r-- | libbuild2/dist/module.hxx | 2 | ||||
-rw-r--r-- | libbuild2/in/init.cxx | 6 | ||||
-rw-r--r-- | libbuild2/install/init.cxx | 7 | ||||
-rw-r--r-- | libbuild2/install/init.hxx | 12 | ||||
-rw-r--r-- | libbuild2/module.cxx | 15 | ||||
-rw-r--r-- | libbuild2/module.hxx | 66 | ||||
-rw-r--r-- | libbuild2/scope.hxx | 2 | ||||
-rw-r--r-- | libbuild2/test/init.cxx | 12 | ||||
-rw-r--r-- | libbuild2/test/init.hxx | 12 | ||||
-rw-r--r-- | libbuild2/test/module.hxx | 5 | ||||
-rw-r--r-- | libbuild2/version/init.cxx | 20 | ||||
-rw-r--r-- | libbuild2/version/module.hxx | 2 |
24 files changed, 171 insertions, 216 deletions
diff --git a/build2/cli/init.cxx b/build2/cli/init.cxx index 6125f25..18c7ff9 100644 --- a/build2/cli/init.cxx +++ b/build2/cli/init.cxx @@ -29,16 +29,13 @@ namespace build2 config_init (scope& rs, scope& bs, const location& l, - unique_ptr<module_base>&, bool first, bool optional, - const variable_map& hints) + module_init_extra&) { tracer trace ("cli::config_init"); l5 ([&]{trace << "for " << bs;}); - assert (hints.empty ()); // We don't known any hints. - // Enter variables. // if (first) @@ -300,10 +297,9 @@ namespace build2 init (scope& rs, scope& bs, const location& l, - unique_ptr<module_base>&, bool first, bool optional, - const variable_map& hints) + module_init_extra& extra) { tracer trace ("cli::init"); l5 ([&]{trace << "for " << bs;}); @@ -320,7 +316,7 @@ namespace build2 // if (!cast_false<bool> (bs["cli.config.loaded"])) { - if (!init_module (rs, bs, "cli.config", l, optional, hints)) + if (!init_module (rs, bs, "cli.config", l, optional, extra.hints)) return false; } else if (!cast_false<bool> (bs["cli.config.configured"])) diff --git a/libbuild2/bash/init.cxx b/libbuild2/bash/init.cxx index ed84265..0dc4bab 100644 --- a/libbuild2/bash/init.cxx +++ b/libbuild2/bash/init.cxx @@ -27,10 +27,9 @@ namespace build2 init (scope& rs, scope& bs, const location& l, - unique_ptr<module_base>&, bool first, bool, - const variable_map&) + module_init_extra&) { tracer trace ("bash::init"); l5 ([&]{trace << "for " << bs;}); diff --git a/libbuild2/bin/init.cxx b/libbuild2/bin/init.cxx index 2bb96e8..069315f 100644 --- a/libbuild2/bin/init.cxx +++ b/libbuild2/bin/init.cxx @@ -42,10 +42,9 @@ namespace build2 vars_init (scope& rs, scope&, const location&, - unique_ptr<module_base>&, bool first, bool, - const variable_map&) + module_init_extra&) { tracer trace ("bin::vars_init"); l5 ([&]{trace << "for " << rs;}); @@ -146,10 +145,9 @@ namespace build2 config_init (scope& rs, scope& bs, const location& loc, - unique_ptr<module_base>&, bool first, bool, - const variable_map& hints) + module_init_extra& extra) { tracer trace ("bin::config_init"); l5 ([&]{trace << "for " << bs;}); @@ -288,7 +286,7 @@ namespace build2 bool hint (false); if (!l) { - if (auto hl = hints[var]) + if (auto hl = extra.hints[var]) { l = hl; hint = true; @@ -364,7 +362,7 @@ namespace build2 // if (!l) { - if (auto hl = hints[var]) + if (auto hl = extra.hints[var]) l = hl; } @@ -412,17 +410,16 @@ namespace build2 init (scope& rs, scope& bs, const location& loc, - unique_ptr<module_base>&, bool first, bool, - const variable_map& hints) + module_init_extra& extra) { tracer trace ("bin::init"); l5 ([&]{trace << "for " << bs;}); // Load bin.config. // - load_module (rs, rs, "bin.config", loc, hints); + load_module (rs, rs, "bin.config", loc, extra.hints); // Cache some config values we will be needing below. // @@ -567,17 +564,16 @@ namespace build2 ar_config_init (scope& rs, scope& bs, const location& loc, - unique_ptr<module_base>&, bool first, bool, - const variable_map& hints) + module_init_extra& extra) { tracer trace ("bin::ar_config_init"); l5 ([&]{trace << "for " << bs;}); // Make sure bin.config is loaded. // - load_module (rs, bs, "bin.config", loc, hints); + load_module (rs, bs, "bin.config", loc, extra.hints); // Enter configuration variables. // @@ -715,18 +711,17 @@ namespace build2 ar_init (scope& rs, scope& bs, const location& loc, - unique_ptr<module_base>&, bool, bool, - const variable_map& hints) + module_init_extra& extra) { tracer trace ("bin::ar_init"); l5 ([&]{trace << "for " << bs;}); // Make sure the bin core and ar.config are loaded. // - load_module (rs, bs, "bin", loc, hints); - load_module (rs, bs, "bin.ar.config", loc, hints); + load_module (rs, bs, "bin", loc, extra.hints); + load_module (rs, bs, "bin.ar.config", loc, extra.hints); return true; } @@ -735,17 +730,16 @@ namespace build2 ld_config_init (scope& rs, scope& bs, const location& loc, - unique_ptr<module_base>&, bool first, bool, - const variable_map& hints) + module_init_extra& extra) { tracer trace ("bin::ld_config_init"); l5 ([&]{trace << "for " << bs;}); // Make sure bin.config is loaded. // - load_module (rs, rs, "bin.config", loc, hints); + load_module (rs, rs, "bin.config", loc, extra.hints); // Enter configuration variables. // @@ -808,18 +802,17 @@ namespace build2 ld_init (scope& rs, scope& bs, const location& loc, - unique_ptr<module_base>&, bool, bool, - const variable_map& hints) + module_init_extra& extra) { tracer trace ("bin::ld_init"); l5 ([&]{trace << "for " << bs;}); // Make sure the bin core and ld.config are loaded. // - load_module (rs, bs, "bin", loc, hints); - load_module (rs, bs, "bin.ld.config", loc, hints); + load_module (rs, bs, "bin", loc, extra.hints); + load_module (rs, bs, "bin.ld.config", loc, extra.hints); const string& lid (cast<string> (rs["bin.ld.id"])); @@ -841,17 +834,16 @@ namespace build2 rc_config_init (scope& rs, scope& bs, const location& loc, - unique_ptr<module_base>&, bool first, bool, - const variable_map& hints) + module_init_extra& extra) { tracer trace ("bin::rc_config_init"); l5 ([&]{trace << "for " << bs;}); // Make sure bin.config is loaded. // - load_module (rs, bs, "bin.config", loc, hints); + load_module (rs, bs, "bin.config", loc, extra.hints); // Enter configuration variables. // @@ -914,18 +906,17 @@ namespace build2 rc_init (scope& rs, scope& bs, const location& loc, - unique_ptr<module_base>&, bool, bool, - const variable_map& hints) + module_init_extra& extra) { tracer trace ("bin::rc_init"); l5 ([&]{trace << "for " << bs;}); // Make sure the bin core and rc.config are loaded. // - load_module (rs, bs, "bin", loc, hints); - load_module (rs, bs, "bin.rc.config", loc, hints); + load_module (rs, bs, "bin", loc, extra.hints); + load_module (rs, bs, "bin.rc.config", loc, extra.hints); return true; } diff --git a/libbuild2/c/init.cxx b/libbuild2/c/init.cxx index a220169..5939d4c 100644 --- a/libbuild2/c/init.cxx +++ b/libbuild2/c/init.cxx @@ -131,10 +131,9 @@ namespace build2 guess_init (scope& rs, scope& bs, const location& loc, - unique_ptr<module_base>& mod, bool, bool, - const variable_map& hints) + module_init_extra& extra) { tracer trace ("c::guess_init"); l5 ([&]{trace << "for " << bs;}); @@ -258,10 +257,9 @@ namespace build2 // vp.insert_alias (d.c_runtime, "c.runtime"); - assert (mod == nullptr); - config_module* m (new config_module (move (d))); - mod.reset (m); - m->guess (rs, loc, hints); + auto& m (extra.set_module (new config_module (move (d)))); + m.guess (rs, loc, extra.hints); + return true; } @@ -269,10 +267,9 @@ namespace build2 config_init (scope& rs, scope& bs, const location& loc, - unique_ptr<module_base>&, bool, bool, - const variable_map& hints) + module_init_extra& extra) { tracer trace ("c::config_init"); l5 ([&]{trace << "for " << bs;}); @@ -282,11 +279,11 @@ namespace build2 if (&rs != &bs) fail (loc) << "c.config module must be loaded in project root"; - // Load c.guess. + // Load c.guess and share its module instance as ours. // - auto& cm (load_module<config_module> (rs, rs, "c.guess", loc, hints)); + extra.module = load_module (rs, rs, "c.guess", loc, extra.hints); + extra.module_as<config_module> ().init (rs, loc, extra.hints); - cm.init (rs, loc, hints); return true; } @@ -307,10 +304,9 @@ namespace build2 init (scope& rs, scope& bs, const location& loc, - unique_ptr<module_base>& mod, bool, bool, - const variable_map& hints) + module_init_extra& extra) { tracer trace ("c::init"); l5 ([&]{trace << "for " << bs;}); @@ -322,11 +318,8 @@ namespace build2 // Load c.config. // - // @@ TODO: move guess to config and use return value? - // - load_module (rs, rs, "c.config", loc, hints); - - config_module& cm (*rs.find_module<config_module> ("c.guess")); + auto& cm ( + load_module<config_module> (rs, rs, "c.config", loc, extra.hints)); cc::data d { cm, @@ -363,10 +356,9 @@ namespace build2 inc }; - assert (mod == nullptr); - module* m; - mod.reset (m = new module (move (d))); - m->init (rs, loc, hints); + auto& m (extra.set_module (new module (move (d)))); + m.init (rs, loc, extra.hints); + return true; } diff --git a/libbuild2/cc/init.cxx b/libbuild2/cc/init.cxx index 0536e0f..436de3b 100644 --- a/libbuild2/cc/init.cxx +++ b/libbuild2/cc/init.cxx @@ -62,10 +62,9 @@ namespace build2 core_vars_init (scope& rs, scope&, const location& loc, - unique_ptr<module_base>&, bool first, bool, - const variable_map&) + module_init_extra&) { tracer trace ("cc::core_vars_init"); l5 ([&]{trace << "for " << rs;}); @@ -159,16 +158,17 @@ namespace build2 core_guess_init (scope& rs, scope&, const location& loc, - unique_ptr<module_base>&, bool first, bool, - const variable_map& h) + module_init_extra& extra) { tracer trace ("cc::core_guess_init"); l5 ([&]{trace << "for " << rs;}); assert (first); + auto& h (extra.hints); + // Load cc.core.vars. // load_module (rs, rs, "cc.core.vars", loc); @@ -232,10 +232,9 @@ namespace build2 core_config_init (scope& rs, scope&, const location& loc, - unique_ptr<module_base>&, bool first, bool, - const variable_map& hints) + module_init_extra& extra) { tracer trace ("cc::core_config_init"); l5 ([&]{trace << "for " << rs;}); @@ -296,7 +295,7 @@ namespace build2 h.assign ("config.bin.target") = cast<target_triplet> (rs["cc.target"]).string (); - if (auto l = hints["config.bin.pattern"]) + if (auto l = extra.hints["config.bin.pattern"]) h.assign ("config.bin.pattern") = cast<string> (l); } @@ -342,10 +341,9 @@ namespace build2 core_init (scope& rs, scope&, const location& loc, - unique_ptr<module_base>&, bool first, bool, - const variable_map& hints) + module_init_extra& extra) { tracer trace ("cc::core_init"); l5 ([&]{trace << "for " << rs;}); @@ -356,7 +354,7 @@ namespace build2 // Load cc.core.config. // - load_module (rs, rs, "cc.core.config", loc, hints); + load_module (rs, rs, "cc.core.config", loc, extra.hints); // Load the bin module. // @@ -433,34 +431,32 @@ namespace build2 config_init (scope& rs, scope& bs, const location& loc, - unique_ptr<module_base>&, bool, bool, - const variable_map& hints) + module_init_extra& extra) { tracer trace ("cc::config_init"); return init_alias (trace, rs, bs, "cc.config", "c.config", "c.config.loaded", "cxx.config", "cxx.config.loaded", - loc, hints); + loc, extra.hints); } bool init (scope& rs, scope& bs, const location& loc, - unique_ptr<module_base>&, bool, bool, - const variable_map& hints) + module_init_extra& extra) { tracer trace ("cc::init"); return init_alias (trace, rs, bs, "cc", "c", "c.loaded", "cxx", "cxx.loaded", - loc, hints); + loc, extra.hints); } static const module_functions mod_functions[] = diff --git a/libbuild2/cc/module.hxx b/libbuild2/cc/module.hxx index 77fe55c..5c7b8ab 100644 --- a/libbuild2/cc/module.hxx +++ b/libbuild2/cc/module.hxx @@ -25,7 +25,7 @@ namespace build2 { struct compiler_info; - class LIBBUILD2_CC_SYMEXPORT config_module: public module_base, + class LIBBUILD2_CC_SYMEXPORT config_module: public build2::module, public virtual config_data { public: @@ -81,7 +81,7 @@ namespace build2 bool new_; // See guess() and init() for details. }; - class LIBBUILD2_CC_SYMEXPORT module: public module_base, + class LIBBUILD2_CC_SYMEXPORT module: public build2::module, public virtual common, link_rule, compile_rule, diff --git a/libbuild2/config/init.cxx b/libbuild2/config/init.cxx index a7f3fc3..2f47486 100644 --- a/libbuild2/config/init.cxx +++ b/libbuild2/config/init.cxx @@ -30,7 +30,7 @@ namespace build2 functions (function_map&); // functions.cxx bool - boot (scope& rs, const location&, unique_ptr<module_base>& mod) + boot (scope& rs, const location&, module_boot_extra& extra) { tracer trace ("config::boot"); @@ -113,17 +113,15 @@ namespace build2 // vp.insert ("config.import"); - unique_ptr<module> m (new module); + auto& m (extra.set_module (new module)); // Adjust priority for the config module and import pseudo-module so // that their variables come first in config.build. // - m->save_module ("config", INT32_MIN); - m->save_module ("import", INT32_MIN); + m.save_module ("config", INT32_MIN); + m.save_module ("import", INT32_MIN); - m->save_variable (c_p, omit_null); - - mod = move (m); + m.save_variable (c_p, omit_null); } // Register the config function family if this is the first instance of @@ -149,10 +147,9 @@ namespace build2 init (scope& rs, scope&, const location& l, - unique_ptr<module_base>& mod, bool first, bool, - const variable_map& config_hints) + module_init_extra& extra) { tracer trace ("config::init"); @@ -164,8 +161,6 @@ namespace build2 l5 ([&]{trace << "for " << rs;}); - assert (config_hints.empty ()); // We don't known any hints. - auto& vp (rs.var_pool ()); auto& c_l (vp.insert<paths> ("config.config.load", true /* ovr */)); auto& c_v (vp.insert<uint64_t> ("config.version", false /*ovr*/)); @@ -266,9 +261,11 @@ namespace build2 // Cache the config.config.persist value, if any. // - if (mod != nullptr) + if (extra.module != nullptr) { - static_cast<module&> (*mod).persist = + auto& m (extra.module_as<module> ()); + + m.persist = cast_null<vector<pair<string, string>>> ( rs["config.config.persist"]); } diff --git a/libbuild2/config/init.hxx b/libbuild2/config/init.hxx index d6a1e08..d602ec9 100644 --- a/libbuild2/config/init.hxx +++ b/libbuild2/config/init.hxx @@ -16,18 +16,6 @@ namespace build2 { namespace config { - bool - boot (scope&, const location&, unique_ptr<module_base>&); - - bool - init (scope&, - scope&, - const location&, - unique_ptr<module_base>&, - bool, - bool, - const variable_map&); - // Module `config` requires bootstrapping. // // `config` -- registers the configure and disfigure meta-operations, diff --git a/libbuild2/config/module.hxx b/libbuild2/config/module.hxx index 0a35369..297db0a 100644 --- a/libbuild2/config/module.hxx +++ b/libbuild2/config/module.hxx @@ -74,7 +74,7 @@ namespace build2 } }; - struct module: module_base + struct module: build2::module { config::saved_modules saved_modules; diff --git a/libbuild2/cxx/init.cxx b/libbuild2/cxx/init.cxx index cf27aaa..719a88a 100644 --- a/libbuild2/cxx/init.cxx +++ b/libbuild2/cxx/init.cxx @@ -353,10 +353,9 @@ namespace build2 guess_init (scope& rs, scope& bs, const location& loc, - unique_ptr<module_base>& mod, bool, bool, - const variable_map& hints) + module_init_extra& extra) { tracer trace ("cxx::guess_init"); l5 ([&]{trace << "for " << bs;}); @@ -504,10 +503,9 @@ namespace build2 vp.insert_alias (d.c_runtime, "cxx.runtime"); vp.insert_alias (d.c_module_name, "cxx.module_name"); - assert (mod == nullptr); - config_module* m (new config_module (move (d))); - mod.reset (m); - m->guess (rs, loc, hints); + auto& m (extra.set_module (new config_module (move (d)))); + m.guess (rs, loc, extra.hints); + return true; } @@ -515,10 +513,9 @@ namespace build2 config_init (scope& rs, scope& bs, const location& loc, - unique_ptr<module_base>&, bool, bool, - const variable_map& hints) + module_init_extra& extra) { tracer trace ("cxx::config_init"); l5 ([&]{trace << "for " << bs;}); @@ -528,11 +525,11 @@ namespace build2 if (&rs != &bs) fail (loc) << "cxx.config module must be loaded in project root"; - // Load cxx.guess. + // Load cxx.guess and share its module instance as ours. // - auto& cm (load_module<config_module> (rs, rs, "cxx.guess", loc, hints)); + extra.module = load_module (rs, rs, "cxx.guess", loc, extra.hints); + extra.module_as<config_module> ().init (rs, loc, extra.hints); - cm.init (rs, loc, hints); return true; } @@ -561,10 +558,9 @@ namespace build2 init (scope& rs, scope& bs, const location& loc, - unique_ptr<module_base>& mod, bool, bool, - const variable_map& hints) + module_init_extra& extra) { tracer trace ("cxx::init"); l5 ([&]{trace << "for " << bs;}); @@ -576,11 +572,8 @@ namespace build2 // Load cxx.config. // - // @@ TODO: move guess to config and use return value? - // - load_module (rs, rs, "cxx.config", loc, hints); - - config_module& cm (*rs.find_module<config_module> ("cxx.guess")); + auto& cm ( + load_module<config_module> (rs, rs, "cxx.config", loc, extra.hints)); auto& vp (rs.var_pool ()); @@ -630,10 +623,9 @@ namespace build2 inc }; - assert (mod == nullptr); - module* m; - mod.reset (m = new module (move (d))); - m->init (rs, loc, hints); + auto& m (extra.set_module (new module (move (d)))); + m.init (rs, loc, extra.hints); + return true; } diff --git a/libbuild2/dist/init.cxx b/libbuild2/dist/init.cxx index 93bcfdb..30cd56b 100644 --- a/libbuild2/dist/init.cxx +++ b/libbuild2/dist/init.cxx @@ -24,7 +24,7 @@ namespace build2 static const rule rule_; bool - boot (scope& rs, const location&, unique_ptr<module_base>& mod) + boot (scope& rs, const location&, module_boot_extra& extra) { tracer trace ("dist::boot"); @@ -77,7 +77,7 @@ namespace build2 // Create the module. // - mod.reset (new module (v_d_p)); + extra.set_module (new module (v_d_p)); return false; } @@ -86,10 +86,9 @@ namespace build2 init (scope& rs, scope&, const location& l, - unique_ptr<module_base>&, bool first, bool, - const variable_map& config_hints) + module_init_extra&) { tracer trace ("dist::init"); @@ -101,8 +100,6 @@ namespace build2 l5 ([&]{trace << "for " << rs;}); - assert (config_hints.empty ()); // We don't known any hints. - // Register our wildcard rule. Do it explicitly for the alias to prevent // something like insert<target>(dist_id, test_id) taking precedence. // diff --git a/libbuild2/dist/init.hxx b/libbuild2/dist/init.hxx index ffaa91d..6069252 100644 --- a/libbuild2/dist/init.hxx +++ b/libbuild2/dist/init.hxx @@ -16,18 +16,6 @@ namespace build2 { namespace dist { - bool - boot (scope&, const location&, unique_ptr<module_base>&); - - bool - init (scope&, - scope&, - const location&, - unique_ptr<module_base>&, - bool, - bool, - const variable_map&); - // Module `dist` requires bootstrapping. // // `dist` -- registers the dist meta-operation, registers/sets variables, diff --git a/libbuild2/dist/module.hxx b/libbuild2/dist/module.hxx index abc1400..983aebc 100644 --- a/libbuild2/dist/module.hxx +++ b/libbuild2/dist/module.hxx @@ -17,7 +17,7 @@ namespace build2 { namespace dist { - struct LIBBUILD2_SYMEXPORT module: module_base + struct LIBBUILD2_SYMEXPORT module: build2::module { static const string name; diff --git a/libbuild2/in/init.cxx b/libbuild2/in/init.cxx index debdb45..bbf5d43 100644 --- a/libbuild2/in/init.cxx +++ b/libbuild2/in/init.cxx @@ -23,10 +23,9 @@ namespace build2 base_init (scope& rs, scope&, const location&, - unique_ptr<module_base>&, bool first, bool, - const variable_map&) + module_init_extra&) { tracer trace ("in::base_init"); l5 ([&]{trace << "for " << rs;}); @@ -74,10 +73,9 @@ namespace build2 init (scope& rs, scope& bs, const location& loc, - unique_ptr<module_base>&, bool, bool, - const variable_map&) + module_init_extra&) { tracer trace ("in::init"); l5 ([&]{trace << "for " << bs;}); diff --git a/libbuild2/install/init.cxx b/libbuild2/install/init.cxx index fdcc627..5aa5b1d 100644 --- a/libbuild2/install/init.cxx +++ b/libbuild2/install/init.cxx @@ -129,7 +129,7 @@ namespace build2 functions (function_map&); // functions.cxx bool - boot (scope& rs, const location&, unique_ptr<module_base>&) + boot (scope& rs, const location&, module_boot_extra&) { tracer trace ("install::boot"); l5 ([&]{trace << "for " << rs;}); @@ -174,10 +174,9 @@ namespace build2 init (scope& rs, scope& bs, const location& l, - unique_ptr<module_base>&, bool first, bool, - const variable_map& config_hints) + module_init_extra&) { tracer trace ("install::init"); @@ -189,8 +188,6 @@ namespace build2 l5 ([&]{trace << "for " << rs;}); - assert (config_hints.empty ()); // We don't known any hints. - // Enter module variables. // auto& vp (rs.var_pool ()); diff --git a/libbuild2/install/init.hxx b/libbuild2/install/init.hxx index 353b24b..5506744 100644 --- a/libbuild2/install/init.hxx +++ b/libbuild2/install/init.hxx @@ -16,18 +16,6 @@ namespace build2 { namespace install { - bool - boot (scope&, const location&, unique_ptr<module_base>&); - - bool - init (scope&, - scope&, - const location&, - unique_ptr<module_base>&, - bool, - bool, - const variable_map&); - // Module `install` requires bootstrapping. // // `install` -- registers the install, uninstall, and update-for-install diff --git a/libbuild2/module.cxx b/libbuild2/module.cxx index cc79af0..191853a 100644 --- a/libbuild2/module.cxx +++ b/libbuild2/module.cxx @@ -521,7 +521,11 @@ namespace build2 i = lm.emplace (mod, module_state {true, false, mf.init, nullptr, loc}).first; - i->second.first = mf.boot (rs, loc, i->second.module); + + { + module_boot_extra extra {i->second.module}; + i->second.first = mf.boot (rs, loc, extra); + } rs.assign (rs.var_pool ().insert (mod + ".booted")) = true; } @@ -608,7 +612,12 @@ namespace build2 else { l = i != lm.end (); - c = l && i->second.init (rs, bs, loc, i->second.module, f, opt, hints); + + if ((c = l)) + { + module_init_extra extra {i->second.module, hints}; + c = i->second.init (rs, bs, loc, f, opt, extra); + } lv = l; cv = c; @@ -641,7 +650,7 @@ namespace build2 init_module (rs, bs, name, loc, opt, hints); } - unique_ptr<module_base>& + const shared_ptr<module>& load_module (scope& rs, scope& bs, const string& name, diff --git a/libbuild2/module.hxx b/libbuild2/module.hxx index 00084c0..3b3dd53 100644 --- a/libbuild2/module.hxx +++ b/libbuild2/module.hxx @@ -22,23 +22,62 @@ namespace build2 // A few high-level notes on the terminology: From the user's perspective, // the module is "loaded" (with the `using` directive). From the // implementation's perspectives, the module library is "loaded" and the - // module is "bootstrapped" (or "booted" for short) and then "initialized" - // (or "inited"). + // module is optionally "bootstrapped" (or "booted" for short) and then + // "initialized" (or "inited"). - class module_base + // Base class for module instance. + // + class module { public: virtual - ~module_base () = default; + ~module () = default; + }; + + // Module boot function signature. + // + // The module_*_extra arguments (here and in init below) are used to pass + // additional information that is only used by some modules. It is also a + // way for us to later pass more information without breaking source + // compatibility. + // + struct module_boot_extra + { + shared_ptr<build2::module>& module; // Module instance (out). + + // Convenience functions. + // + template <typename T> + T& set_module (T* p) {assert (!module); module.reset (p); return *p;} + + template <typename T> + T& module_as () {assert (module); return static_cast<T&> (*module);} }; // Return true if the module should be initialized first (the order of - // initialization within each group is unspecified). + // initialization within the resulting two groups of modules is + // unspecified). // using module_boot_function = bool (scope& root, const location&, - unique_ptr<module_base>&); + module_boot_extra&); + + // Module init function signature. + // + struct module_init_extra + { + shared_ptr<build2::module>& module; // Module instance (in/out). + const variable_map& hints; // Configuration hints (see below). + + // Convenience functions. + // + template <typename T> + T& set_module (T* p) {assert (!module); module.reset (p); return *p;} + + template <typename T> + T& module_as () {assert (module); return static_cast<T&> (*module);} + }; // Return false if the module configuration (normally based on the default // values) was unsuccessful but this is not (yet) an error. One example @@ -50,13 +89,13 @@ namespace build2 bool (scope& root, scope& base, const location&, - unique_ptr<module_base>&, bool first, // First time for this project. bool optional, // Loaded with using? (optional module). - const variable_map& hints); // Configuration hints (see below). + module_init_extra&); // If the boot function is not NULL, then such a module is said to require - // bootstrapping and must be loaded in bootstrap.build. + // bootstrapping and must be loaded in bootstrap.build. Such a module cannot + // be optional. // struct module_functions { @@ -88,7 +127,7 @@ namespace build2 bool boot; // True if the module boot'ed but not yet init'ed. bool first; // True if the boot'ed module must be init'ed first. module_init_function* init; - unique_ptr<module_base> module; + shared_ptr<build2::module> module; const location loc; // Boot location. }; @@ -142,10 +181,9 @@ namespace build2 bool optional, const variable_map& config_hints = empty_variable_map); - // As above but always load and return a reference to the module instance - // pointer (so it can be moved). + // As above but always load and return a pointer to the module instance. // - LIBBUILD2_SYMEXPORT unique_ptr<module_base>& + LIBBUILD2_SYMEXPORT const shared_ptr<module>& load_module (scope& root, scope& base, const string& name, @@ -173,7 +211,7 @@ namespace build2 // The loaded_modules map is locked per top-level (as opposed to nested) // context (see context.hxx for details). // - // Note: should only be constructed during context-wide serial execution. + // Note: should only be constructed during contexts-wide serial execution. // class LIBBUILD2_SYMEXPORT loaded_modules_lock { diff --git a/libbuild2/scope.hxx b/libbuild2/scope.hxx index dd2831c..f9dd8d9 100644 --- a/libbuild2/scope.hxx +++ b/libbuild2/scope.hxx @@ -399,7 +399,7 @@ namespace build2 bool find_module (const string& name) const { - return root_extra->modules.find_module<module_base> (name) != nullptr; + return root_extra->modules.find_module<module> (name) != nullptr; } template <typename T> diff --git a/libbuild2/test/init.cxx b/libbuild2/test/init.cxx index 6a13990..ec95927 100644 --- a/libbuild2/test/init.cxx +++ b/libbuild2/test/init.cxx @@ -25,7 +25,7 @@ namespace build2 namespace test { bool - boot (scope& rs, const location&, unique_ptr<module_base>& mod) + boot (scope& rs, const location&, module_boot_extra& extra) { tracer trace ("test::boot"); @@ -116,7 +116,8 @@ namespace build2 v = cast<target_triplet> (rs.ctx.global_scope["build.host"]); } - mod.reset (new module (move (d))); + extra.set_module (new module (move (d))); + return false; } @@ -124,10 +125,9 @@ namespace build2 init (scope& rs, scope&, const location& l, - unique_ptr<module_base>& mod, bool first, bool, - const variable_map& config_hints) + module_init_extra& extra) { tracer trace ("test::init"); @@ -139,12 +139,10 @@ namespace build2 l5 ([&]{trace << "for " << rs;}); - assert (mod != nullptr); - module& m (static_cast<module&> (*mod)); + auto& m (extra.module_as<module> ()); // Configure. // - assert (config_hints.empty ()); // We don't known any hints. // Adjust module priority so that the config.test.* values are saved at // the end of config.build. diff --git a/libbuild2/test/init.hxx b/libbuild2/test/init.hxx index 49cdb14..7683858 100644 --- a/libbuild2/test/init.hxx +++ b/libbuild2/test/init.hxx @@ -16,18 +16,6 @@ namespace build2 { namespace test { - bool - boot (scope&, const location&, unique_ptr<module_base>&); - - bool - init (scope&, - scope&, - const location&, - unique_ptr<module_base>&, - bool, - bool, - const variable_map&); - // Module `test` requires bootstrapping. // // `test` -- registers the test and update-for-test operations, registers/ diff --git a/libbuild2/test/module.hxx b/libbuild2/test/module.hxx index 584cb84..af06434 100644 --- a/libbuild2/test/module.hxx +++ b/libbuild2/test/module.hxx @@ -17,7 +17,10 @@ namespace build2 { namespace test { - struct module: module_base, virtual common, default_rule, group_rule + struct module: build2::module, + virtual common, + default_rule, + group_rule { const test::group_rule& group_rule () const diff --git a/libbuild2/version/init.cxx b/libbuild2/version/init.cxx index f69e416..d07198c 100644 --- a/libbuild2/version/init.cxx +++ b/libbuild2/version/init.cxx @@ -32,7 +32,7 @@ namespace build2 static const manifest_install_rule manifest_install_rule_; bool - boot (scope& rs, const location& l, unique_ptr<module_base>& mod) + boot (scope& rs, const location& l, module_boot_extra& extra) { tracer trace ("version::boot"); l5 ([&]{trace << "for " << rs;}); @@ -271,13 +271,14 @@ namespace build2 set ("version.revision", uint64_t (v.revision)); - // Create the module. + // Create the module instance. // - mod.reset (new module (cast<project_name> (rs.vars[ctx.var_project]), - move (v), - committed, - rewritten, - move (ds))); + extra.set_module ( + new module (cast<project_name> (rs.vars[ctx.var_project]), + move (v), + committed, + rewritten, + move (ds))); return true; // Init first (dist.package, etc). } @@ -289,10 +290,9 @@ namespace build2 init (scope& rs, scope&, const location& l, - unique_ptr<module_base>& mod, bool first, bool, - const variable_map&) + module_init_extra& extra) { tracer trace ("version::init"); @@ -305,7 +305,7 @@ namespace build2 // load_module (rs, rs, "in.base", l); - module& m (static_cast<module&> (*mod)); + auto& m (extra.module_as<module> ()); const standard_version& v (m.version); // If the dist module is used, set its dist.package and register the diff --git a/libbuild2/version/module.hxx b/libbuild2/version/module.hxx index 174da7b..4d51d4e 100644 --- a/libbuild2/version/module.hxx +++ b/libbuild2/version/module.hxx @@ -29,7 +29,7 @@ namespace build2 using dependencies = std::map<string, dependency>; - struct module: module_base + struct module: build2::module { using dependencies_type = version::dependencies; |