aboutsummaryrefslogtreecommitdiff
path: root/build2
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2019-08-22 14:38:57 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2019-08-23 18:14:07 +0200
commit5035f4ef68922ac758b1e4734e67d73c9228010b (patch)
tree271fdd5b1d6e995a058d97aacb3ac90a538d9ff1 /build2
parent8793941652d6aa1c3d02b2f87f691e6d06254b7d (diff)
Introduce notion of build context
All non-const global state is now in class context and we can now have multiple independent builds going on at the same time.
Diffstat (limited to 'build2')
-rw-r--r--build2/b.cxx171
-rw-r--r--build2/bin/init.cxx12
-rw-r--r--build2/bin/target.cxx110
-rw-r--r--build2/c/init.cxx2
-rw-r--r--build2/cc/common.cxx43
-rw-r--r--build2/cc/common.hxx4
-rw-r--r--build2/cc/compile-rule.cxx82
-rw-r--r--build2/cc/init.cxx13
-rw-r--r--build2/cc/link-rule.cxx40
-rw-r--r--build2/cc/module.cxx16
-rw-r--r--build2/cc/msvc.cxx9
-rw-r--r--build2/cc/pkgconfig.cxx19
-rw-r--r--build2/cc/target.cxx8
-rw-r--r--build2/cc/utility.cxx4
-rw-r--r--build2/cc/windows-manifest.cxx2
-rw-r--r--build2/cc/windows-rpath.cxx4
-rw-r--r--build2/cli/init.cxx2
-rw-r--r--build2/cli/rule.cxx6
-rw-r--r--build2/cli/target.cxx15
-rw-r--r--build2/cxx/init.cxx7
-rw-r--r--build2/cxx/target.cxx20
21 files changed, 326 insertions, 263 deletions
diff --git a/build2/b.cxx b/build2/b.cxx
index f359dbc..51b024e 100644
--- a/build2/b.cxx
+++ b/build2/b.cxx
@@ -107,12 +107,15 @@ namespace build2
if (ops.structured_result ())
{
+ const target& t (at.as_target ());
+ context& ctx (t.ctx);
+
cout << at.state
- << ' ' << current_mif->name
- << ' ' << current_inner_oif->name;
+ << ' ' << ctx.current_mif->name
+ << ' ' << ctx.current_inner_oif->name;
- if (current_outer_oif != nullptr)
- cout << '(' << current_outer_oif->name << ')';
+ if (ctx.current_outer_oif != nullptr)
+ cout << '(' << ctx.current_outer_oif->name << ')';
// There are two ways one may wish to identify the target of the
// operation: as something specific but inherently non-portable (say,
@@ -131,7 +134,7 @@ namespace build2
stream_verbosity sv (stream_verb (cout));
stream_verb (cout, stream_verbosity (1, 0));
- cout << ' ' << at.as_target () << endl;
+ cout << ' ' << t << endl;
stream_verb (cout, sv);
}
@@ -222,6 +225,8 @@ main (int argc, char* argv[])
<< system_error (errno, generic_category ()); // Sanitize.
#endif
+ scheduler sched;
+
// Parse the command line.
//
try
@@ -475,7 +480,6 @@ main (int argc, char* argv[])
//
init (&::terminate,
argv[0],
- !ops.serial_stop (), ops.dry_run (),
(ops.mtime_check () ? optional<bool> (true) :
ops.no_mtime_check () ? optional<bool> (false) : nullopt),
(ops.config_sub_specified ()
@@ -490,7 +494,7 @@ main (int argc, char* argv[])
// current and child processes unless we are in the stop mode. Failed that
// we may have multiple dialog boxes popping up.
//
- if (keep_going)
+ if (!ops.serial_stop ())
SetErrorMode (SetErrorMode (0) | // Returns the current mode.
SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
#endif
@@ -582,14 +586,16 @@ main (int argc, char* argv[])
fail << "invalid --max-jobs|-J value";
}
- sched.startup (jobs,
- 1,
- max_jobs,
- jobs * ops.queue_depth (),
- (ops.max_stack_specified ()
- ? optional<size_t> (ops.max_stack () * 1024)
- : nullopt));
+ sched.startup (jobs,
+ 1,
+ max_jobs,
+ jobs * ops.queue_depth (),
+ (ops.max_stack_specified ()
+ ? optional<size_t> (ops.max_stack () * 1024)
+ : nullopt));
+ // @@ CTX: should these be per-context?
+ //
variable_cache_mutex_shard_size = sched.shard_size ();
variable_cache_mutex_shard.reset (
new shared_mutex[variable_cache_mutex_shard_size]);
@@ -606,10 +612,21 @@ main (int argc, char* argv[])
trace << "jobs: " << jobs;
}
- // Set the build state before parsing the buildspec since it relies on
- // global scope being setup.
+ // Set the build context before parsing the buildspec since it relies on
+ // the global scope being setup. We reset it for every meta-operation (see
+ // below).
//
- variable_overrides var_ovs (reset (cmd_vars));
+ unique_ptr<context> ctx;
+ auto new_context = [&ctx, &sched, &cmd_vars]
+ {
+ ctx = nullptr; // Free first.
+ ctx.reset (new context (sched,
+ cmd_vars,
+ ops.dry_run (),
+ !ops.serial_stop () /* keep_going */));
+ };
+
+ new_context ();
// Parse the buildspec.
//
@@ -619,7 +636,7 @@ main (int argc, char* argv[])
istringstream is (args);
is.exceptions (istringstream::failbit | istringstream::badbit);
- parser p;
+ parser p (*ctx);
bspec = p.parse_buildspec (is, path ("<buildspec>"));
}
catch (const io_error&)
@@ -745,13 +762,13 @@ main (int argc, char* argv[])
else
opspecs.assign (lifted, 1);
- // Reset the build state for each meta-operation since there is no
+ // Reset the build context for each meta-operation since there is no
// guarantee their assumptions (e.g., in the load callback) are
// compatible.
//
if (dirty)
{
- var_ovs = reset (cmd_vars);
+ new_context ();
dirty = false;
}
@@ -769,24 +786,25 @@ main (int argc, char* argv[])
values& mparams (lifted == nullptr ? mit->params : lifted->params);
string mname (lifted == nullptr ? mit->name : lifted->name);
- current_mname = mname; // Set early.
+ ctx->current_mname = mname; // Set early.
if (!mname.empty ())
{
- if (meta_operation_id m = meta_operation_table.find (mname))
+ if (meta_operation_id m = ctx->meta_operation_table.find (mname))
{
// Can modify params, opspec, change meta-operation name.
//
- if (auto f = meta_operation_table[m].process)
- mname = current_mname =
- f (var_ovs, mparams, opspecs, lifted != nullptr, l);
+ if (auto f = ctx->meta_operation_table[m].process)
+ mname = ctx->current_mname = f (
+ *ctx, mparams, opspecs, lifted != nullptr, l);
}
}
// Expose early so can be used during bootstrap (with the same
// limitations as for pre-processing).
//
- global_scope->rw ().assign (var_build_meta_operation) = mname;
+ scope& gs (ctx->global_scope.rw ());
+ gs.assign (ctx->var_build_meta_operation) = mname;
for (auto oit (opspecs.begin ()); oit != opspecs.end (); ++oit)
{
@@ -797,7 +815,7 @@ main (int argc, char* argv[])
const values& oparams (lifted == nullptr ? os.params : values ());
const string& oname (lifted == nullptr ? os.name : empty_string);
- current_oname = oname; // Set early.
+ ctx->current_oname = oname; // Set early.
if (lifted != nullptr)
lifted = nullptr; // Clear for the next iteration.
@@ -817,9 +835,11 @@ main (int argc, char* argv[])
// Return true if this operation is lifted.
//
- auto lift = [&oname, &mname, &os, &mit, &lifted, &skip, &l, &trace] ()
+ auto lift = [&ctx,
+ &oname, &mname,
+ &os, &mit, &lifted, &skip, &l, &trace] ()
{
- meta_operation_id m (meta_operation_table.find (oname));
+ meta_operation_id m (ctx->meta_operation_table.find (oname));
if (m != 0)
{
@@ -978,7 +998,7 @@ main (int argc, char* argv[])
// Handle a forwarded configuration. Note that if we've changed
// out_root then we also have to remap out_base.
//
- out_root = bootstrap_fwd (src_root, altn);
+ out_root = bootstrap_fwd (*ctx, src_root, altn);
if (src_root != out_root)
{
out_base = out_root / out_base.leaf (src_root);
@@ -1023,8 +1043,7 @@ main (int argc, char* argv[])
// use to the bootstrap files (other than src-root.build, which,
// BTW, doesn't need to exist if src_root == out_root).
//
- scope& rs (
- create_root (*scope::global_, out_root, src_root)->second);
+ scope& rs (create_root (gs, out_root, src_root)->second);
bool bstrapped (bootstrapped (rs));
@@ -1034,7 +1053,7 @@ main (int argc, char* argv[])
// See if the bootstrap process set/changed src_root.
//
- value& v (rs.assign (var_src_root));
+ value& v (rs.assign (ctx->var_src_root));
if (v)
{
@@ -1062,8 +1081,8 @@ main (int argc, char* argv[])
<< (forwarded ? "forwarded " : "specified ")
<< src_root;
- new_src_root = src_root;
- old_src_root = move (p);
+ ctx->new_src_root = src_root;
+ ctx->old_src_root = move (p);
p = src_root;
}
}
@@ -1096,7 +1115,7 @@ main (int argc, char* argv[])
// command line and import).
//
if (forwarded)
- rs.assign (var_forwarded) = true;
+ rs.assign (ctx->var_forwarded) = true;
// Sync local variable that are used below with actual values.
//
@@ -1133,7 +1152,7 @@ main (int argc, char* argv[])
// Note that the subprojects variable has already been processed
// and converted to a map by the bootstrap_src() call above.
//
- if (auto l = rs.vars[var_subprojects])
+ if (auto l = rs.vars[ctx->var_subprojects])
{
for (const auto& p: cast<subprojects> (l))
{
@@ -1148,8 +1167,8 @@ main (int argc, char* argv[])
// all be known. We store the combined action id in uint8_t;
// see <operation> for details.
//
- assert (operation_table.size () <= 128);
- assert (meta_operation_table.size () <= 128);
+ assert (ctx->operation_table.size () <= 128);
+ assert (ctx->meta_operation_table.size () <= 128);
// Since we now know all the names of meta-operations and
// operations, "lift" names that we assumed (from buildspec syntax)
@@ -1166,7 +1185,7 @@ main (int argc, char* argv[])
if (!mname.empty ())
{
- m = meta_operation_table.find (mname);
+ m = ctx->meta_operation_table.find (mname);
if (m == 0)
fail (l) << "unknown meta-operation " << mname;
@@ -1174,7 +1193,7 @@ main (int argc, char* argv[])
if (!oname.empty ())
{
- o = operation_table.find (oname);
+ o = ctx->operation_table.find (oname);
if (o == 0)
fail (l) << "unknown operation " << oname;
@@ -1197,7 +1216,7 @@ main (int argc, char* argv[])
if (mif == nullptr)
fail (l) << "target " << tn << " does not support meta-"
- << "operation " << meta_operation_table[m].name;
+ << "operation " << ctx->meta_operation_table[m].name;
}
//
// Otherwise, check that all the targets in a meta-operation
@@ -1210,7 +1229,7 @@ main (int argc, char* argv[])
if (mi == nullptr)
fail (l) << "target " << tn << " does not support meta-"
- << "operation " << meta_operation_table[mid].name;
+ << "operation " << ctx->meta_operation_table[mid].name;
if (mi != mif)
fail (l) << "different implementations of meta-operation "
@@ -1238,7 +1257,7 @@ main (int argc, char* argv[])
fail (l) << "unexpected parameters for meta-operation "
<< mif->name;
- set_current_mif (*mif);
+ ctx->current_meta_operation (*mif);
dirty = true;
}
@@ -1247,16 +1266,16 @@ main (int argc, char* argv[])
//
if (oid == 0)
{
- auto lookup =
- [&rs, &l, &tn] (operation_id o) -> const operation_info*
- {
- const operation_info* r (rs.root_extra->operations[o]);
+ auto lookup = [&ctx, &rs, &l, &tn] (operation_id o) ->
+ const operation_info*
+ {
+ const operation_info* r (rs.root_extra->operations[o]);
- if (r == nullptr)
- fail (l) << "target " << tn << " does not support "
- << "operation " << operation_table[o];
- return r;
- };
+ if (r == nullptr)
+ fail (l) << "target " << tn << " does not support "
+ << "operation " << ctx->operation_table[o];
+ return r;
+ };
if (o == 0)
o = default_id;
@@ -1324,19 +1343,19 @@ main (int argc, char* argv[])
//
else
{
- auto check =
- [&rs, &l, &tn] (operation_id o, const operation_info* i)
- {
- const operation_info* r (rs.root_extra->operations[o]);
+ auto check = [&ctx, &rs, &l, &tn] (operation_id o,
+ const operation_info* i)
+ {
+ const operation_info* r (rs.root_extra->operations[o]);
- if (r == nullptr)
- fail (l) << "target " << tn << " does not support "
- << "operation " << operation_table[o];
+ if (r == nullptr)
+ fail (l) << "target " << tn << " does not support "
+ << "operation " << ctx->operation_table[o];
- if (r != i)
- fail (l) << "different implementations of operation "
- << i->name << " in the same operation batch";
- };
+ if (r != i)
+ fail (l) << "different implementations of operation "
+ << i->name << " in the same operation batch";
+ };
check (orig_oid, oif);
@@ -1406,7 +1425,7 @@ main (int argc, char* argv[])
trace << " out_root: " << out_root;
trace << " src_root: " << src_root;
trace << " forwarded: " << (forwarded ? "true" : "false");
- if (auto l = rs.vars[var_amalgamation])
+ if (auto l = rs.vars[ctx->var_amalgamation])
{
trace << " amalgamation: " << cast<dir_path> (l);
trace << " strong scope: " << *rs.strong_scope ();
@@ -1427,9 +1446,9 @@ main (int argc, char* argv[])
// So we split it into two passes.
//
{
- auto& sm (scope_map::instance);
+ auto& sm (ctx->scopes.rw ());
- for (const variable_override& o: var_ovs)
+ for (const variable_override& o: ctx->var_overrides)
{
if (o.ovr.visibility != variable_visibility::normal)
continue;
@@ -1450,7 +1469,7 @@ main (int argc, char* argv[])
v = o.val;
}
- for (const variable_override& o: var_ovs)
+ for (const variable_override& o: ctx->var_overrides)
{
// Ours is either project (%foo) or scope (/foo).
//
@@ -1504,7 +1523,7 @@ main (int argc, char* argv[])
// building before we know how to for all the targets in this
// operation batch.
//
- const scope& bs (scopes.find (ts.out_base));
+ const scope& bs (ctx->scopes.find (ts.out_base));
// Find the target type and extract the extension.
//
@@ -1546,7 +1565,7 @@ main (int argc, char* argv[])
} // target
if (dump_load)
- dump ();
+ dump (*ctx);
// Finally, match the rules and perform the operation.
//
@@ -1558,7 +1577,7 @@ main (int argc, char* argv[])
if (mif->operation_pre != nullptr)
mif->operation_pre (mparams, pre_oid); // Cannot be translated.
- set_current_oif (*pre_oif, oif);
+ ctx->current_operation (*pre_oif, oif);
action a (mid, pre_oid, oid);
@@ -1570,7 +1589,7 @@ main (int argc, char* argv[])
mif->match (mparams, a, tgs, diag, true /* progress */);
if (dump_match)
- dump (a);
+ dump (*ctx, a);
if (mif->execute != nullptr && !ops.match_only ())
mif->execute (mparams, a, tgs, diag, true /* progress */);
@@ -1585,7 +1604,7 @@ main (int argc, char* argv[])
tgs.reset ();
}
- set_current_oif (*oif, outer_oif);
+ ctx->current_operation (*oif, outer_oif);
action a (mid, oid, oif->outer_id);
@@ -1597,7 +1616,7 @@ main (int argc, char* argv[])
mif->match (mparams, a, tgs, diag, true /* progress */);
if (dump_match)
- dump (a);
+ dump (*ctx, a);
if (mif->execute != nullptr && !ops.match_only ())
mif->execute (mparams, a, tgs, diag, true /* progress */);
@@ -1613,7 +1632,7 @@ main (int argc, char* argv[])
if (mif->operation_pre != nullptr)
mif->operation_pre (mparams, post_oid); // Cannot be translated.
- set_current_oif (*post_oif, oif);
+ ctx->current_operation (*post_oif, oif);
action a (mid, post_oid, oid);
@@ -1625,7 +1644,7 @@ main (int argc, char* argv[])
mif->match (mparams, a, tgs, diag, true /* progress */);
if (dump_match)
- dump (a);
+ dump (*ctx, a);
if (mif->execute != nullptr && !ops.match_only ())
mif->execute (mparams, a, tgs, diag, true /* progress */);
diff --git a/build2/bin/init.cxx b/build2/bin/init.cxx
index b46d643..4e80834 100644
--- a/build2/bin/init.cxx
+++ b/build2/bin/init.cxx
@@ -56,7 +56,7 @@ namespace build2
// Target is a string and not target_triplet because it can be
// specified by the user.
//
- auto& vp (var_pool.rw (rs));
+ auto& vp (rs.ctx.var_pool.rw (rs));
vp.insert<string> ("config.bin.target", true);
vp.insert<string> ("config.bin.pattern", true);
@@ -266,7 +266,7 @@ namespace build2
// config.bin.target
//
{
- const variable& var (var_pool["config.bin.target"]);
+ const variable& var (rs.ctx.var_pool["config.bin.target"]);
// We first see if the value was specified via the configuration
// mechanism.
@@ -343,7 +343,7 @@ namespace build2
// config.bin.pattern
//
{
- const variable& var (var_pool["config.bin.pattern"]);
+ const variable& var (rs.ctx.var_pool["config.bin.pattern"]);
// We first see if the value was specified via the configuration
// mechanism.
@@ -568,7 +568,7 @@ namespace build2
//
if (first)
{
- auto& v (var_pool.rw (rs));
+ auto& v (rs.ctx.var_pool.rw (rs));
v.insert<process_path> ("bin.ar.path");
v.insert<process_path> ("bin.ranlib.path");
@@ -744,7 +744,7 @@ namespace build2
//
if (first)
{
- auto& v (var_pool.rw (rs));
+ auto& v (rs.ctx.var_pool.rw (rs));
v.insert<process_path> ("bin.ld.path");
v.insert<path> ("config.bin.ld", true);
@@ -857,7 +857,7 @@ namespace build2
//
if (first)
{
- auto& v (var_pool.rw (rs));
+ auto& v (rs.ctx.var_pool.rw (rs));
v.insert<process_path> ("bin.rc.path");
v.insert<path> ("config.bin.rc", true);
diff --git a/build2/bin/target.cxx b/build2/bin/target.cxx
index ec4a0ef..9074317 100644
--- a/build2/bin/target.cxx
+++ b/build2/bin/target.cxx
@@ -88,11 +88,12 @@ namespace build2
//
template <typename M, typename G>
static target*
- m_factory (const target_type&, dir_path dir, dir_path out, string n)
+ m_factory (context& ctx,
+ const target_type&, dir_path dir, dir_path out, string n)
{
- const G* g (targets.find<G> (dir, out, n));
+ const G* g (ctx.targets.find<G> (dir, out, n));
- M* m (new M (move (dir), move (out), move (n)));
+ M* m (new M (ctx, move (dir), move (out), move (n)));
m->group = g;
return m;
@@ -104,8 +105,8 @@ namespace build2
&objx::static_type,
&m_factory<obje, obj>,
nullptr, /* fixed_extension */
- &target_extension_var<var_extension, nullptr>,
- &target_pattern_var<var_extension, nullptr>,
+ &target_extension_var<nullptr>,
+ &target_pattern_var<nullptr>,
nullptr,
&target_search, // Note: not _file(); don't look for an existing file.
false
@@ -117,8 +118,8 @@ namespace build2
&bmix::static_type,
&m_factory<bmie, bmi>,
nullptr, /* fixed_extension */
- &target_extension_var<var_extension, nullptr>,
- &target_pattern_var<var_extension, nullptr>,
+ &target_extension_var<nullptr>,
+ &target_pattern_var<nullptr>,
nullptr,
&target_search, // Note: not _file(); don't look for an existing file.
false
@@ -130,8 +131,8 @@ namespace build2
&hbmix::static_type,
&m_factory<hbmie, hbmi>,
nullptr, /* fixed_extension */
- &target_extension_var<var_extension, nullptr>,
- &target_pattern_var<var_extension, nullptr>,
+ &target_extension_var<nullptr>,
+ &target_pattern_var<nullptr>,
nullptr,
&target_search, // Note: not _file(); don't look for an existing file.
false
@@ -143,8 +144,8 @@ namespace build2
&objx::static_type,
&m_factory<obja, obj>,
nullptr, /* fixed_extension */
- &target_extension_var<var_extension, nullptr>,
- &target_pattern_var<var_extension, nullptr>,
+ &target_extension_var<nullptr>,
+ &target_pattern_var<nullptr>,
nullptr,
&target_search, // Note: not _file(); don't look for an existing file.
false
@@ -156,8 +157,8 @@ namespace build2
&bmix::static_type,
&m_factory<bmia, bmi>,
nullptr, /* fixed_extension */
- &target_extension_var<var_extension, nullptr>,
- &target_pattern_var<var_extension, nullptr>,
+ &target_extension_var<nullptr>,
+ &target_pattern_var<nullptr>,
nullptr,
&target_search, // Note: not _file(); don't look for an existing file.
false
@@ -169,8 +170,8 @@ namespace build2
&hbmix::static_type,
&m_factory<hbmia, hbmi>,
nullptr, /* fixed_extension */
- &target_extension_var<var_extension, nullptr>,
- &target_pattern_var<var_extension, nullptr>,
+ &target_extension_var<nullptr>,
+ &target_pattern_var<nullptr>,
nullptr,
&target_search, // Note: not _file(); don't look for an existing file.
false
@@ -182,8 +183,8 @@ namespace build2
&objx::static_type,
&m_factory<objs, obj>,
nullptr, /* fixed_extension */
- &target_extension_var<var_extension, nullptr>,
- &target_pattern_var<var_extension, nullptr>,
+ &target_extension_var<nullptr>,
+ &target_pattern_var<nullptr>,
nullptr,
&target_search, // Note: not _file(); don't look for an existing file.
false
@@ -195,8 +196,8 @@ namespace build2
&bmix::static_type,
&m_factory<bmis, bmi>,
nullptr, /* fixed_extension */
- &target_extension_var<var_extension, nullptr>,
- &target_pattern_var<var_extension, nullptr>,
+ &target_extension_var<nullptr>,
+ &target_pattern_var<nullptr>,
nullptr,
&target_search, // Note: not _file(); don't look for an existing file.
false
@@ -208,8 +209,8 @@ namespace build2
&hbmix::static_type,
&m_factory<hbmis, hbmi>,
nullptr, /* fixed_extension */
- &target_extension_var<var_extension, nullptr>,
- &target_pattern_var<var_extension, nullptr>,
+ &target_extension_var<nullptr>,
+ &target_pattern_var<nullptr>,
nullptr,
&target_search, // Note: not _file(); don't look for an existing file.
false
@@ -221,8 +222,8 @@ namespace build2
&libux::static_type,
&target_factory<libue>,
nullptr, /* fixed_extension */
- &target_extension_var<var_extension, nullptr>,
- &target_pattern_var<var_extension, nullptr>,
+ &target_extension_var<nullptr>,
+ &target_pattern_var<nullptr>,
nullptr,
&target_search, // Note: not _file(); don't look for an existing file.
false
@@ -234,8 +235,8 @@ namespace build2
&libux::static_type,
&m_factory<libua, libul>,
nullptr, /* fixed_extension */
- &target_extension_var<var_extension, nullptr>,
- &target_pattern_var<var_extension, nullptr>,
+ &target_extension_var<nullptr>,
+ &target_pattern_var<nullptr>,
nullptr,
&target_search, // Note: not _file(); don't look for an existing file.
false
@@ -247,8 +248,8 @@ namespace build2
&libux::static_type,
&m_factory<libus, libul>,
nullptr, /* fixed_extension */
- &target_extension_var<var_extension, nullptr>,
- &target_pattern_var<var_extension, nullptr>,
+ &target_extension_var<nullptr>,
+ &target_pattern_var<nullptr>,
nullptr,
&target_search, // Note: not _file(); don't look for an existing file.
false
@@ -258,21 +259,22 @@ namespace build2
//
template <typename G, typename E, typename A, typename S>
static target*
- g_factory (const target_type&, dir_path dir, dir_path out, string n)
+ g_factory (context& ctx,
+ const target_type&, dir_path dir, dir_path out, string n)
{
// Casts are MT-aware (during serial load).
//
- E* e (phase == run_phase::load
- ? const_cast<E*> (targets.find<E> (dir, out, n))
+ E* e (ctx.phase == run_phase::load
+ ? const_cast<E*> (ctx.targets.find<E> (dir, out, n))
: nullptr);
- A* a (phase == run_phase::load
- ? const_cast<A*> (targets.find<A> (dir, out, n))
+ A* a (ctx.phase == run_phase::load
+ ? const_cast<A*> (ctx.targets.find<A> (dir, out, n))
: nullptr);
- S* s (phase == run_phase::load
- ? const_cast<S*> (targets.find<S> (dir, out, n))
+ S* s (ctx.phase == run_phase::load
+ ? const_cast<S*> (ctx.targets.find<S> (dir, out, n))
: nullptr);
- G* g (new G (move (dir), move (out), move (n)));
+ G* g (new G (ctx, move (dir), move (out), move (n)));
if (e != nullptr) e->group = g;
if (a != nullptr) a->group = g;
@@ -323,16 +325,17 @@ namespace build2
// The same as g_factory() but without E.
//
static target*
- libul_factory (const target_type&, dir_path dir, dir_path out, string n)
+ libul_factory (context& ctx,
+ const target_type&, dir_path dir, dir_path out, string n)
{
- libua* a (phase == run_phase::load
- ? const_cast<libua*> (targets.find<libua> (dir, out, n))
+ libua* a (ctx.phase == run_phase::load
+ ? const_cast<libua*> (ctx.targets.find<libua> (dir, out, n))
: nullptr);
- libus* s (phase == run_phase::load
- ? const_cast<libus*> (targets.find<libus> (dir, out, n))
+ libus* s (ctx.phase == run_phase::load
+ ? const_cast<libus*> (ctx.targets.find<libus> (dir, out, n))
: nullptr);
- libul* g (new libul (move (dir), move (out), move (n)));
+ libul* g (new libul (ctx, move (dir), move (out), move (n)));
if (a != nullptr) a->group = g;
if (s != nullptr) s->group = g;
@@ -369,8 +372,8 @@ namespace build2
&file::static_type,
&m_factory<liba, lib>,
nullptr, /* fixed_extension */
- &target_extension_var<var_extension, nullptr>,
- &target_pattern_var<var_extension, nullptr>,
+ &target_extension_var<nullptr>,
+ &target_pattern_var<nullptr>,
nullptr,
&file_search,
false
@@ -382,8 +385,8 @@ namespace build2
&file::static_type,
&m_factory<libs, lib>,
nullptr, /* fixed_extension */
- &target_extension_var<var_extension, nullptr>,
- &target_pattern_var<var_extension, nullptr>,
+ &target_extension_var<nullptr>,
+ &target_pattern_var<nullptr>,
nullptr,
&file_search,
false
@@ -403,18 +406,19 @@ namespace build2
}
static target*
- lib_factory (const target_type&, dir_path dir, dir_path out, string n)
+ lib_factory (context& ctx,
+ const target_type&, dir_path dir, dir_path out, string n)
{
// Casts are MT-aware (during serial load).
//
- liba* a (phase == run_phase::load
- ? const_cast<liba*> (targets.find<liba> (dir, out, n))
+ liba* a (ctx.phase == run_phase::load
+ ? const_cast<liba*> (ctx.targets.find<liba> (dir, out, n))
: nullptr);
- libs* s (phase == run_phase::load
- ? const_cast<libs*> (targets.find<libs> (dir, out, n))
+ libs* s (ctx.phase == run_phase::load
+ ? const_cast<libs*> (ctx.targets.find<libs> (dir, out, n))
: nullptr);
- lib* l (new lib (move (dir), move (out), move (n)));
+ lib* l (new lib (ctx, move (dir), move (out), move (n)));
if (a != nullptr) a->group = l;
if (s != nullptr) s->group = l;
@@ -443,8 +447,8 @@ namespace build2
&file::static_type,
&target_factory<libi>,
nullptr, /* fixed_extension */
- &target_extension_var<var_extension, nullptr>,
- &target_pattern_var<var_extension, nullptr>,
+ &target_extension_var<nullptr>,
+ &target_pattern_var<nullptr>,
nullptr,
&file_search,
false
diff --git a/build2/c/init.cxx b/build2/c/init.cxx
index 5c55281..ff9cc58 100644
--- a/build2/c/init.cxx
+++ b/build2/c/init.cxx
@@ -145,7 +145,7 @@ namespace build2
// Enter all the variables and initialize the module data.
//
- auto& v (var_pool.rw (rs));
+ auto& v (rs.ctx.var_pool.rw (rs));
cc::config_data d {
cc::lang::c,
diff --git a/build2/cc/common.cxx b/build2/cc/common.cxx
index aa0eb89..4f5db4c 100644
--- a/build2/cc/common.cxx
+++ b/build2/cc/common.cxx
@@ -87,7 +87,7 @@ namespace build2
bool impl (proc_impl && proc_impl (l, la));
bool cc (false), same (false);
- auto& vp (var_pool);
+ auto& vp (top_bs.ctx.var_pool);
lookup c_e_libs;
lookup x_e_libs;
@@ -221,7 +221,7 @@ namespace build2
: &cast<dir_paths> (
bs.root_scope ()->vars[same
? x_sys_lib_dirs
- : var_pool[*t + ".sys_lib_dirs"]]);
+ : bs.ctx.var_pool[*t + ".sys_lib_dirs"]]);
};
auto find_linfo = [top_li, t, cc, &bs, &l, &li] ()
@@ -474,7 +474,7 @@ namespace build2
if (xt == nullptr)
{
if (n.qualified ())
- xt = import_existing (pk);
+ xt = import_existing (s.ctx, pk);
}
if (xt == nullptr)
@@ -494,20 +494,21 @@ namespace build2
//
template <typename T>
ulock common::
- insert_library (T*& r,
+ insert_library (context& ctx,
+ T*& r,
const string& name,
const dir_path& d,
optional<string> ext,
bool exist,
tracer& trace)
{
- auto p (targets.insert_locked (T::static_type,
- d,
- dir_path (),
- name,
- move (ext),
- true, // Implied.
- trace));
+ auto p (ctx.targets.insert_locked (T::static_type,
+ d,
+ dir_path (),
+ name,
+ move (ext),
+ true, // Implied.
+ trace));
assert (!exist || !p.second.owns_lock ());
r = &p.first.template as<T> ();
@@ -626,6 +627,8 @@ namespace build2
&name, ext,
&p, &f, exist, &trace, this] (const dir_path& d) -> bool
{
+ context& ctx (p.scope->ctx);
+
timestamp mt;
// libs
@@ -648,9 +651,10 @@ namespace build2
if (tclass == "windows")
{
libi* i (nullptr);
- insert_library (i, name, d, se, exist, trace);
+ insert_library (ctx, i, name, d, se, exist, trace);
- ulock l (insert_library (s, name, d, nullopt, exist, trace));
+ ulock l (
+ insert_library (ctx, s, name, d, nullopt, exist, trace));
if (!exist)
{
@@ -677,7 +681,7 @@ namespace build2
}
else
{
- insert_library (s, name, d, se, exist, trace);
+ insert_library (ctx, s, name, d, se, exist, trace);
s->mtime (mt);
s->path (move (f));
@@ -697,7 +701,7 @@ namespace build2
if (mt != timestamp_nonexistent)
{
- insert_library (s, name, d, se, exist, trace);
+ insert_library (ctx, s, name, d, se, exist, trace);
s->mtime (mt);
s->path (move (f));
@@ -722,7 +726,7 @@ namespace build2
// Note that this target is outside any project which we treat
// as out trees.
//
- insert_library (a, name, d, ae, exist, trace);
+ insert_library (ctx, a, name, d, ae, exist, trace);
a->mtime (mt);
a->path (move (f));
}
@@ -760,14 +764,14 @@ namespace build2
if (na && !r.first.empty ())
{
- insert_library (a, name, d, nullopt, exist, trace);
+ insert_library (ctx, a, name, d, nullopt, exist, trace);
a->mtime (timestamp_unreal);
a->path (empty_path);
}
if (ns && !r.second.empty ())
{
- insert_library (s, name, d, nullopt, exist, trace);
+ insert_library (ctx, s, name, d, nullopt, exist, trace);
s->mtime (timestamp_unreal);
s->path (empty_path);
}
@@ -821,7 +825,8 @@ namespace build2
// Enter (or find) the lib{} target group.
//
lib* lt;
- insert_library (lt, name, *pd, l ? p.tk.ext : nullopt, exist, trace);
+ insert_library (
+ p.scope->ctx, lt, name, *pd, l ? p.tk.ext : nullopt, exist, trace);
// Result.
//
diff --git a/build2/cc/common.hxx b/build2/cc/common.hxx
index c58a7f3..b24eb7d 100644
--- a/build2/cc/common.hxx
+++ b/build2/cc/common.hxx
@@ -8,6 +8,7 @@
#include <libbuild2/types.hxx>
#include <libbuild2/utility.hxx>
+#include <libbuild2/context.hxx>
#include <libbuild2/variable.hxx>
#include <build2/bin/target.hxx>
@@ -278,7 +279,8 @@ namespace build2
template <typename T>
static ulock
- insert_library (T*&,
+ insert_library (context&,
+ T*&,
const string&,
const dir_path&,
optional<string>,
diff --git a/build2/cc/compile-rule.cxx b/build2/cc/compile-rule.cxx
index 833fd44..fa43533 100644
--- a/build2/cc/compile-rule.cxx
+++ b/build2/cc/compile-rule.cxx
@@ -365,7 +365,9 @@ namespace build2
const variable& var (
com
? c_export_poptions
- : (t == x ? x_export_poptions : var_pool[t + ".export.poptions"]));
+ : (t == x
+ ? x_export_poptions
+ : l.ctx.var_pool[t + ".export.poptions"]));
append_options (args, l, var);
};
@@ -418,7 +420,9 @@ namespace build2
const variable& var (
com
? c_export_poptions
- : (t == x ? x_export_poptions : var_pool[t + ".export.poptions"]));
+ : (t == x
+ ? x_export_poptions
+ : l.ctx.var_pool[t + ".export.poptions"]));
hash_options (cs, l, var);
};
@@ -472,7 +476,9 @@ namespace build2
const variable& var (
com
? c_export_poptions
- : (t == x ? x_export_poptions : var_pool[t + ".export.poptions"]));
+ : (t == x
+ ? x_export_poptions
+ : l.ctx.var_pool[t + ".export.poptions"]));
append_prefixes (m, l, var);
};
@@ -553,7 +559,7 @@ namespace build2
// @@ MT perf: so we are going to switch the phase and execute for
// any generated header.
//
- phase_switch ps (run_phase::execute);
+ phase_switch ps (t.ctx, run_phase::execute);
target_state ns (execute_direct (a, t));
if (ns != os && ns != target_state::unchanged)
@@ -577,6 +583,8 @@ namespace build2
match_data& md (t.data<match_data> ());
+ context& ctx (t.ctx);
+
// Note: until refined below, non-BMI-generating translation unit is
// assumed non-modular.
//
@@ -692,7 +700,7 @@ namespace build2
// Start asynchronous matching of prerequisites. Wait with unlocked
// phase to allow phase switching.
//
- wait_guard wg (target::count_busy (), t[a].task_count, true);
+ wait_guard wg (ctx, ctx.count_busy (), t[a].task_count, true);
size_t start (pts.size ()); // Index of the first to be added.
for (prerequisite_member p: group_prerequisite_members (a, t))
@@ -754,7 +762,7 @@ namespace build2
continue;
}
- match_async (a, *pt, target::count_busy (), t[a].task_count);
+ match_async (a, *pt, ctx.count_busy (), t[a].task_count);
pts.push_back (prerequisite_target (pt, pi));
}
@@ -1142,7 +1150,7 @@ namespace build2
// to keep re-validating the file on every subsequent dry-run as well
// on the real run).
//
- if (u && dd.reading () && !dry_run)
+ if (u && dd.reading () && !ctx.dry_run)
dd.touch = true;
dd.close ();
@@ -2161,7 +2169,7 @@ namespace build2
//
small_vector<const target_type*, 2> tts;
- const scope& bs (scopes.find (d));
+ const scope& bs (t.ctx.scopes.find (d));
if (const scope* rs = bs.root_scope ())
{
tts = map_extension (bs, n, e);
@@ -2201,7 +2209,7 @@ namespace build2
// absolute path with a spelled-out extension to multiple targets.
//
for (const target_type* tt: tts)
- if ((r = targets.find (*tt, d, out, n, e, trace)) != nullptr)
+ if ((r = t.ctx.targets.find (*tt, d, out, n, e, trace)) != nullptr)
break;
// Note: we can't do this because of the in-source builds where
@@ -2887,7 +2895,7 @@ namespace build2
// See if this path is inside a project with an out-of-
// tree build and is in the out directory tree.
//
- const scope& bs (scopes.find (d));
+ const scope& bs (t.ctx.scopes.find (d));
if (bs.root_scope () != nullptr)
{
const dir_path& bp (bs.out_path ());
@@ -5101,18 +5109,18 @@ namespace build2
modules_sidebuild_dir /=
x);
- const scope* ps (&scopes.find (pd));
+ const scope* ps (&rs.ctx.scopes.find (pd));
if (ps->out_path () != pd)
{
// Switch the phase to load then create and load the subproject.
//
- phase_switch phs (run_phase::load);
+ phase_switch phs (rs.ctx, run_phase::load);
// Re-test again now that we are in exclusive phase (another thread
// could have already created and loaded the subproject).
//
- ps = &scopes.find (pd);
+ ps = &rs.ctx.scopes.find (pd);
if (ps->out_path () != pd)
{
@@ -5200,7 +5208,7 @@ namespace build2
// exists then we assume all this is already done (otherwise why would
// someone have created such a target).
//
- if (const file* bt = targets.find<file> (
+ if (const file* bt = bs.ctx.targets.find<file> (
tt,
pd,
dir_path (), // Always in the out tree.
@@ -5237,13 +5245,14 @@ namespace build2
}
}
- auto p (targets.insert_locked (tt,
- move (pd),
- dir_path (), // Always in the out tree.
- move (mf),
- nullopt, // Use default extension.
- true, // Implied.
- trace));
+ auto p (bs.ctx.targets.insert_locked (
+ tt,
+ move (pd),
+ dir_path (), // Always in the out tree.
+ move (mf),
+ nullopt, // Use default extension.
+ true, // Implied.
+ trace));
file& bt (static_cast<file&> (p.first));
// Note that this is racy and someone might have created this target
@@ -5295,7 +5304,7 @@ namespace build2
const target_type& tt (compile_types (li.type).hbmi);
- if (const file* bt = targets.find<file> (
+ if (const file* bt = bs.ctx.targets.find<file> (
tt,
pd,
dir_path (), // Always in the out tree.
@@ -5307,13 +5316,14 @@ namespace build2
prerequisites ps;
ps.push_back (prerequisite (ht));
- auto p (targets.insert_locked (tt,
- move (pd),
- dir_path (), // Always in the out tree.
- move (mf),
- nullopt, // Use default extension.
- true, // Implied.
- trace));
+ auto p (bs.ctx.targets.insert_locked (
+ tt,
+ move (pd),
+ dir_path (), // Always in the out tree.
+ move (mf),
+ nullopt, // Use default extension.
+ true, // Implied.
+ trace));
file& bt (static_cast<file&> (p.first));
// Note that this is racy and someone might have created this target
@@ -5550,6 +5560,8 @@ namespace build2
match_data md (move (t.data<match_data> ()));
unit_type ut (md.type);
+ context& ctx (t.ctx);
+
// While all our prerequisites are already up-to-date, we still have to
// execute them to keep the dependency counts straight. Actually, no, we
// may also have to update the modules.
@@ -5575,9 +5587,9 @@ namespace build2
{
if (md.touch)
{
- touch (tp, false, 2);
+ touch (ctx, tp, false, 2);
t.mtime (system_clock::now ());
- skip_count.fetch_add (1, memory_order_relaxed);
+ ctx.skip_count.fetch_add (1, memory_order_relaxed);
}
// Note: else mtime should be cached.
@@ -5592,7 +5604,7 @@ namespace build2
? system_clock::now ()
: timestamp_unknown);
- touch (md.dd, false, verb_never);
+ touch (ctx, md.dd, false, verb_never);
const scope& bs (t.base_scope ());
const scope& rs (*bs.root_scope ());
@@ -5941,7 +5953,7 @@ namespace build2
// translation unit (i.e., one of the imported module's has BMIs
// changed).
//
- if (!dry_run)
+ if (!ctx.dry_run)
{
try
{
@@ -6020,7 +6032,7 @@ namespace build2
if (verb >= 2)
print_process (args);
- if (!dry_run)
+ if (!ctx.dry_run)
{
// Remove the target file if this fails. If we don't do that, we
// will end up with a broken build that is up-to-date.
@@ -6053,7 +6065,7 @@ namespace build2
timestamp now (system_clock::now ());
- if (!dry_run)
+ if (!ctx.dry_run)
depdb::check_mtime (start, md.dd, tp, now);
// Should we go to the filesystem and get the new mtime? We know the
diff --git a/build2/cc/init.cxx b/build2/cc/init.cxx
index e22ece7..c83d5ed 100644
--- a/build2/cc/init.cxx
+++ b/build2/cc/init.cxx
@@ -26,27 +26,29 @@ namespace build2
static target_state
clean_module_sidebuilds (action, const scope& rs, const dir&)
{
+ context& ctx (rs.ctx);
+
const dir_path& out_root (rs.out_path ());
dir_path d (out_root / rs.root_extra->build_dir / modules_sidebuild_dir);
if (exists (d))
{
- if (build2::rmdir_r (d))
+ if (rmdir_r (ctx, d))
{
// Clean up cc/ if it became empty.
//
d = out_root / rs.root_extra->build_dir / module_dir;
if (empty (d))
{
- rmdir (d);
+ rmdir (ctx, d);
// And build/ if it also became empty (e.g., in case of a build
// with a transient configuration).
//
d = out_root / rs.root_extra->build_dir;
if (empty (d))
- rmdir (d);
+ rmdir (ctx, d);
}
return target_state::changed;
@@ -77,7 +79,7 @@ namespace build2
// Enter variables. Note: some overridable, some not.
//
- auto& v (var_pool.rw (rs));
+ auto& v (rs.ctx.var_pool.rw (rs));
auto v_t (variable_visibility::target);
@@ -276,7 +278,8 @@ namespace build2
// Prepare configuration hints. They are only used on the first load
// of bin.config so we only populate them on our first load.
//
- variable_map h;
+ variable_map h (rs.ctx);
+
if (first)
{
// Note that all these variables have already been registered.
diff --git a/build2/cc/link-rule.cxx b/build2/cc/link-rule.cxx
index bb91722..bfc31d7 100644
--- a/build2/cc/link-rule.cxx
+++ b/build2/cc/link-rule.cxx
@@ -165,14 +165,15 @@ namespace build2
// otherwise the above search would have returned the member
// target.
//
- pt = search_existing (p.prerequisite.key (tt));
+ pt = search_existing (t.ctx, p.prerequisite.key (tt));
}
}
else if (!p.is_a<libue> ())
{
// See if we also/instead have a group.
//
- pg = search_existing (p.prerequisite.key (libul::static_type));
+ pg = search_existing (t.ctx,
+ p.prerequisite.key (libul::static_type));
if (pt == nullptr)
swap (pt, pg);
@@ -483,6 +484,7 @@ namespace build2
tracer trace (x, "link_rule::apply");
file& t (xt.as<file> ());
+ context& ctx (t.ctx);
// Note that for_install is signalled by install_rule and therefore
// can only be relied upon during execute.
@@ -697,7 +699,7 @@ namespace build2
// Note that ad hoc inputs have to be explicitly marked with the
// include=adhoc prerequisite-specific variable.
//
- if (current_outer_oif != nullptr)
+ if (ctx.current_outer_oif != nullptr)
continue;
}
@@ -945,7 +947,7 @@ namespace build2
// Windows.
//
#ifdef _WIN32
- dir.state[a].assign (var_backlink) = "copy";
+ dir.state[a].assign (ctx.var_backlink) = "copy";
#endif
}
}
@@ -1163,7 +1165,7 @@ namespace build2
bool u;
if ((u = pt->is_a<libux> ()) || pt->is_a<liba> ())
{
- const variable& var (var_pool["bin.whole"]); // @@ Cache.
+ const variable& var (ctx.var_pool["bin.whole"]); // @@ Cache.
// See the bin module for the lookup semantics discussion. Note
// that the variable is not overridable so we omit find_override()
@@ -1197,7 +1199,7 @@ namespace build2
// Wait with unlocked phase to allow phase switching.
//
- wait_guard wg (target::count_busy (), t[a].task_count, true);
+ wait_guard wg (ctx, ctx.count_busy (), t[a].task_count, true);
i = start;
for (prerequisite_member p: group_prerequisite_members (a, t))
@@ -1229,7 +1231,7 @@ namespace build2
}
}
- match_async (a, *pt, target::count_busy (), t[a].task_count);
+ match_async (a, *pt, ctx.count_busy (), t[a].task_count);
mark (pt, m);
}
@@ -1473,7 +1475,7 @@ namespace build2
? (exp ? c_export_loptions : c_loptions)
: (t == x
? (exp ? x_export_loptions : x_loptions)
- : var_pool[t + (exp ? ".export.loptions" : ".loptions")]));
+ : l.ctx.var_pool[t + (exp ? ".export.loptions" : ".loptions")]));
append_options (d.args, *g, var);
}
@@ -1575,7 +1577,7 @@ namespace build2
? (exp ? c_export_loptions : c_loptions)
: (t == x
? (exp ? x_export_loptions : x_loptions)
- : var_pool[t + (exp ? ".export.loptions" : ".loptions")]));
+ : l.ctx.var_pool[t + (exp ? ".export.loptions" : ".loptions")]));
hash_options (d.cs, *g, var);
}
@@ -1747,6 +1749,8 @@ namespace build2
const file& t (xt.as<file> ());
const path& tp (t.path ());
+ context& ctx (t.ctx);
+
const scope& bs (t.base_scope ());
const scope& rs (*bs.root_scope ());
@@ -1866,7 +1870,7 @@ namespace build2
if (verb >= 3)
print_process (args);
- if (!dry_run)
+ if (!ctx.dry_run)
{
auto_rmfile rm (of);
@@ -1966,7 +1970,7 @@ namespace build2
const string& cs (
cast<string> (
rs[tsys == "win32-msvc"
- ? var_pool["bin.ld.checksum"]
+ ? ctx.var_pool["bin.ld.checksum"]
: x_checksum]));
if (dd.expect (cs) != nullptr)
@@ -2726,7 +2730,7 @@ namespace build2
//
auto_rmfile rm;
- if (!dry_run)
+ if (!ctx.dry_run)
{
rm = auto_rmfile (relt);
@@ -2823,7 +2827,7 @@ namespace build2
if (verb >= 2)
print_process (args);
- if (!dry_run)
+ if (!ctx.dry_run)
run (rl, args);
}
@@ -2843,12 +2847,12 @@ namespace build2
// For shared libraries we may need to create a bunch of symlinks (or
// fallback to hardlinks/copies on Windows).
//
- auto ln = [] (const path& f, const path& l)
+ auto ln = [&ctx] (const path& f, const path& l)
{
if (verb >= 3)
text << "ln -sf " << f << ' ' << l;
- if (dry_run)
+ if (ctx.dry_run)
return;
try
@@ -2908,12 +2912,12 @@ namespace build2
//
if (tsys == "darwin" && cast<string> (rs["bin.ar.id"]) == "generic")
{
- if (!dry_run)
- touch (tp, false /* create */, verb_never);
+ if (!ctx.dry_run)
+ touch (ctx, tp, false /* create */, verb_never);
}
}
- if (!dry_run)
+ if (!ctx.dry_run)
{
rm.cancel ();
dd.check_mtime (tp);
diff --git a/build2/cc/module.cxx b/build2/cc/module.cxx
index 36cdd1a..064d954 100644
--- a/build2/cc/module.cxx
+++ b/build2/cc/module.cxx
@@ -41,9 +41,13 @@ namespace build2
config::save_module (rs, x, 250);
- const variable& config_c_poptions (var_pool["config.cc.poptions"]);
- const variable& config_c_coptions (var_pool["config.cc.coptions"]);
- const variable& config_c_loptions (var_pool["config.cc.loptions"]);
+ auto& vp (rs.ctx.var_pool.rw (rs));
+
+ // Must already exist.
+ //
+ const variable& config_c_poptions (vp["config.cc.poptions"]);
+ const variable& config_c_coptions (vp["config.cc.coptions"]);
+ const variable& config_c_loptions (vp["config.cc.loptions"]);
// config.x
//
@@ -63,8 +67,6 @@ namespace build2
//
if (!cc_loaded)
{
- auto& vp (var_pool.rw (rs));
-
for (const char* const* pm (x_hinters); *pm != nullptr; ++pm)
{
string m (*pm);
@@ -201,7 +203,7 @@ namespace build2
{
// Prepare configuration hints.
//
- variable_map h;
+ variable_map h (rs.ctx);
// Note that all these variables have already been registered.
//
@@ -545,7 +547,7 @@ namespace build2
//
if (!cast_false<bool> (rs["cc.core.config.loaded"]))
{
- variable_map h;
+ variable_map h (rs.ctx);
if (!ci.bin_pattern.empty ())
h.assign ("config.bin.pattern") = ci.bin_pattern;
diff --git a/build2/cc/msvc.cxx b/build2/cc/msvc.cxx
index 6125fdd..7d8c3f5 100644
--- a/build2/cc/msvc.cxx
+++ b/build2/cc/msvc.cxx
@@ -365,6 +365,7 @@ namespace build2
{
// Pretty similar logic to search_library().
//
+ assert (p.scope != nullptr);
const optional<string>& ext (p.tk.ext);
const string& name (*p.tk.name);
@@ -403,7 +404,7 @@ namespace build2
// Enter the target.
//
T* t;
- common::insert_library (t, name, d, e, exist, trace);
+ common::insert_library (p.scope->ctx, t, name, d, e, exist, trace);
t->mtime (mt);
t->path (move (f));
@@ -453,6 +454,8 @@ namespace build2
{
tracer trace (x, "msvc_search_shared");
+ assert (pk.scope != nullptr);
+
libs* s (nullptr);
auto search = [&s, &ld, &d, &pk, exist, &trace] (
@@ -461,7 +464,9 @@ namespace build2
if (libi* i = msvc_search_library<libi> (
ld, d, pk, otype::s, pf, sf, exist, trace))
{
- ulock l (insert_library (s, *pk.tk.name, d, nullopt, exist, trace));
+ ulock l (
+ insert_library (
+ pk.scope->ctx, s, *pk.tk.name, d, nullopt, exist, trace));
if (!exist)
{
diff --git a/build2/cc/pkgconfig.cxx b/build2/cc/pkgconfig.cxx
index c23b746..3b4c711 100644
--- a/build2/cc/pkgconfig.cxx
+++ b/build2/cc/pkgconfig.cxx
@@ -1027,7 +1027,7 @@ namespace build2
// Parse modules and add them to the prerequisites.
//
- auto parse_modules = [&trace, &next, this]
+ auto parse_modules = [&trace, &next, &s, this]
(const pkgconf& pc, prerequisites& ps)
{
string mstr (pc.variable ("cxx_modules"));
@@ -1057,7 +1057,7 @@ namespace build2
// For now there are only C++ modules.
//
auto tl (
- targets.insert_locked (
+ s.ctx.targets.insert_locked (
*x_mod,
mp.directory (),
dir_path (),
@@ -1228,6 +1228,8 @@ namespace build2
{
tracer trace (x, "pkgconfig_save");
+ context& ctx (l.ctx);
+
const scope& bs (l.base_scope ());
const scope& rs (*bs.root_scope ());
@@ -1246,7 +1248,7 @@ namespace build2
if (verb >= 2)
text << "cat >" << p;
- if (dry_run)
+ if (ctx.dry_run)
return;
auto_rmfile arm (p);
@@ -1256,9 +1258,12 @@ namespace build2
ofdstream os (p);
{
- const project_name& n (cast<project_name> (rs.vars[var_project]));
+ const project_name& n (project (rs));
+
+ if (n.empty ())
+ fail << "no project name in " << rs;
- lookup vl (rs.vars[var_version]);
+ lookup vl (rs.vars[ctx.var_version]);
if (!vl)
fail << "no version variable in project " << n <<
info << "while generating " << p;
@@ -1271,12 +1276,12 @@ namespace build2
// This one is required so make something up if unspecified.
//
os << "Description: ";
- if (const string* s = cast_null<string> (rs[var_project_summary]))
+ if (const string* s = cast_null<string> (rs[ctx.var_project_summary]))
os << *s << endl;
else
os << n << ' ' << v << endl;
- if (const string* u = cast_null<string> (rs[var_project_url]))
+ if (const string* u = cast_null<string> (rs[ctx.var_project_url]))
os << "URL: " << *u << endl;
}
diff --git a/build2/cc/target.cxx b/build2/cc/target.cxx
index c637e60..89b9391 100644
--- a/build2/cc/target.cxx
+++ b/build2/cc/target.cxx
@@ -33,8 +33,8 @@ namespace build2
&cc::static_type,
&target_factory<h>,
nullptr, /* fixed_extension */
- &target_extension_var<var_extension, h_ext_def>,
- &target_pattern_var<var_extension, h_ext_def>,
+ &target_extension_var<h_ext_def>,
+ &target_pattern_var<h_ext_def>,
nullptr,
&file_search,
false
@@ -48,8 +48,8 @@ namespace build2
&cc::static_type,
&target_factory<c>,
nullptr, /* fixed_extension */
- &target_extension_var<var_extension, c_ext_def>,
- &target_pattern_var<var_extension, c_ext_def>,
+ &target_extension_var<c_ext_def>,
+ &target_pattern_var<c_ext_def>,
nullptr,
&file_search,
false
diff --git a/build2/cc/utility.cxx b/build2/cc/utility.cxx
index 3271f7c..e9d4ce3 100644
--- a/build2/cc/utility.cxx
+++ b/build2/cc/utility.cxx
@@ -70,9 +70,9 @@ namespace build2
// Called by the compile rule during execute.
//
- return phase == run_phase::match && !exist
+ return x.ctx.phase == run_phase::match && !exist
? &search (x, tt, x.dir, x.out, x.name)
- : search_existing (tt, x.dir, x.out, x.name);
+ : search_existing (x.ctx, tt, x.dir, x.out, x.name);
}
else
{
diff --git a/build2/cc/windows-manifest.cxx b/build2/cc/windows-manifest.cxx
index da12f0f..733cae5 100644
--- a/build2/cc/windows-manifest.cxx
+++ b/build2/cc/windows-manifest.cxx
@@ -119,7 +119,7 @@ namespace build2
if (verb >= 3)
text << "cat >" << mf;
- if (!dry_run)
+ if (!t.ctx.dry_run)
{
auto_rmfile rm (mf);
diff --git a/build2/cc/windows-rpath.cxx b/build2/cc/windows-rpath.cxx
index d81e3b0..4478f7d 100644
--- a/build2/cc/windows-rpath.cxx
+++ b/build2/cc/windows-rpath.cxx
@@ -281,7 +281,7 @@ namespace build2
// simpler.
//
{
- rmdir_status s (build2::rmdir_r (ad, empty, 3));
+ rmdir_status s (rmdir_r (t.ctx, ad, empty, 3));
if (empty)
return;
@@ -362,7 +362,7 @@ namespace build2
if (verb >= 3)
text << "cat >" << am;
- if (dry_run)
+ if (t.ctx.dry_run)
return;
auto_rmfile rm (am);
diff --git a/build2/cli/init.cxx b/build2/cli/init.cxx
index 6d20aa0..2e553f7 100644
--- a/build2/cli/init.cxx
+++ b/build2/cli/init.cxx
@@ -43,7 +43,7 @@ namespace build2
//
if (first)
{
- auto& v (var_pool.rw (rs));
+ auto& v (rs.ctx.var_pool.rw (rs));
// Note: some overridable, some not.
//
diff --git a/build2/cli/rule.cxx b/build2/cli/rule.cxx
index f6bebee..4ccafc9 100644
--- a/build2/cli/rule.cxx
+++ b/build2/cli/rule.cxx
@@ -112,7 +112,7 @@ namespace build2
// Check if there is a corresponding cli.cxx{} group.
//
- const cli_cxx* g (targets.find<cli_cxx> (t.dir, t.out, t.name));
+ const cli_cxx* g (t.ctx.targets.find<cli_cxx> (t.dir, t.out, t.name));
// If not or if it has no prerequisites (happens when we use it to
// set cli.options) and this target has a cli{} prerequisite, then
@@ -124,7 +124,7 @@ namespace build2
prerequisite_members (a, t)))
{
if (g == nullptr)
- g = &targets.insert<cli_cxx> (t.dir, t.out, t.name, trace);
+ g = &t.ctx.targets.insert<cli_cxx> (t.dir, t.out, t.name, trace);
g->prerequisites (prerequisites {p->as_prerequisite ()});
}
@@ -322,7 +322,7 @@ namespace build2
else if (verb)
text << "cli " << s;
- if (!dry_run)
+ if (!t.ctx.dry_run)
{
run (cli, args);
dd.check_mtime (tp);
diff --git a/build2/cli/target.cxx b/build2/cli/target.cxx
index 096295a..2fd70f7 100644
--- a/build2/cli/target.cxx
+++ b/build2/cli/target.cxx
@@ -23,8 +23,8 @@ namespace build2
&file::static_type,
&target_factory<cli>,
nullptr, /* fixed_extension */
- &target_extension_var<var_extension, cli_ext_def>,
- &target_pattern_var<var_extension, cli_ext_def>,
+ &target_extension_var<cli_ext_def>,
+ &target_pattern_var<cli_ext_def>,
nullptr,
&file_search,
false
@@ -45,7 +45,8 @@ namespace build2
}
static target*
- cli_cxx_factory (const target_type&, dir_path d, dir_path o, string n)
+ cli_cxx_factory (context& ctx,
+ const target_type&, dir_path d, dir_path o, string n)
{
tracer trace ("cli::cli_cxx_factory");
@@ -55,11 +56,11 @@ namespace build2
//
// Also required for the src-out remapping logic.
//
- targets.insert<cxx::hxx> (d, o, n, trace);
- targets.insert<cxx::cxx> (d, o, n, trace);
- targets.insert<cxx::ixx> (d, o, n, trace);
+ ctx.targets.insert<cxx::hxx> (d, o, n, trace);
+ ctx.targets.insert<cxx::cxx> (d, o, n, trace);
+ ctx.targets.insert<cxx::ixx> (d, o, n, trace);
- return new cli_cxx (move (d), move (o), move (n));
+ return new cli_cxx (ctx, move (d), move (o), move (n));
}
const target_type cli_cxx::static_type
diff --git a/build2/cxx/init.cxx b/build2/cxx/init.cxx
index c355763..1ffa098 100644
--- a/build2/cxx/init.cxx
+++ b/build2/cxx/init.cxx
@@ -62,7 +62,8 @@ namespace build2
//
auto enter = [&rs] (const char* v) -> const variable&
{
- return var_pool.rw (rs).insert<bool> (v, variable_visibility::project);
+ return rs.ctx.var_pool.rw (rs).insert<bool> (
+ v, variable_visibility::project);
};
// NOTE: see also module sidebuild subproject if changing anything about
@@ -370,7 +371,7 @@ namespace build2
// Enter all the variables and initialize the module data.
//
- auto& v (var_pool.rw (rs));
+ auto& v (rs.ctx.var_pool.rw (rs));
cc::config_data d {
cc::lang::cxx,
@@ -572,7 +573,7 @@ namespace build2
config_module& cm (*rs.lookup_module<config_module> ("cxx.guess"));
- auto& vp (var_pool.rw (rs));
+ auto& vp (rs.ctx.var_pool.rw (rs));
bool modules (cast<bool> (rs["cxx.features.modules"]));
diff --git a/build2/cxx/target.cxx b/build2/cxx/target.cxx
index 025bf9d..45463f3 100644
--- a/build2/cxx/target.cxx
+++ b/build2/cxx/target.cxx
@@ -19,8 +19,8 @@ namespace build2
&cc::static_type,
&target_factory<hxx>,
nullptr, /* fixed_extension */
- &target_extension_var<var_extension, hxx_ext_def>,
- &target_pattern_var<var_extension, hxx_ext_def>,
+ &target_extension_var<hxx_ext_def>,
+ &target_pattern_var<hxx_ext_def>,
nullptr,
&file_search,
false
@@ -33,8 +33,8 @@ namespace build2
&cc::static_type,
&target_factory<ixx>,
nullptr, /* fixed_extension */
- &target_extension_var<var_extension, ixx_ext_def>,
- &target_pattern_var<var_extension, ixx_ext_def>,
+ &target_extension_var<ixx_ext_def>,
+ &target_pattern_var<ixx_ext_def>,
nullptr,
&file_search,
false
@@ -47,8 +47,8 @@ namespace build2
&cc::static_type,
&target_factory<txx>,
nullptr, /* fixed_extension */
- &target_extension_var<var_extension, txx_ext_def>,
- &target_pattern_var<var_extension, txx_ext_def>,
+ &target_extension_var<txx_ext_def>,
+ &target_pattern_var<txx_ext_def>,
nullptr,
&file_search,
false
@@ -61,8 +61,8 @@ namespace build2
&cc::static_type,
&target_factory<cxx>,
nullptr, /* fixed_extension */
- &target_extension_var<var_extension, cxx_ext_def>,
- &target_pattern_var<var_extension, cxx_ext_def>,
+ &target_extension_var<cxx_ext_def>,
+ &target_pattern_var<cxx_ext_def>,
nullptr,
&file_search,
false
@@ -75,8 +75,8 @@ namespace build2
&cc::static_type,
&target_factory<mxx>,
nullptr, /* fixed_extension */
- &target_extension_var<var_extension, mxx_ext_def>,
- &target_pattern_var<var_extension, mxx_ext_def>,
+ &target_extension_var<mxx_ext_def>,
+ &target_pattern_var<mxx_ext_def>,
nullptr,
&file_search,
false