aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/config/operation.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'libbuild2/config/operation.cxx')
-rw-r--r--libbuild2/config/operation.cxx522
1 files changed, 366 insertions, 156 deletions
diff --git a/libbuild2/config/operation.cxx b/libbuild2/config/operation.cxx
index b9856be..150bf1a 100644
--- a/libbuild2/config/operation.cxx
+++ b/libbuild2/config/operation.cxx
@@ -42,7 +42,7 @@ namespace build2
ofs << "# Created automatically by the config module." << endl
<< "#" << endl
<< "src_root = ";
- to_stream (ofs, name (src_root), true /* quote */, '@');
+ to_stream (ofs, name (src_root), quote_mode::normal, '@');
ofs << endl;
ofs.close ();
@@ -61,8 +61,10 @@ namespace build2
path f (src_root / rs.root_extra->out_root_file);
- if (verb)
- text << (verb >= 2 ? "cat >" : "save ") << f;
+ if (verb >= 2)
+ text << "cat >" << f;
+ else if (verb)
+ print_diag ("save", f);
try
{
@@ -71,7 +73,7 @@ namespace build2
ofs << "# Created automatically by the config module." << endl
<< "#" << endl
<< "out_root = ";
- to_stream (ofs, name (out_root), true /* quote */, '@');
+ to_stream (ofs, name (out_root), quote_mode::normal, '@');
ofs << endl;
ofs.close ();
@@ -82,8 +84,6 @@ namespace build2
}
}
- using project_set = set<const scope*>; // Use pointers to get comparison.
-
// Return (first) whether an unused/inherited variable should be saved
// according to the config.config.persist value and (second) whether the
// user should be warned about it.
@@ -134,7 +134,8 @@ namespace build2
bool r;
if (c.compare (p, 4 , "save") == 0) r = true;
else if (c.compare (p, 4 , "drop") == 0) r = false;
- else fail << "invalid config.config.persist action '" << c << "'";
+ else fail << "invalid config.config.persist action '" << c << "'"
+ << endf;
bool w (false);
if ((p += 4) != c.size ())
@@ -159,24 +160,26 @@ namespace build2
// If inherit is false, then don't rely on inheritance from outer scopes.
//
+ // @@ We are modifying the module (marking additional variables as saved)
+ // and this function can be called from a buildfile (probably only
+ // during serial execution but still).
+ //
+ // We could also be configuring multiple projects (including from
+ // pkg_configure() in bpkg) but feels like we should be ok since we
+ // only modify this project's root scope data which should not affect
+ // any other project.
+ //
+ // See also save_environment() for a similar issue.
+ //
void
save_config (const scope& rs,
ostream& os, const path_name& on,
bool inherit,
+ const module& mod,
const project_set& projects)
{
context& ctx (rs.ctx);
- // @@ We are modifying the module (marking additional variables as
- // saved) and this function can be called from a buildfile (probably
- // only during serial execution but still).
- //
- module* mod (rs.find_module<module> (module::name));
-
- if (mod == nullptr)
- fail (on) << "no configuration information available during this "
- << "meta-operation";
-
names storage;
auto info_value = [&storage] (diag_record& dr, const value& v) mutable
@@ -186,7 +189,7 @@ namespace build2
if (v)
{
storage.clear ();
- dr << "'" << reverse (v, storage) << "'";
+ dr << "'" << reverse (v, storage, true /* reduce */) << "'";
}
else
dr << "[null]";
@@ -214,9 +217,11 @@ namespace build2
// saved according to config.config.persist potentially warning if the
// variable would otherwise be dropped.
//
+ // Note: go straight for the public variable pool.
+ //
auto& vp (ctx.var_pool);
- for (auto p (rs.vars.lookup_namespace (*vp.find ("config")));
+ for (auto p (rs.vars.lookup_namespace ("config"));
p.first != p.second;
++p.first)
{
@@ -228,26 +233,59 @@ namespace build2
if (size_t n = var->override ())
var = vp.find (string (var->name, 0, n));
+ const string& name (var->name);
+
// Skip special variables.
//
- if (var->name == "config.booted" ||
- var->name == "config.loaded" ||
- var->name == "config.configured" ||
- var->name.compare (0, 14, "config.config.") == 0)
+ if (name == "config.booted" ||
+ name == "config.loaded" ||
+ name == "config.configured" ||
+ name.compare (0, 14, "config.config.") == 0)
continue;
- if (mod->find_variable (*var)) // Saved or unsaved.
+ if (mod.find_variable (*var)) // Saved or unsaved.
continue;
+ // Skip config.**.develop variables (see parser::parse_config() for
+ // details).
+ //
+ // In a sense, this variable is always "available" but if the
+ // package does not distinguish between development and consumption,
+ // then specifying config.*.develop=true should be noop.
+ //
+ {
+ size_t p (name.rfind ('.'));
+ if (p != 6 && name.compare (p + 1, string::npos, "develop") == 0)
+ continue;
+ }
+
+ // A common reason behind an unused config.import.* value is an
+ // unused dependency. That is, there is depends in manifest but no
+ // import in buildfile (or import could be conditional in which case
+ // depends should also be conditional). So let's suggest this
+ // possibility. Note that the project name may have been sanitized
+ // to a variable name. Oh, well, better than nothing.
+ //
+ auto info_import = [] (diag_record& dr, const string& var)
+ {
+ if (var.compare (0, 14, "config.import.") == 0)
+ {
+ size_t p (var.find ('.', 14));
+
+ dr << info << "potentially unused dependency on "
+ << string (var, 14, p == string::npos ? p : p - 14);
+ }
+ };
+
const value& v (p.first->second);
pair<bool, bool> r (save_config_variable (*var,
- mod->persist,
+ mod.persist,
false /* inherited */,
true /* unused */));
if (r.first) // save
{
- mod->save_variable (*var, 0);
+ const_cast<module&> (mod).save_variable (*var, 0);
if (r.second) // warn
{
@@ -266,6 +304,7 @@ namespace build2
diag_record dr;
dr << warn (on) << "saving no longer used variable " << *var;
+ info_import (dr, var->name);
if (verb >= 2)
info_value (dr, v);
}
@@ -276,6 +315,7 @@ namespace build2
{
diag_record dr;
dr << warn (on) << "dropping no longer used variable " << *var;
+ info_import (dr, var->name);
info_value (dr, v);
}
}
@@ -283,12 +323,23 @@ namespace build2
// Save config variables.
//
- for (auto p: mod->saved_modules.order)
+ for (auto p: mod.saved_modules.order)
{
const string& sname (p.second->first);
const saved_variables& svars (p.second->second);
- bool first (true); // Separate modules with a blank line.
+ // Separate modules with a blank line.
+ //
+ auto first = [v = true] () mutable
+ {
+ if (v)
+ {
+ v = false;
+ return "\n";
+ }
+ return "";
+ };
+
for (const saved_variable& sv: svars)
{
if (!sv.flags) // unsaved
@@ -308,7 +359,13 @@ namespace build2
// inherited. We might also not have any value at all (see
// unconfigured()).
//
- if (!l.defined () || (l->null && flags & save_null_omitted))
+ // Note that we must check for null() before attempting any
+ // further tests.
+ //
+ if (!l.defined () ||
+ (l->null ? flags & save_null_omitted :
+ l->empty () ? flags & save_empty_omitted :
+ (flags & save_false_omitted) != 0 && !cast<bool> (*l)))
continue;
// Handle inherited from outer scope values.
@@ -317,90 +374,97 @@ namespace build2
// we save the inherited values regardless of whether they are
// used or not.
//
- if (inherit && !(l.belongs (rs) || l.belongs (ctx.global_scope)))
+ const value* base (nullptr);
+ if (inherit)
{
- // This is presumably an inherited value. But it could also be
- // some left-over garbage. For example, an amalgamation could
- // have used a module but then dropped it while its config
- // values are still lingering in config.build. They are probably
- // still valid and we should probably continue using them but we
- // definitely want to move them to our config.build since they
- // will be dropped from the amalgamation's config.build on the
- // next reconfigure. Let's also warn the user just in case,
- // unless there is no module and thus we couldn't really check
- // (the latter could happen when calling $config.save() during
- // other meta-operations, though it passes false for inherit).
+ // Return true if the specified value can be inherited from.
//
- // There is also another case that falls under this now that
- // overrides are by default amalgamation-wide rather than just
- // "project and subprojects": we may be (re-)configuring a
- // subproject but the override is now set on the outer project's
- // root.
- //
- bool found (false), checked (true);
- const scope* r (&rs);
- while ((r = r->parent_scope ()->root_scope ()) != nullptr)
+ auto find_inherited = [&on, &projects,
+ &info_value,
+ &sname, &rs, &var] (const lookup& org,
+ const lookup& ovr)
{
- if (l.belongs (*r))
+ const lookup& l (ovr);
+
+ // This is presumably an inherited value. But it could also be
+ // some left-over garbage. For example, an amalgamation could
+ // have used a module but then dropped it while its config
+ // values are still lingering in config.build. They are
+ // probably still valid and we should probably continue using
+ // them but we definitely want to move them to our
+ // config.build since they will be dropped from the
+ // amalgamation's config.build on the next reconfigure. Let's
+ // also warn the user just in case, unless there is no module
+ // and thus we couldn't really check (the latter could happen
+ // when calling $config.save() during other meta-operations,
+ // though it passes false for inherit).
+ //
+ // There is also another case that falls under this now that
+ // overrides are by default amalgamation-wide rather than just
+ // "project and subprojects": we may be (re-)configuring a
+ // subproject but the override is now set on the outer
+ // project's root.
+ //
+ bool found (false), checked (true);
+ const scope* r (&rs);
+ while ((r = r->parent_scope ()->root_scope ()) != nullptr)
{
- // Find the config module (might not be there).
- //
- if (auto* m = r->find_module<const module> (module::name))
+ if (l.belongs (*r))
{
- // Find the corresponding saved module.
+ // Find the config module (might not be there).
//
- auto i (m->saved_modules.find (sname));
-
- if (i != m->saved_modules.end ())
+ if (auto* m = r->find_module<const module> (module::name))
{
- // Find the variable.
+ // Find the corresponding saved module.
//
- const saved_variables& sv (i->second);
- found = sv.find (var) != sv.end ();
+ auto i (m->saved_modules.find (sname));
- // If not marked as saved, check whether overriden via
- // config.config.persist.
- //
- if (!found && m->persist != nullptr)
+ if (i != m->saved_modules.end ())
{
- found = save_config_variable (
- var,
- m->persist,
- false /* inherited */,
- true /* unused */).first;
+ // Find the variable.
+ //
+ const saved_variables& sv (i->second);
+ found = sv.find (var) != sv.end ();
+
+ // If not marked as saved, check whether overriden via
+ // config.config.persist.
+ //
+ if (!found && m->persist != nullptr)
+ {
+ found = save_config_variable (
+ var,
+ m->persist,
+ false /* inherited */,
+ true /* unused */).first;
+ }
+
+ // Handle that other case: if this is an override but
+ // the outer project itself is not being configured,
+ // then we need to save this override.
+ //
+ // One problem with using the already configured
+ // project set is that the outer project may be
+ // configured only after us in which case both
+ // projects will save the value. But perhaps this is a
+ // feature, not a bug since this is how project-local
+ // (%) override behaves.
+ //
+ if (found &&
+ org != ovr &&
+ projects.find (r) == projects.end ())
+ found = false;
}
-
- // Handle that other case: if this is an override but
- // the outer project itself is not being configured,
- // then we need to save this override.
- //
- // One problem with using the already configured project
- // set is that the outer project may be configured only
- // after us in which case both projects will save the
- // value. But perhaps this is a feature, not a bug since
- // this is how project-local (%) override behaves.
- //
- if (found &&
- org.first != ovr.first &&
- projects.find (r) == projects.end ())
- found = false;
}
- }
- else
- checked = false;
+ else
+ checked = false;
- break;
+ break;
+ }
}
- }
- if (found)
- {
- // Inherited.
- //
- continue;
- }
- else
- {
+ if (found)
+ return true;
+
// If this value is not defined in a project's root scope,
// then something is broken.
//
@@ -413,7 +477,7 @@ namespace build2
// our own. One special case where we don't want to warn the
// user is if the variable is overriden.
//
- if (checked && org.first == ovr.first)
+ if (checked && org == ovr)
{
diag_record dr;
dr << warn (on) << "saving previously inherited variable "
@@ -425,6 +489,39 @@ namespace build2
if (verb >= 2)
info_value (dr, *l);
}
+
+ return false;
+ };
+
+ // Inherit as-is.
+ //
+ if (!l.belongs (rs) &&
+ !l.belongs (ctx.global_scope) &&
+ find_inherited (org.first, ovr.first))
+ continue;
+ else if (flags & save_base)
+ {
+ // See if we can base our value on inherited.
+ //
+ if (const scope* ors = rs.parent_scope ()->root_scope ())
+ {
+ pair<lookup, size_t> org (ors->lookup_original (var));
+ pair<lookup, size_t> ovr (var.overrides == nullptr
+ ? org
+ : ors->lookup_override (var, org));
+ const lookup& l (ovr.first);
+
+ // We cannot base anything on an empty value.
+ //
+ if (l && !l->empty ())
+ {
+ // @@ It's not clear we want the checks/diagnostics in
+ // this case.
+ //
+ if (find_inherited (org.first, ovr.first))
+ base = l.value;
+ }
+ }
}
}
@@ -442,44 +539,42 @@ namespace build2
continue;
}
- // If we got here then we are saving this variable. Handle the
- // blank line.
- //
- if (first)
- {
- os << endl;
- first = false;
- }
-
// Handle the save_default_commented flag.
//
- if ((org.first.defined () && org.first->extra) && // Default value.
- org.first == ovr.first && // Not overriden.
+ if (org.first.defined () && org.first->extra == 1 && // Default.
+ org.first == ovr.first && // No override.
(flags & save_default_commented) != 0)
{
- os << '#' << n << " =" << endl;
+ os << first () << '#' << n << " =" << endl;
continue;
}
- if (v)
+ if (v.null)
{
- storage.clear ();
- names_view ns (reverse (v, storage));
+ os << first () << n << " = [null]" << endl;
+ continue;
+ }
- os << n;
+ storage.clear ();
+ pair<names_view, const char*> p (
+ sv.save != nullptr
+ ? sv.save (v, base, storage)
+ : make_pair (reverse (v, storage, true /* reduce */), "="));
- if (ns.empty ())
- os << " =";
- else
- {
- os << " = ";
- to_stream (os, ns, true /* quote */, '@');
- }
+ // Might becomes empty after a custom save function had at it.
+ //
+ if (p.first.empty () && (flags & save_empty_omitted))
+ continue;
+
+ os << first () << n << ' ' << p.second;
- os << endl;
+ if (!p.first.empty ())
+ {
+ os << ' ';
+ to_stream (os, p.first, quote_mode::normal, '@');
}
- else
- os << n << " = [null]" << endl;
+
+ os << endl;
}
}
}
@@ -493,6 +588,7 @@ namespace build2
save_config (const scope& rs,
const path& f,
bool inherit,
+ const module& mod,
const project_set& projects)
{
path_name fn (f);
@@ -500,13 +596,16 @@ namespace build2
if (f.string () == "-")
fn.name = "<stdout>";
- if (verb)
- text << (verb >= 2 ? "cat >" : "save ") << fn;
+ if (verb >= 2)
+ text << "cat >" << fn;
+ else if (verb)
+ print_diag ("save", fn);
try
{
ofdstream ofs;
- save_config (rs, open_file_or_stdout (fn, ofs), fn, inherit, projects);
+ save_config (
+ rs, open_file_or_stdout (fn, ofs), fn, inherit, mod, projects);
ofs.close ();
}
catch (const io_error& e)
@@ -515,10 +614,86 @@ namespace build2
}
}
+ // Update config.config.environment value for a hermetic configuration.
+ //
+ // @@ We are modifying the module. See also save_config() for a similar
+ // issue.
+ //
+ static void
+ save_environment (scope& rs, module& mod)
+ {
+ // Here we have two parts: (1) get the list of environment variables we
+ // need to save and (2) save their values in config.config.environment.
+ //
+ // The saved_environment list should by now contain all the project-
+ // specific environment variables. To that we add builtin defaults and
+ // then filter the result against config.config.hermetic.environment
+ // inclusions/exclusions.
+ //
+ auto& vars (mod.saved_environment);
+
+ vars.insert ("PATH");
+
+#if defined(_WIN32)
+#elif defined(__APPLE__)
+ vars.insert ("DYLD_LIBRARY_PATH");
+#else // Linux, FreeBSD, NetBSD, OpenBSD
+ vars.insert ("LD_LIBRARY_PATH");
+#endif
+
+ for (const pair<string, optional<bool>>& p:
+ cast_empty<hermetic_environment> (
+ rs["config.config.hermetic.environment"]))
+ {
+ if (!p.second || *p.second)
+ vars.insert (p.first);
+ else
+ vars.erase (p.first);
+ }
+
+ // Get the values.
+ //
+ strings vals;
+ {
+ // Set the project environment before querying the values. Note that
+ // the logic in init() makes sure that this is all we need to do to
+ // handle reload (in which case we should still be using
+ // config.config.environment from amalgamation, if any).
+ //
+ auto_project_env penv (rs);
+
+ for (const string& var: vars)
+ {
+ if (optional<string> val = getenv (var))
+ {
+ vals.push_back (var + '=' + *val);
+ }
+ else
+ vals.push_back (var); // Unset.
+ }
+ }
+
+ // Note: go straight for the public variable pool.
+ //
+ value& v (rs.assign (*rs.ctx.var_pool.find ("config.config.environment")));
+
+ // Note that setting new config.config.environment value invalidates the
+ // project's environment (scope::root_extra::environment) which could be
+ // queried in the post-configuration hook. We could re-initialize it but
+ // the c.c.e value from amalgamation could be referenced by subprojects.
+ // So instead it seems easier to just save the old value in the module.
+ //
+ if (v)
+ mod.old_environment = move (v.as<strings> ());
+
+ v = move (vals);
+ }
+
static void
configure_project (action a,
const scope& rs,
const variable* c_s, // config.config.save
+ const module& mod,
project_set& projects)
{
tracer trace ("configure_project");
@@ -538,7 +713,7 @@ namespace build2
//
if (out_root != src_root)
{
- mkdir_p (out_root / rs.root_extra->build_dir);
+ mkdir_p (out_root / rs.root_extra->build_dir, 1);
mkdir (out_root / rs.root_extra->bootstrap_dir, 2);
}
@@ -548,6 +723,12 @@ namespace build2
{
l5 ([&]{trace << "completely configuring " << out_root;});
+ // Save the environment if this configuration is hermetic (see init()
+ // for the other half of this logic).
+ //
+ if (cast_false<bool> (rs["config.config.hermetic"]))
+ save_environment (const_cast<scope&> (rs), const_cast<module&> (mod));
+
// Save src-root.build unless out_root is the same as src.
//
if (c_s == nullptr && out_root != src_root)
@@ -572,12 +753,17 @@ namespace build2
// may end up leaving it in partially configured state.
//
if (c_s == nullptr)
- save_config (rs, config_file (rs), true /* inherit */, projects);
+ save_config (rs, config_file (rs), true /* inherit */, mod, projects);
else
{
lookup l (rs[*c_s]);
if (l && (l.belongs (rs) || l.belongs (ctx.global_scope)))
{
+ const path& f (cast<path> (l));
+
+ if (f.empty ())
+ fail << "empty path in " << *c_s;
+
// While writing the complete configuration seems like a natural
// default, there might be a desire to take inheritance into
// account (if, say, we are exporting at multiple levels). One can
@@ -585,7 +771,7 @@ namespace build2
// still want to support this mode somehow in the future (it seems
// like an override of config.config.persist should do the trick).
//
- save_config (rs, cast<path> (l), false /* inherit */, projects);
+ save_config (rs, f, false /* inherit */, mod, projects);
}
}
}
@@ -596,11 +782,8 @@ namespace build2
if (c_s == nullptr)
{
- if (module* m = rs.find_module<module> (module::name))
- {
- for (auto hook: m->configure_post_)
- hook (a, rs);
- }
+ for (auto hook: mod.configure_post_)
+ hook (a, rs);
}
// Configure subprojects that have been loaded.
@@ -611,15 +794,19 @@ namespace build2
{
const dir_path& pd (p.second);
dir_path out_nroot (out_root / pd);
- const scope& nrs (ctx.scopes.find (out_nroot));
+ const scope& nrs (ctx.scopes.find_out (out_nroot));
- // @@ Strictly speaking we need to check whether the config module
- // was loaded for this subproject.
+ // Skip this subproject if it is not loaded or doesn't use the
+ // config module.
//
- if (nrs.out_path () != out_nroot) // This subproject not loaded.
- continue;
+ if (nrs.out_path () == out_nroot)
+ {
+ if (const module* m = nrs.find_module<module> (module::name))
+ {
+ configure_project (a, nrs, c_s, *m, projects);
+ }
+ }
- configure_project (a, nrs, c_s, projects);
}
}
}
@@ -651,7 +838,7 @@ namespace build2
for (auto p: *ps)
{
dir_path out_nroot (out_root / p.second);
- const scope& nrs (ctx.scopes.find (out_nroot));
+ const scope& nrs (ctx.scopes.find_out (out_nroot));
assert (nrs.out_path () == out_nroot);
configure_forward (nrs, projects);
@@ -662,11 +849,13 @@ namespace build2
operation_id (*pre) (const values&, meta_operation_id, const location&);
static operation_id
- configure_operation_pre (const values&, operation_id o)
+ configure_operation_pre (context&, const values&, operation_id o)
{
// Don't translate default to update. In our case unspecified
// means configure everything.
//
+ // Note: see pkg_configure() in bpkg if changing anything here.
+ //
return o;
}
@@ -701,8 +890,10 @@ namespace build2
}
static void
- configure_pre (const values& params, const location& l)
+ configure_pre (context&, const values& params, const location& l)
{
+ // Note: see pkg_configure() in bpkg if changing anything here.
+ //
forward (params, "configure", l); // Validate.
}
@@ -722,11 +913,13 @@ namespace build2
//
create_bootstrap_inner (rs);
- if (rs.out_path () == rs.src_path ())
+ if (rs.out_eq_src ())
fail (l) << "forwarding to source directory " << rs.src_path ();
}
else
- load (params, rs, buildfile, out_base, src_base, l); // Normal load.
+ // Normal load.
+ //
+ perform_load (params, rs, buildfile, out_base, src_base, l);
}
static void
@@ -746,7 +939,7 @@ namespace build2
ts.push_back (&rs);
}
else
- search (params, rs, bs, bf, tk, l, ts); // Normal search.
+ perform_search (params, rs, bs, bf, tk, l, ts); // Normal search.
}
static void
@@ -766,6 +959,8 @@ namespace build2
context& ctx (fwd ? ts[0].as<scope> ().ctx : ts[0].as<target> ().ctx);
+ // Note: go straight for the public variable pool.
+ //
const variable* c_s (ctx.var_pool.find ("config.config.save"));
if (c_s->overrides == nullptr)
@@ -820,16 +1015,28 @@ namespace build2
ctx.current_operation (*oif);
+ if (oif->operation_pre != nullptr)
+ oif->operation_pre (ctx, {}, true /* inner */, location ());
+
phase_lock pl (ctx, run_phase::match);
- match (action (configure_id, id), t);
+ match_sync (action (configure_id, id), t);
+
+ if (oif->operation_post != nullptr)
+ oif->operation_post (ctx, {}, true /* inner */);
}
}
- configure_project (a, *rs, c_s, projects);
+ configure_project (a,
+ *rs,
+ c_s,
+ *rs->find_module<module> (module::name),
+ projects);
}
}
}
+ // NOTE: see pkg_configure() in bpkg if changing anything here.
+ //
const meta_operation_info mo_configure {
configure_id,
"configure",
@@ -879,7 +1086,7 @@ namespace build2
{
const dir_path& pd (p.second);
dir_path out_nroot (out_root / pd);
- const scope& nrs (ctx.scopes.find (out_nroot));
+ const scope& nrs (ctx.scopes.find_out (out_nroot));
assert (nrs.out_path () == out_nroot); // See disfigure_load().
r = disfigure_project (a, nrs, projects) || r;
@@ -905,7 +1112,7 @@ namespace build2
}
}
- if (module* m = rs.find_module<module> (module::name))
+ if (const module* m = rs.find_module<module> (module::name))
{
for (auto hook: m->disfigure_pre_)
r = hook (a, rs) || r;
@@ -987,7 +1194,7 @@ namespace build2
for (auto p: *ps)
{
dir_path out_nroot (out_root / p.second);
- const scope& nrs (ctx.scopes.find (out_nroot));
+ const scope& nrs (ctx.scopes.find_out (out_nroot));
assert (nrs.out_path () == out_nroot);
r = disfigure_forward (nrs, projects) || r;
@@ -1004,13 +1211,13 @@ namespace build2
}
static void
- disfigure_pre (const values& params, const location& l)
+ disfigure_pre (context&, const values& params, const location& l)
{
forward (params, "disfigure", l); // Validate.
}
static operation_id
- disfigure_operation_pre (const values&, operation_id o)
+ disfigure_operation_pre (context&, const values&, operation_id o)
{
// Don't translate default to update. In our case unspecified
// means disfigure everything.
@@ -1128,6 +1335,8 @@ namespace build2
// Add the default config.config.persist value unless there is a custom
// one (specified as a command line override).
//
+ // Note: go straight for the public variable pool.
+ //
const variable& var (*ctx.var_pool.find ("config.config.persist"));
if (!rs[var].defined ())
@@ -1244,7 +1453,8 @@ namespace build2
string ("config"), /* config_module */
nullopt, /* config_file */
true, /* buildfile */
- "the create meta-operation");
+ "the create meta-operation",
+ 1 /* verbosity */);
save_config (ctx, d);
}