aboutsummaryrefslogtreecommitdiff
path: root/libbuild2
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2020-09-22 11:28:53 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2020-09-22 11:28:53 +0200
commitd06e8d1d3b0594c74fa444da76c3c7925ed58f70 (patch)
treea2c6d46e285b8109adc53a7ee2562cd26126a399 /libbuild2
parent9f72ad00a0654bc965ff527615e02fd35596073c (diff)
Add ability to skip external modules during bootstrap (--no-external-modules)
Diffstat (limited to 'libbuild2')
-rw-r--r--libbuild2/context.cxx2
-rw-r--r--libbuild2/context.hxx5
-rw-r--r--libbuild2/file.cxx8
-rw-r--r--libbuild2/module.cxx94
4 files changed, 75 insertions, 34 deletions
diff --git a/libbuild2/context.cxx b/libbuild2/context.cxx
index d62965c..b78cd27 100644
--- a/libbuild2/context.cxx
+++ b/libbuild2/context.cxx
@@ -59,6 +59,7 @@ namespace build2
context (scheduler& s,
global_mutexes& ms,
bool mo,
+ bool nem,
bool dr,
bool kg,
const strings& cmd_vars,
@@ -68,6 +69,7 @@ namespace build2
sched (s),
mutexes (ms),
match_only (mo),
+ no_external_modules (nem),
dry_run_option (dr),
keep_going (kg),
phase_mutex (*this),
diff --git a/libbuild2/context.hxx b/libbuild2/context.hxx
index c4e1259..0790355 100644
--- a/libbuild2/context.hxx
+++ b/libbuild2/context.hxx
@@ -146,6 +146,10 @@ namespace build2
//
bool match_only;
+ // Skip booting external modules flag (see --no-external-modules).
+ //
+ bool no_external_modules;
+
// Dry run flag (see --dry-run|-n).
//
// This flag is set (based on dry_run_option) only for the final execute
@@ -479,6 +483,7 @@ namespace build2
context (scheduler&,
global_mutexes&,
bool match_only = false,
+ bool no_external_modules = false,
bool dry_run = false,
bool keep_going = true,
const strings& cmd_vars = {},
diff --git a/libbuild2/file.cxx b/libbuild2/file.cxx
index 2660b9e..67aeb77 100644
--- a/libbuild2/file.cxx
+++ b/libbuild2/file.cxx
@@ -1431,6 +1431,8 @@ namespace build2
{
tracer trace ("load_root");
+ context& ctx (root.ctx);
+
const dir_path& out_root (root.out_path ());
const dir_path& src_root (root.src_path ());
@@ -1442,6 +1444,10 @@ namespace build2
if (root.buildfiles.find (f) != root.buildfiles.end ())
return;
+ if (ctx.no_external_modules)
+ fail << "attempt to load project " << root << " after skipped loading "
+ << "external modules";
+
// First load outer roots, if any.
//
if (scope* rs = root.parent_scope ()->root_scope ())
@@ -1483,7 +1489,7 @@ namespace build2
// Reuse the parser to accumulate the configuration variable information.
//
- parser p (root.ctx, load_stage::root);
+ parser p (ctx, load_stage::root);
if (he) {source_hooks (p, root, hd, true /* pre */); p.reset ();}
if (fe) {source_once (p, root, root, f, root);}
diff --git a/libbuild2/module.cxx b/libbuild2/module.cxx
index 11b32cb..14cf183 100644
--- a/libbuild2/module.cxx
+++ b/libbuild2/module.cxx
@@ -81,6 +81,7 @@ namespace build2
new context (ctx.sched,
ctx.mutexes,
false, /* match_only */
+ false, /* no_external_modules */
false, /* dry_run */
ctx.keep_going,
ctx.global_var_overrides, /* cmd_vars */
@@ -238,7 +239,11 @@ namespace build2
#endif
const string& mod,
const location& loc,
- bool /* boot */,
+#if defined(BUILD2_BOOTSTRAP) || defined(LIBBUILD2_STATIC_BUILD)
+ bool,
+#else
+ bool boot,
+#endif
bool opt)
{
tracer trace ("import_module");
@@ -251,6 +256,26 @@ namespace build2
else if (mod == "install") return &install::build2_install_load;
else if (mod == "test") return &test::build2_test_load;
+ module_load_function* r (nullptr);
+
+ // No dynamic loading of build system modules during bootstrap or if
+ // statically-linked..
+ //
+#if defined(BUILD2_BOOTSTRAP) || defined(LIBBUILD2_STATIC_BUILD)
+ if (!opt)
+ {
+ fail (loc) << "unknown build system module " << mod <<
+#ifdef BUILD2_BOOTSTRAP
+ info << "running bootstrap build system";
+#else
+ info << "running statically-linked build system";
+#endif
+ }
+#else
+ context& ctx (bs.ctx);
+
+ bool bundled (bundled_module (mod));
+
// Note that importing external modules during bootstrap is problematic
// since we haven't loaded config.build nor entered non-global variable
// overrides. We used to just not support external modules that require
@@ -287,28 +312,20 @@ namespace build2
// And another case is the bdep-sync hook which also doesn't have the
// global overrides propagated to it.
//
- // It does feel right to propagate global overrides to all the nested
- // build system invocations. Maybe we should set an environment variable?
-
- module_load_function* r (nullptr);
-
- // No dynamic loading of build system modules during bootstrap or if
- // statically-linked..
- //
-#if defined(BUILD2_BOOTSTRAP) || defined(LIBBUILD2_STATIC_BUILD)
- if (!opt)
- {
- fail (loc) << "unknown build system module " << mod <<
-#ifdef BUILD2_BOOTSTRAP
- info << "running bootstrap build system";
-#else
- info << "running statically-linked build system";
-#endif
- }
-#else
- context& ctx (bs.ctx);
-
- bool bundled (bundled_module (mod));
+ // And it turns out the story does not end here: without an external
+ // module we cannot do info or dist. So to support this we now allow
+ // skipping of loading of external modules (for dist this is only part of
+ // the solution with the other part being the bootstrap mode). While no
+ // doubt a hack, it feels like this is the time to cut of this complexity
+ // escalation. Essentially, we are saying external module that require
+ // bootstrap must be prepared to be skipped if the project is only being
+ // bootstrapped. Note also that the fact that a module boot was skipped
+ // can be detected by checking the module's *.booted variable. In case of
+ // a skip it will be false, as opposed to true if the module was booted
+ // and undefined if the module was not mentioned.
+ //
+ if (boot && !bundled && ctx.no_external_modules)
+ return nullptr;
// See if we can import a target for this module.
//
@@ -570,7 +587,14 @@ namespace build2
<< mmod;
}
else
+ {
+ // Reduce skipped external module to optional.
+ //
+ if (boot)
+ opt = true;
+
i = loaded_modules.emplace (move (mmod), nullptr).first;
+ }
}
}
@@ -616,23 +640,27 @@ namespace build2
// Otherwise search for this module.
//
- const module_functions& mf (
- *find_module (rs, mod, loc, true /* boot */, false /* optional */));
+ // Note that find_module() may return NULL in case of a skipped external
+ // module.
+ //
+ const module_functions* mf (
+ find_module (rs, mod, loc, true /* boot */, false /* optional */));
- if (mf.boot == nullptr)
- fail (loc) << "build system module " << mod << " should not be loaded "
- << "during bootstrap";
+ if (mf != nullptr)
+ {
+ if (mf->boot == nullptr)
+ fail (loc) << "build system module " << mod << " should not be loaded "
+ << "during bootstrap";
- lm.push_back (module_state {loc, mod, mf.init, nullptr, nullopt});
- i = lm.end () - 1;
+ lm.push_back (module_state {loc, mod, mf->init, nullptr, nullopt});
+ i = lm.end () - 1;
- {
module_boot_extra e {nullptr, module_boot_init::before};
// Note: boot() can load additional modules invalidating the iterator.
//
size_t j (i - lm.begin ());
- mf.boot (rs, loc, e);
+ mf->boot (rs, loc, e);
i = lm.begin () + j;
if (e.module != nullptr)
@@ -641,7 +669,7 @@ namespace build2
i->boot_init = e.init;
}
- rs.assign (rs.var_pool ().insert (mod + ".booted")) = true;
+ rs.assign (rs.var_pool ().insert (mod + ".booted")) = (mf != nullptr);
}
module_state*