aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build2/algorithm16
-rw-r--r--build2/algorithm.cxx30
-rw-r--r--build2/cli/rule.cxx2
-rw-r--r--build2/cxx/compile.cxx2
-rw-r--r--build2/cxx/link.cxx2
-rw-r--r--build2/rule.cxx12
6 files changed, 37 insertions, 27 deletions
diff --git a/build2/algorithm b/build2/algorithm
index e57b94d..509e478 100644
--- a/build2/algorithm
+++ b/build2/algorithm
@@ -36,8 +36,8 @@ namespace build2
target&
search (const target_type&, const prerequisite_key&);
- // As above but specify the prerequisite to search as individual
- // key components.
+ // As above but specify the prerequisite to search as individual key
+ // components. Scope can be NULL if the directory is absolute.
//
target&
search (const target_type& type,
@@ -130,13 +130,15 @@ namespace build2
group_view
resolve_group_members (action, target&);
- // Inject dependency on the parent directory's fsdir{}, unless it is outside
- // of any project (say, for example, an installation directory). Return the
- // injected target or NULL. Normally this function is called from the rule's
- // apply() function.
+ // Inject dependency on the target's directory fsdir{}, unless it is in the
+ // src tree, root of the project, or is outside of any project (say, for
+ // example, an installation directory). If the parent argument is true, then
+ // inject the parent directory of a target that is itself a directory (name
+ // is empty). Return the injected target or NULL. Normally this function is
+ // called from the rule's apply() function.
//
fsdir*
- inject_parent_fsdir (action, target&);
+ inject_fsdir (action, target&, bool parent = true);
// Execute the action on target, assuming a rule has been matched
// and the recipe for this action has been set. This is the default
diff --git a/build2/algorithm.cxx b/build2/algorithm.cxx
index 51d2725..59a7800 100644
--- a/build2/algorithm.cxx
+++ b/build2/algorithm.cxx
@@ -305,31 +305,33 @@ namespace build2
}
fsdir*
- inject_parent_fsdir (action a, target& t)
+ inject_fsdir (action a, target& t, bool parent)
{
- tracer trace ("inject_parent_fsdir");
+ tracer trace ("inject_fsdir");
- scope& s (t.base_scope ());
- scope* rs (s.root_scope ());
+ scope& bs (t.base_scope ());
+ scope* rs (bs.root_scope ());
- if (rs == nullptr) // Could be outside any project.
+ // Handle the outside of any project and at root scope cases.
+ //
+ if (rs == nullptr || &bs == rs)
return nullptr;
- const dir_path& out_root (rs->out_path ());
-
- // If t is a directory (name is empty), say foo/bar/, then
- // t is bar and its parent directory is foo/.
+ // If t is a directory (name is empty), say foo/bar/, then t is bar and
+ // its parent directory is foo/.
//
- const dir_path& d (t.name.empty () ? t.dir.directory () : t.dir);
+ const dir_path& d (parent && t.name.empty () ? t.dir.directory () : t.dir);
- if (!d.sub (out_root))
+ // Handle the src = out and (again) root scope cases.
+ //
+ if (d.sub (rs->src_path ()) || d == rs->out_path ())
return nullptr;
- l6 ([&]{trace << "for " << t;});
+ l6 ([&]{trace << d << " for " << t;});
- // Target in the out tree, so out directory is empty.
+ // Target is in the out tree, so out directory is empty.
//
- fsdir* r (&search<fsdir> (d, dir_path (), string (), nullptr, &s));
+ fsdir* r (&search<fsdir> (d, dir_path (), string (), nullptr, nullptr));
match (a, *r);
t.prerequisite_targets.emplace_back (r);
return r;
diff --git a/build2/cli/rule.cxx b/build2/cli/rule.cxx
index 139abc6..26c17cd 100644
--- a/build2/cli/rule.cxx
+++ b/build2/cli/rule.cxx
@@ -184,7 +184,7 @@ namespace build2
// Inject dependency on the output directory.
//
- inject_parent_fsdir (a, t);
+ inject_fsdir (a, t);
// Search and match prerequisite members.
//
diff --git a/build2/cxx/compile.cxx b/build2/cxx/compile.cxx
index e0fabb4..25416e8 100644
--- a/build2/cxx/compile.cxx
+++ b/build2/cxx/compile.cxx
@@ -82,7 +82,7 @@ namespace build2
// Inject dependency on the output directory.
//
- fsdir* dir (inject_parent_fsdir (a, t));
+ fsdir* dir (inject_fsdir (a, t));
// Search and match all the existing prerequisites. The injection
// code (below) takes care of the ones it is adding.
diff --git a/build2/cxx/link.cxx b/build2/cxx/link.cxx
index 1818be6..82d98a1 100644
--- a/build2/cxx/link.cxx
+++ b/build2/cxx/link.cxx
@@ -694,7 +694,7 @@ namespace build2
// Inject dependency on the output directory.
//
- inject_parent_fsdir (a, t);
+ inject_fsdir (a, t);
optional<dir_paths> lib_paths; // Extract lazily.
diff --git a/build2/rule.cxx b/build2/rule.cxx
index b010ae2..cbb7d08 100644
--- a/build2/rule.cxx
+++ b/build2/rule.cxx
@@ -144,6 +144,11 @@ namespace build2
recipe alias_rule::
apply (action a, target& t, const match_result&) const
{
+ // Inject dependency on our directory (note: not parent) so that it is
+ // automatically created on update and removed on clean.
+ //
+ inject_fsdir (a, t, false);
+
search_and_match_prerequisites (a, t);
return default_recipe;
}
@@ -161,11 +166,12 @@ namespace build2
recipe fsdir_rule::
apply (action a, target& t, const match_result&) const
{
- // Inject dependency on the parent directory. Note that we
- // don't do it for clean since we shouldn't be removing it.
+ // Inject dependency on the parent directory. Note that we don't do it for
+ // clean since we shouldn't (and can't possibly, since it's our parent) be
+ // removing it.
//
if (a.operation () != clean_id)
- inject_parent_fsdir (a, t);
+ inject_fsdir (a, t);
search_and_match_prerequisites (a, t);