aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2016-08-05 16:38:18 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2016-08-05 16:38:18 +0200
commit1b01309cf61f45ffc5862a2c3da8c71324bc77b3 (patch)
tree1072ef7d6fb35e3e86eb68ae4e5363a3742f4eee
parent0f1697e7465f15590a115dedb4516568f1e30db8 (diff)
Implement out-qualified target syntax for setting target-specific vars
So now we can do: doc{INSTALL}@./: install = false Note that so far that's the only place where we support out-qualification. Grep for @@ OUT to see other places.
-rw-r--r--build2/parser.cxx71
-rw-r--r--build2/target.cxx2
-rw-r--r--tests/target/out-qualified/src/build/bootstrap.build2
-rw-r--r--tests/target/out-qualified/src/buildfile5
-rw-r--r--tests/target/out-qualified/src/foo0
-rwxr-xr-xtests/target/out-qualified/test.sh3
-rwxr-xr-xtests/test.sh1
7 files changed, 66 insertions, 18 deletions
diff --git a/build2/parser.cxx b/build2/parser.cxx
index 009316f..82be698 100644
--- a/build2/parser.cxx
+++ b/build2/parser.cxx
@@ -98,7 +98,11 @@ namespace build2
public:
enter_target (): p_ (nullptr), t_ (nullptr) {}
- enter_target (parser& p, name&& n, const location& loc, tracer& tr)
+ enter_target (parser& p,
+ name&& n, // If n.pair, then o is out dir.
+ name&& o,
+ const location& loc,
+ tracer& tr)
: p_ (&p), t_ (p.target_)
{
const string* e;
@@ -107,26 +111,41 @@ namespace build2
if (ti == nullptr)
p.fail (loc) << "unknown target type " << n.type;
+ bool src (n.pair); // If out-qualified, then it is from src.
+ if (src)
+ {
+ assert (n.pair == '@');
+
+ if (!o.directory ())
+ p.fail (loc) << "directory expected after @";
+ }
+
dir_path& d (n.dir);
+ const dir_path& sd (p.scope_->src_path ());
+ const dir_path& od (p.scope_->out_path ());
+
if (d.empty ())
- d = p.scope_->out_path (); // Already normalized.
+ d = src ? sd : od; // Already dormalized.
else
{
if (d.relative ())
- d = p.scope_->out_path () / d;
+ d = (src ? sd : od) / d;
d.normalize ();
}
+ dir_path out;
+ if (src && sd != od) // If in-source build, then out must be empty.
+ {
+ out = o.dir.relative () ? od / o.dir : move (o.dir);
+ out.normalize ();
+ }
+
// Find or insert.
//
- // @@ OUT: for now we assume the target is always in the out tree. The
- // only way to specify an src prerequisite will be with the explicit
- // @-syntax.
- //
p.target_ = &targets.insert (
- *ti, move (d), dir_path (), move (n.value), e, tr).first;
+ *ti, move (d), move (out), move (n.value), e, tr).first;
}
~enter_target ()
@@ -454,14 +473,19 @@ namespace build2
// may contain variable expansions that would be sensitive to
// the target/scope context in which they are evaluated.
//
- replay_guard rg (*this, ns.size () > 1);
+ // Note: watch out for an out-qualified single target (two names).
+ //
+ replay_guard rg (
+ *this, ns.size () > 2 || (ns.size () == 2 && !ns[0].pair));
- for (name& n: ns)
+ for (auto i (ns.begin ()), e (ns.end ()); i != e; )
{
+ name& n (*i);
+
if (n.qualified ())
fail (nloc) << "project name in scope/target " << n;
- if (n.directory ())
+ if (n.directory () && !n.pair) // Not out-qualified.
{
// Scope variable.
//
@@ -477,13 +501,18 @@ namespace build2
if (p == string::npos)
{
- enter_target tg (*this, move (n), nloc, trace);
+ name o (n.pair ? move (*++i) : name ());
+ enter_target tg (*this, move (n), move (o), nloc, trace);
variable (t, tt, var, att);
}
else
{
// See tests/variable/type-pattern.
//
+ if (n.pair)
+ fail (nloc) << "out-qualified target type/pattern-"
+ << "specific variable";
+
if (n.value.find ('*', p + 1) != string::npos)
fail (nloc) << "multiple wildcards in target type/pattern "
<< n;
@@ -591,7 +620,8 @@ namespace build2
}
}
- rg.play (); // Replay.
+ if (++i != e)
+ rg.play (); // Replay.
}
}
// Dependency declaration.
@@ -650,7 +680,9 @@ namespace build2
if (tn.qualified ())
fail (nloc) << "project name in target " << tn;
- enter_target tg (*this, move (tn), nloc, trace);
+ // @@ OUT TODO
+ //
+ enter_target tg (*this, move (tn), name (), nloc, trace);
//@@ OPT: move if last/single target (common cases).
//
@@ -2209,7 +2241,7 @@ namespace build2
else if (tt == type::lparen)
{
expire_mode ();
- value v (eval (t, tt));
+ value v (eval (t, tt)); //@@ OUT will parse @-pair and do well?
if (!v)
fail (loc) << "null variable/function name";
@@ -2233,6 +2265,8 @@ namespace build2
if (qual.empty ())
fail (loc) << "empty variable/function qualification";
+
+ qual.pair = '\0'; // We broke up the pair.
}
name = move (ns[n - 1].value);
@@ -2313,10 +2347,13 @@ namespace build2
enter_scope sg;
enter_target tg;
- if (qual.directory ())
+ if (qual.directory ()) //@@ OUT
sg = enter_scope (*this, move (qual.dir));
else if (!qual.empty ())
- tg = enter_target (*this, move (qual), loc, trace);
+ // @@ OUT TODO
+ //
+ tg = enter_target (
+ *this, move (qual), build2::name (), loc, trace);
// Lookup.
//
diff --git a/build2/target.cxx b/build2/target.cxx
index d9dd12e..a0283b0 100644
--- a/build2/target.cxx
+++ b/build2/target.cxx
@@ -300,7 +300,7 @@ namespace build2
os << '@' << o;
}
else
- os << '@' << k.out;
+ os << '@' << *k.out;
}
return os;
diff --git a/tests/target/out-qualified/src/build/bootstrap.build b/tests/target/out-qualified/src/build/bootstrap.build
new file mode 100644
index 0000000..056ee6f
--- /dev/null
+++ b/tests/target/out-qualified/src/build/bootstrap.build
@@ -0,0 +1,2 @@
+project = test
+amalgamation =
diff --git a/tests/target/out-qualified/src/buildfile b/tests/target/out-qualified/src/buildfile
new file mode 100644
index 0000000..1bcaa32
--- /dev/null
+++ b/tests/target/out-qualified/src/buildfile
@@ -0,0 +1,5 @@
+./: file{foo}
+
+# Use --verbose 6 to debug.
+#
+file{foo}@./: x = y
diff --git a/tests/target/out-qualified/src/foo b/tests/target/out-qualified/src/foo
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/target/out-qualified/src/foo
diff --git a/tests/target/out-qualified/test.sh b/tests/target/out-qualified/test.sh
new file mode 100755
index 0000000..f1ece0e
--- /dev/null
+++ b/tests/target/out-qualified/test.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+b -q src/@out/
diff --git a/tests/test.sh b/tests/test.sh
index f29b43a..9ce7152 100755
--- a/tests/test.sh
+++ b/tests/test.sh
@@ -22,6 +22,7 @@ test "names"
test "pairs"
test "quote"
test "scope"
+test "target/out-qualified"
test "variable/dir-path"
test "variable/expansion"
test "variable/null"