aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libbuild2/config/init.cxx6
-rw-r--r--libbuild2/dist/init.cxx4
-rw-r--r--libbuild2/file.cxx28
-rw-r--r--libbuild2/install/init.cxx4
-rw-r--r--libbuild2/module.cxx18
-rw-r--r--libbuild2/module.hxx28
-rw-r--r--libbuild2/test/init.cxx4
-rw-r--r--libbuild2/version/init.cxx6
8 files changed, 64 insertions, 34 deletions
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<build2::module> 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<T&> (*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<build2::module> module;
- location_value loc; // Boot location.
+ optional<module_boot_init> boot_init;
};
struct module_map: vector<module_state>
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