aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2016-07-22 09:23:55 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2016-07-22 09:23:55 +0200
commit4c3e451a852b537c04f5b73af23639902117b94f (patch)
tree951c165070ebf531580dcecef85976dc194e735d
parentc1d08dbc56d0c8d3346deaba5d6b1946b6d711f4 (diff)
Change default var override from 'projects and subprojects' to amalgamation
The 'projects and subprojects' semantics resulted in some counter-intuitive behavior. For example, in a project with tests/ as a subproject if one builds one of the tests directly with a non-global override (say C++ compiler), then the main project would be built without the overrides. I this light, overriding in the whole amalgamation seems like the right thing to do. The old behavior can still be obtained with scope qualification, for example: b ./:foo=bar
-rw-r--r--build2/b.cxx36
-rw-r--r--build2/context.cxx3
-rw-r--r--tests/variable/override/p/loader1
-rwxr-xr-xtests/variable/override/test.sh10
4 files changed, 47 insertions, 3 deletions
diff --git a/build2/b.cxx b/build2/b.cxx
index 3cd8793..d16c0c6 100644
--- a/build2/b.cxx
+++ b/build2/b.cxx
@@ -790,14 +790,44 @@ main (int argc, char* argv[])
// second sitution so if it is already set, then it can only be the
// first case.
//
- bool first (true);
+ // This is further complicated by the project vs amalgamation logic
+ // (we may have already done the amalgamation but not the project).
+ //
+ 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));
+
+ if (!p.second)
+ {
+ if (first_a)
+ break;
+
+ fail << "multiple amalgamation overrides of variable "
+ << o.var.name;
+ }
+
+ value& v (p.first);
+ v = o.val;
+ first_a = false;
+ }
+
+ 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;
+
auto p (rs.vars.insert (o.ovr));
if (!p.second)
{
- if (first)
+ if (first_p)
break;
fail << "multiple project overrides of variable " << o.var.name;
@@ -805,7 +835,7 @@ main (int argc, char* argv[])
value& v (p.first);
v = o.val;
- first = false;
+ first_p = false;
}
ts.root_scope = &rs;
diff --git a/build2/context.cxx b/build2/context.cxx
index 60e55bd..e08fb52 100644
--- a/build2/context.cxx
+++ b/build2/context.cxx
@@ -183,6 +183,9 @@ namespace build2
if (r.first.type != nullptr)
fail << "typed override of variable " << n;
+ // Global and scope overrides we can enter directly. Project ones will
+ // be entered by the caller for for each amalgamation/project.
+ //
if (c == '!' || !dir.empty ())
{
scope& s (c == '!' ? gs : scopes.insert (dir, false)->second);
diff --git a/tests/variable/override/p/loader b/tests/variable/override/p/loader
new file mode 100644
index 0000000..f298dcc
--- /dev/null
+++ b/tests/variable/override/p/loader
@@ -0,0 +1 @@
+include ../buildfile
diff --git a/tests/variable/override/test.sh b/tests/variable/override/test.sh
index e960929..a8b08b2 100755
--- a/tests/variable/override/test.sh
+++ b/tests/variable/override/test.sh
@@ -103,6 +103,16 @@ p/d : X
p/d/t : X
EOF
+test v=X --buildfile loader ./p/ <<EOF
+/ :
+. : X
+d : X
+d/t : X
+p : X
+p/d : X
+p/d/t : X
+EOF
+
test /v=X <<EOF
/ :
. : X