aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2017-07-19 18:51:51 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2017-07-19 18:51:51 +0200
commite5664cb06e54d50e42e7722d5eaafd3cae2313b0 (patch)
tree5ad53d207607d011d9f2c1999dad1af3aa42f879
parent2d9c7b8c018f161cb22e1bccb207c46e1eac8497 (diff)
Add support for explicit fsdir{} specification
-rw-r--r--build2/algorithm.cxx46
-rw-r--r--build2/algorithm.hxx5
2 files changed, 37 insertions, 14 deletions
diff --git a/build2/algorithm.cxx b/build2/algorithm.cxx
index a55b885..cbe27b6 100644
--- a/build2/algorithm.cxx
+++ b/build2/algorithm.cxx
@@ -768,28 +768,46 @@ namespace build2
// If root scope is NULL, then this can mean that we are out of any
// project or if the directory is in src_root. In both cases we don't
- // inject anything.
+ // inject anything unless explicitly requested.
//
// Note that we also used to bail out if this is the root of the
// project. But that proved not to be such a great idea in case of
// subprojects (e.g., tests/).
//
- if (rs == nullptr)
- return nullptr;
+ const fsdir* r (nullptr);
+ if (rs != nullptr && !d.sub (rs->src_path ()))
+ {
+ l6 ([&]{trace << d << " for " << t;});
- // Handle the src_root = out_root.
- //
- if (d.sub (rs->src_path ()))
- return nullptr;
+ // Target is in the out tree, so out directory is empty.
+ //
+ r = &search<fsdir> (t, d, dir_path (), string (), nullptr, nullptr);
+ }
+ else
+ {
+ // See if one was mentioned explicitly.
+ //
+ for (const prerequisite& p: group_prerequisites (t))
+ {
+ if (p.is_a<fsdir> ())
+ {
+ const target& pt (search (t, p));
- l6 ([&]{trace << d << " for " << t;});
+ if (pt.dir == d)
+ {
+ r = &pt.as<fsdir> ();
+ break;
+ }
+ }
+ }
+ }
+
+ if (r != nullptr)
+ {
+ match (a, *r);
+ t.prerequisite_targets.emplace_back (r);
+ }
- // Target is in the out tree, so out directory is empty.
- //
- const fsdir* r (
- &search<fsdir> (t, d, dir_path (), string (), nullptr, nullptr));
- match (a, *r);
- t.prerequisite_targets.emplace_back (r);
return r;
}
diff --git a/build2/algorithm.hxx b/build2/algorithm.hxx
index fc5e02a..5b52069 100644
--- a/build2/algorithm.hxx
+++ b/build2/algorithm.hxx
@@ -239,6 +239,11 @@ namespace build2
// the injected target or NULL. Normally this function is called from the
// rule's apply() function.
//
+ // As an extension, this function will also search for an existing fsdir{}
+ // prerequisite for the directory and if one exists, return that (even if
+ // the target is in src tree). This can be used, for example, to place
+ // output into an otherwise non-existent directory.
+ //
const fsdir*
inject_fsdir (action, target&, bool parent = true);