diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2018-11-09 11:45:02 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2018-11-09 11:45:02 +0200 |
commit | accbdae9b6e985d663d8af57375c7861ecd755a1 (patch) | |
tree | 6e6016a1a6ebdaccf2ef67b29c4236aa23914573 /build2/b.cxx | |
parent | 6158e136e105aae2f032a159ce807db68abee281 (diff) |
Add support for relative to base scope command line variable overrides
Currently, if we say:
$ b dir/ ./foo=bar
The scope the foo=bar is set on is relative to CWD, not dir/. While this
may seem wrong at first, this is the least surprising behavior when we
take into account that there can be multiple dir/'s.
Sometimes, however, we do want the override directory to be treated relative
to (every) target's base scope that we are building. To support this we are
extending the '.' and '..' special directory names (which are still resolved
relative to CWD) with '...', which means "relative to the base scope of every
target in the buildspec". For example:
$ b dir/ .../foo=bar
Is equivalent to:
$ b dir/ dir/foo=bar
And:
$ b liba/ libb/ .../tests/foo=bar
Is equivalent to:
$ b liba/ libb/ liba/tests/foo=bar libb/tests/foo=bar
Diffstat (limited to 'build2/b.cxx')
-rw-r--r-- | build2/b.cxx | 81 |
1 files changed, 49 insertions, 32 deletions
diff --git a/build2/b.cxx b/build2/b.cxx index aedda7f..c1bf07d 100644 --- a/build2/b.cxx +++ b/build2/b.cxx @@ -1192,50 +1192,67 @@ main (int argc, char* argv[]) // // This is further complicated by the project vs amalgamation logic // (we may have already done the amalgamation but not the project). + // So we split it into two passes. // - bool first_a (true); - for (const variable_override& o: var_ovs) { - if (o.ovr.visibility != variable_visibility::normal) - continue; - - auto p (rs.weak_scope ()->vars.insert (o.ovr)); + auto& sm (scope_map::instance); - if (!p.second) + bool first_a (true); + for (const variable_override& o: var_ovs) { - if (first_a) - break; + if (o.ovr.visibility != variable_visibility::normal) + continue; - fail << "multiple amalgamation overrides of variable " - << o.var.name; - } + // If we have a directory, enter the scope, similar to how we do + // it in the context's reset(). + // + scope& s (o.dir + ? sm.insert ((out_base / *o.dir).normalize ())->second + : *rs.weak_scope ()); - value& v (p.first); - v = o.val; - first_a = false; - } + auto p (s.vars.insert (o.ovr)); - bool first_p (true); - for (const variable_override& o: var_ovs) - { - // Ours is either project (%foo) or scope (/foo). - // - if (o.ovr.visibility == variable_visibility::normal) - continue; + if (!p.second) + { + if (first_a) + break; + + fail << "multiple " << (o.dir ? "scope" : "amalgamation") + << " overrides of variable " << o.var.name; + } - auto p (rs.vars.insert (o.ovr)); + value& v (p.first); + v = o.val; + first_a = false; + } - if (!p.second) + bool first_p (true); + for (const variable_override& o: var_ovs) { - if (first_p) - break; + // Ours is either project (%foo) or scope (/foo). + // + if (o.ovr.visibility == variable_visibility::normal) + continue; - fail << "multiple project overrides of variable " << o.var.name; - } + scope& s (o.dir + ? sm.insert ((out_base / *o.dir).normalize ())->second + : rs); + + auto p (s.vars.insert (o.ovr)); - value& v (p.first); - v = o.val; - first_p = false; + if (!p.second) + { + if (first_p) + break; + + fail << "multiple " << (o.dir ? "scope" : "project") + << " overrides of variable " << o.var.name; + } + + value& v (p.first); + v = o.val; + first_p = false; + } } ts.root_scope = &rs; |