From d91e48ea57b83f7018a25d3f54bba96cf889d66d Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Sun, 16 Aug 2020 10:30:35 +0200 Subject: Add ability to initialize bootstrapped modules after loading root.build --- libbuild2/config/init.cxx | 6 ++++-- libbuild2/dist/init.cxx | 4 +--- libbuild2/file.cxx | 28 +++++++++++++++++++++++----- libbuild2/install/init.cxx | 4 +--- libbuild2/module.cxx | 18 +++++++++--------- libbuild2/module.hxx | 28 +++++++++++++++++++++------- libbuild2/test/init.cxx | 4 +--- libbuild2/version/init.cxx | 6 ++++-- 8 files changed, 64 insertions(+), 34 deletions(-) (limited to 'libbuild2') diff --git a/libbuild2/config/init.cxx b/libbuild2/config/init.cxx index 69da09c..df71fae 100644 --- a/libbuild2/config/init.cxx +++ b/libbuild2/config/init.cxx @@ -28,7 +28,7 @@ namespace build2 void functions (function_map&); // functions.cxx - bool + void boot (scope& rs, const location&, module_boot_extra& extra) { tracer trace ("config::boot"); @@ -139,7 +139,9 @@ namespace build2 rs.insert_meta_operation (configure_id, mo_configure); rs.insert_meta_operation (disfigure_id, mo_disfigure); - return true; // Initialize first (load config.build). + // Initialize first (load config.build). + // + extra.init = module_boot_init::before_first; } // host-config.cxx.in diff --git a/libbuild2/dist/init.cxx b/libbuild2/dist/init.cxx index a95f768..a96d10e 100644 --- a/libbuild2/dist/init.cxx +++ b/libbuild2/dist/init.cxx @@ -22,7 +22,7 @@ namespace build2 { static const rule rule_; - bool + void boot (scope& rs, const location&, module_boot_extra& extra) { tracer trace ("dist::boot"); @@ -74,8 +74,6 @@ namespace build2 // Create the module. // extra.set_module (new module (v_d_p)); - - return false; } bool diff --git a/libbuild2/file.cxx b/libbuild2/file.cxx index 171d136..252f885 100644 --- a/libbuild2/file.cxx +++ b/libbuild2/file.cxx @@ -1446,17 +1446,25 @@ namespace build2 if (scope* rs = root.parent_scope ()->root_scope ()) load_root (*rs); - // Finish off initializing bootstrapped modules. + // Finish off initializing bootstrapped modules (before mode). // - for (auto& s: root.root_extra->modules) + // Note that init() can load additional modules invalidating iterators. + // + size_t boot_mods (root.root_extra->modules.size ()); + + for (size_t i (0); i != boot_mods; ++i) { - if (s.boot && s.first) + module_state& s (root.root_extra->modules[i]); + + if (s.boot_init && *s.boot_init == module_boot_init::before_first) init_module (root, root, s.name, s.loc); } - for (auto& s: root.root_extra->modules) + for (size_t i (0); i != boot_mods; ++i) { - if (s.boot && !s.first) + module_state& s (root.root_extra->modules[i]); + + if (s.boot_init && *s.boot_init == module_boot_init::before) init_module (root, root, s.name, s.loc); } @@ -1482,6 +1490,16 @@ namespace build2 if (fe) {source_once (p, root, root, f, root);} if (he) {p.reset (); source_hooks (p, root, hd, false /* pre */);} + // Finish off initializing bootstrapped modules (after mode). + // + for (size_t i (0); i != boot_mods; ++i) + { + module_state& s (root.root_extra->modules[i]); + + if (s.boot_init && *s.boot_init == module_boot_init::after) + init_module (root, root, s.name, s.loc); + } + // Print the project configuration report, similar to how we do it in // build system modules. // diff --git a/libbuild2/install/init.cxx b/libbuild2/install/init.cxx index e8ca982..769b106 100644 --- a/libbuild2/install/init.cxx +++ b/libbuild2/install/init.cxx @@ -227,7 +227,7 @@ namespace build2 void functions (function_map&); // functions.cxx - bool + void boot (scope& rs, const location&, module_boot_extra&) { tracer trace ("install::boot"); @@ -246,8 +246,6 @@ namespace build2 rs.insert_operation (install_id, op_install); rs.insert_operation (uninstall_id, op_uninstall); rs.insert_operation (update_for_install_id, op_update_for_install); - - return false; } static const path cmd ("install"); diff --git a/libbuild2/module.cxx b/libbuild2/module.cxx index bb877d9..02ea64d 100644 --- a/libbuild2/module.cxx +++ b/libbuild2/module.cxx @@ -581,7 +581,7 @@ namespace build2 // The only valid situation here is if the module has already been // bootstrapped. // - assert (i->boot); + assert (i->boot_init); return; } @@ -594,22 +594,22 @@ namespace build2 fail (loc) << "build system module " << mod << " should not be loaded " << "during bootstrap"; - lm.push_back (module_state {true, false, mod, mf.init, nullptr, loc}); + lm.push_back (module_state {loc, mod, mf.init, nullptr, nullopt}); i = lm.end () - 1; { - module_boot_extra e; + module_boot_extra e {nullptr, module_boot_init::before}; // Note: boot() can load additional modules invalidating the iterator. // size_t j (i - lm.begin ()); - bool f (mf.boot (rs, loc, e)); + mf.boot (rs, loc, e); i = lm.begin () + j; - i->first = f; - if (e.module != nullptr) i->module = move (e.module); + + i->boot_init = e.init; } rs.assign (rs.var_pool ().insert (mod + ".booted")) = true; @@ -640,7 +640,7 @@ namespace build2 fail (loc) << "build system module " << mod << " should be loaded " << "during bootstrap"; - lm.push_back (module_state {false, false, mod, mf->init, nullptr, loc}); + lm.push_back (module_state {loc, mod, mf->init, nullptr, nullopt}); i = lm.end () - 1; } } @@ -648,9 +648,9 @@ namespace build2 { module_state& s (*i); - if (s.boot) + if (s.boot_init) { - s.boot = false; + s.boot_init = nullopt; f = true; // This is a first call to init. } } diff --git a/libbuild2/module.hxx b/libbuild2/module.hxx index 0305e2c..4110682 100644 --- a/libbuild2/module.hxx +++ b/libbuild2/module.hxx @@ -40,9 +40,27 @@ namespace build2 // way for us to later pass more information without breaking source // compatibility. // + // By default a booted module is initialized before loading root.build. + // + // The module should specify the before_first initialization mode if it + // should be initialized first (within the resulting two groups the modules + // are initializated in the order loaded). + // + // The module should specify the after initialization mode if it should be + // initialized after loading root.build. Note that in this case the module + // is also allowed to be initialized explicitly from root.build. + // + enum class module_boot_init + { + before_first, + before, + after + }; + struct module_boot_extra { shared_ptr module; // Module instance (out). + module_boot_init init; // Init mode (out). // Convenience functions. // @@ -53,11 +71,8 @@ namespace build2 T& module_as () {assert (module); return static_cast (*module);} }; - // Return true if the module should be initialized first (within the - // resulting two groups the modules are initializated in the order loaded). - // using module_boot_function = - bool (scope& root, + void (scope& root, const location&, module_boot_extra&); @@ -122,12 +137,11 @@ namespace build2 // struct module_state { - 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. + location_value loc; // Load location. const string name; module_init_function* init; shared_ptr module; - location_value loc; // Boot location. + optional boot_init; }; struct module_map: vector diff --git a/libbuild2/test/init.cxx b/libbuild2/test/init.cxx index b6b18d9..aaacdc6 100644 --- a/libbuild2/test/init.cxx +++ b/libbuild2/test/init.cxx @@ -21,7 +21,7 @@ namespace build2 { namespace test { - bool + void boot (scope& rs, const location&, module_boot_extra& extra) { tracer trace ("test::boot"); @@ -112,8 +112,6 @@ namespace build2 } extra.set_module (new module (move (d))); - - return false; } bool diff --git a/libbuild2/version/init.cxx b/libbuild2/version/init.cxx index 681b6a4..7cb5a48 100644 --- a/libbuild2/version/init.cxx +++ b/libbuild2/version/init.cxx @@ -30,7 +30,7 @@ namespace build2 static const in_rule in_rule_; static const manifest_install_rule manifest_install_rule_; - bool + void boot (scope& rs, const location& l, module_boot_extra& extra) { tracer trace ("version::boot"); @@ -279,7 +279,9 @@ namespace build2 rewritten, move (ds))); - return true; // Init first (dist.package, etc). + // Initialize first (dist.package, etc). + // + extra.init = module_boot_init::before_first; } static void -- cgit v1.1