aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/config
diff options
context:
space:
mode:
Diffstat (limited to 'libbuild2/config')
-rw-r--r--libbuild2/config/functions.cxx2
-rw-r--r--libbuild2/config/host-config.cxx.in3
-rw-r--r--libbuild2/config/init.cxx53
-rw-r--r--libbuild2/config/module.hxx2
-rw-r--r--libbuild2/config/operation.cxx77
-rw-r--r--libbuild2/config/operation.hxx6
6 files changed, 108 insertions, 35 deletions
diff --git a/libbuild2/config/functions.cxx b/libbuild2/config/functions.cxx
index 84c1b03..b1a61a2 100644
--- a/libbuild2/config/functions.cxx
+++ b/libbuild2/config/functions.cxx
@@ -95,7 +95,7 @@ namespace build2
// See save_config() for details.
//
assert (s->ctx.phase == run_phase::load);
- module* mod (s->rw ().find_module<module> (module::name));
+ const module* mod (s->find_module<module> (module::name));
if (mod == nullptr)
fail << "config.save() called without config module";
diff --git a/libbuild2/config/host-config.cxx.in b/libbuild2/config/host-config.cxx.in
index 9e3e0c2..6b1ce77 100644
--- a/libbuild2/config/host-config.cxx.in
+++ b/libbuild2/config/host-config.cxx.in
@@ -9,5 +9,8 @@ namespace build2
//
extern const char host_config[] = R"###($host_config$)###";
extern const char build2_config[] = R"###($build2_config$)###";
+
+ extern const char host_config_no_warnings[] = R"###($host_config_no_warnings$)###";
+ extern const char build2_config_no_warnings[] = R"###($build2_config_no_warnings$)###";
}
}
diff --git a/libbuild2/config/init.cxx b/libbuild2/config/init.cxx
index 7035ce5..2f134c4 100644
--- a/libbuild2/config/init.cxx
+++ b/libbuild2/config/init.cxx
@@ -26,6 +26,8 @@ namespace build2
{
namespace config
{
+ static const file_rule file_rule_ (true /* check_type */);
+
void
functions (function_map&); // functions.cxx
@@ -39,7 +41,7 @@ namespace build2
save_environment (const value& d, const value* b, names& storage)
{
if (b == nullptr)
- return make_pair (reverse (d, storage), "=");
+ return make_pair (reverse (d, storage, true /* reduce */), "=");
// The plan is to iterator over environment variables adding those that
// are not in base to storage. There is, however, a complication: we may
@@ -208,6 +210,9 @@ namespace build2
#ifndef BUILD2_BOOTSTRAP
extern const char host_config[];
extern const char build2_config[];
+
+ extern const char host_config_no_warnings[];
+ extern const char build2_config_no_warnings[];
#endif
bool
@@ -429,8 +434,15 @@ namespace build2
auto load_config_file = [&load_config] (const path& f, const location& l)
{
path_name fn (f);
- ifdstream ifs;
- load_config (open_file_or_stdin (fn, ifs), fn, l);
+ try
+ {
+ ifdstream ifs;
+ load_config (open_file_or_stdin (fn, ifs), fn, l);
+ }
+ catch (const io_error& e)
+ {
+ fail << "unable to read buildfile " << fn << ": " << e;
+ }
};
// Load config.build unless requested not to.
@@ -475,14 +487,23 @@ namespace build2
const string& s (f.string ());
- if (s[0] != '~')
+ if (s.empty ())
+ fail << "empty path in config.config.load";
+ else if (s[0] != '~')
load_config_file (f, l);
- else if (s == "~host" || s == "~build2")
+ else if (s == "~host" || s == "~host-no-warnings" ||
+ s == "~build2" || s == "~build2-no-warnings")
{
#ifdef BUILD2_BOOTSTRAP
assert (false);
#else
- istringstream is (s[1] == 'h' ? host_config : build2_config);
+ istringstream is (s[1] == 'h'
+ ? (s.size () == 5
+ ? host_config
+ : host_config_no_warnings)
+ : (s.size () == 7
+ ? build2_config
+ : build2_config_no_warnings));
load_config (is, path_name (s), l);
#endif
}
@@ -705,21 +726,23 @@ namespace build2
// Register alias and fallback rule for the configure meta-operation.
//
+ rs.insert_rule<alias> (configure_id, 0, "config.alias", alias_rule::instance);
+
+ // This allows a custom configure rule while doing nothing by default.
+ //
+ rs.insert_rule<target> (configure_id, 0, "config.noop", noop_rule::instance);
+
// We need this rule for out-of-any-project dependencies (for example,
// libraries imported from /usr/lib). We are registering it on the
// global scope similar to builtin rules.
//
- // See a similar rule in the dist module.
+ // Note: use target instead of anything more specific (such as
+ // mtime_target) in order not to take precedence over the rules above.
//
- rs.global_scope ().insert_rule<mtime_target> (
- configure_id, 0, "config.file", file_rule::instance);
-
- rs.insert_rule<alias> (configure_id, 0, "config.alias", alias_rule::instance);
-
- // This allows a custom configure rule while doing nothing by default.
+ // See a similar rule in the dist module.
//
- rs.insert_rule<target> (configure_id, 0, "config.noop", noop_rule::instance);
- rs.insert_rule<file> (configure_id, 0, "config.noop", noop_rule::instance);
+ rs.global_scope ().insert_rule<target> (
+ configure_id, 0, "config.file", file_rule_);
return true;
}
diff --git a/libbuild2/config/module.hxx b/libbuild2/config/module.hxx
index 82b79be..8d3ff67 100644
--- a/libbuild2/config/module.hxx
+++ b/libbuild2/config/module.hxx
@@ -160,7 +160,7 @@ namespace build2
save_module (scope&, const char*, int);
const saved_variable*
- find_variable (const variable& var)
+ find_variable (const variable& var) const
{
auto i (saved_modules.find_sup (var.name));
if (i != saved_modules.end ())
diff --git a/libbuild2/config/operation.cxx b/libbuild2/config/operation.cxx
index 34ed402..150bf1a 100644
--- a/libbuild2/config/operation.cxx
+++ b/libbuild2/config/operation.cxx
@@ -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 ())
@@ -163,11 +164,18 @@ namespace build2
// 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,
- module& mod,
+ const module& mod,
const project_set& projects)
{
context& ctx (rs.ctx);
@@ -181,7 +189,7 @@ namespace build2
if (v)
{
storage.clear ();
- dr << "'" << reverse (v, storage) << "'";
+ dr << "'" << reverse (v, storage, true /* reduce */) << "'";
}
else
dr << "[null]";
@@ -251,6 +259,24 @@ namespace build2
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,
@@ -259,7 +285,7 @@ namespace build2
true /* unused */));
if (r.first) // save
{
- mod.save_variable (*var, 0);
+ const_cast<module&> (mod).save_variable (*var, 0);
if (r.second) // warn
{
@@ -278,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);
}
@@ -288,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);
}
}
@@ -531,7 +559,7 @@ namespace build2
pair<names_view, const char*> p (
sv.save != nullptr
? sv.save (v, base, storage)
- : make_pair (reverse (v, storage), "="));
+ : make_pair (reverse (v, storage, true /* reduce */), "="));
// Might becomes empty after a custom save function had at it.
//
@@ -560,7 +588,7 @@ namespace build2
save_config (const scope& rs,
const path& f,
bool inherit,
- module& mod,
+ const module& mod,
const project_set& projects)
{
path_name fn (f);
@@ -588,6 +616,9 @@ 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)
{
@@ -660,9 +691,9 @@ namespace build2
static void
configure_project (action a,
- scope& rs,
+ const scope& rs,
const variable* c_s, // config.config.save
- module& mod,
+ const module& mod,
project_set& projects)
{
tracer trace ("configure_project");
@@ -696,7 +727,7 @@ namespace build2
// for the other half of this logic).
//
if (cast_false<bool> (rs["config.config.hermetic"]))
- save_environment (rs, mod);
+ save_environment (const_cast<scope&> (rs), const_cast<module&> (mod));
// Save src-root.build unless out_root is the same as src.
//
@@ -728,6 +759,11 @@ namespace build2
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
@@ -735,8 +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 */, mod, projects);
+ save_config (rs, f, false /* inherit */, mod, projects);
}
}
}
@@ -759,14 +794,14 @@ namespace build2
{
const dir_path& pd (p.second);
dir_path out_nroot (out_root / pd);
- scope& nrs (ctx.scopes.find_out (out_nroot).rw ());
+ const scope& nrs (ctx.scopes.find_out (out_nroot));
// Skip this subproject if it is not loaded or doesn't use the
// config module.
//
if (nrs.out_path () == out_nroot)
{
- if (module* m = nrs.find_module<module> (module::name))
+ if (const module* m = nrs.find_module<module> (module::name))
{
configure_project (a, nrs, c_s, *m, projects);
}
@@ -819,6 +854,8 @@ namespace build2
// 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;
}
@@ -855,6 +892,8 @@ namespace build2
static void
configure_pre (context&, const values& params, const location& l)
{
+ // Note: see pkg_configure() in bpkg if changing anything here.
+ //
forward (params, "configure", l); // Validate.
}
@@ -976,20 +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_sync (action (configure_id, id), t);
+
+ if (oif->operation_post != nullptr)
+ oif->operation_post (ctx, {}, true /* inner */);
}
}
configure_project (a,
- rs->rw (),
+ *rs,
c_s,
- *rs->rw ().find_module<module> (module::name),
+ *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",
diff --git a/libbuild2/config/operation.hxx b/libbuild2/config/operation.hxx
index 9e2a91e..1662941 100644
--- a/libbuild2/config/operation.hxx
+++ b/libbuild2/config/operation.hxx
@@ -15,8 +15,8 @@ namespace build2
{
class module;
- extern const meta_operation_info mo_configure;
- extern const meta_operation_info mo_disfigure;
+ LIBBUILD2_SYMEXPORT extern const meta_operation_info mo_configure;
+ LIBBUILD2_SYMEXPORT extern const meta_operation_info mo_disfigure;
const string&
preprocess_create (context&,
@@ -37,7 +37,7 @@ namespace build2
save_config (const scope& rs,
ostream&, const path_name&,
bool inherit,
- module&,
+ const module&,
const project_set&);
// See config.config.hermetic.environment.