From e5664cb06e54d50e42e7722d5eaafd3cae2313b0 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 19 Jul 2017 18:51:51 +0200 Subject: Add support for explicit fsdir{} specification --- build2/algorithm.cxx | 46 ++++++++++++++++++++++++++++++++-------------- build2/algorithm.hxx | 5 +++++ 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 (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 ()) + { + const target& pt (search (t, p)); - l6 ([&]{trace << d << " for " << t;}); + if (pt.dir == d) + { + r = &pt.as (); + 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 (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); -- cgit v1.1