aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2015-08-14 15:47:34 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2015-08-14 15:47:34 +0200
commitf62ff2e840fd92a03b4a3298de938d426f8b5c7a (patch)
treeaf8c7a85c5bdc4bd8bc60632aa6929cb27b98284
parent9fa5209175dffb881e8ec6c5f6ad4fc54448244a (diff)
Fix several issues in outer operation recipe override logic
-rw-r--r--build/bin/rule.cxx10
-rw-r--r--build/target24
-rw-r--r--build/target.cxx40
3 files changed, 50 insertions, 24 deletions
diff --git a/build/bin/rule.cxx b/build/bin/rule.cxx
index 8507497..a09bffd 100644
--- a/build/bin/rule.cxx
+++ b/build/bin/rule.cxx
@@ -79,7 +79,15 @@ namespace build
match_only (a, *t.so);
}
- return match_result (t, &type);
+ match_result mr (t, &type);
+
+ // If there is an outer operation, indicate that we match
+ // unconditionally so that we don't override ourselves.
+ //
+ if (a.outer_operation () != 0)
+ mr.recipe_action = action (a.meta_operation (), a.operation ());
+
+ return mr;
}
recipe lib_rule::
diff --git a/build/target b/build/target
index dd58b24..35b013a 100644
--- a/build/target
+++ b/build/target
@@ -328,29 +328,7 @@ namespace build
recipe (action_type a) const {return a > action ? empty_recipe : recipe_;}
void
- recipe (action_type a, recipe_type r)
- {
- assert (a > action || !recipe_);
- action = a;
- recipe_ = std::move (r);
-
- // Also reset the target state. If this is a noop recipe, then
- // mark the target unchanged so that we don't waste time executing
- // the recipe. If this is a group recipe, then mark the state as
- // coming from the group.
- //
- raw_state = target_state::unknown;
-
- if (recipe_function** f = recipe_.target<recipe_function*> ())
- {
- if (*f == &noop_action)
- raw_state = target_state::unchanged;
- else if (*f == &group_action)
- raw_state = target_state::group;
- }
-
- dependents = 0;
- }
+ recipe (action_type, recipe_type);
// Target type info.
//
diff --git a/build/target.cxx b/build/target.cxx
index 033a7f9..236b729 100644
--- a/build/target.cxx
+++ b/build/target.cxx
@@ -51,6 +51,46 @@ namespace build
//
void target::
+ recipe (action_type a, recipe_type r)
+ {
+ assert (a > action || !recipe_);
+
+ bool override (a == action && recipe_); // See action::operator<.
+
+ // Only noop_recipe can be overridden.
+ //
+ if (override)
+ {
+ recipe_function** f (recipe_.target<recipe_function*> ());
+ assert (f != nullptr && *f == &noop_action);
+ }
+
+ action = a;
+ recipe_ = std::move (r);
+
+ // Also reset the target state. If this is a noop recipe, then
+ // mark the target unchanged so that we don't waste time executing
+ // the recipe. If this is a group recipe, then mark the state as
+ // coming from the group.
+ //
+ raw_state = target_state::unknown;
+
+ if (recipe_function** f = recipe_.target<recipe_function*> ())
+ {
+ if (*f == &noop_action)
+ raw_state = target_state::unchanged;
+ else if (*f == &group_action)
+ raw_state = target_state::group;
+ }
+
+ // This one is tricky: we don't want to reset the dependents count
+ // if we are merely overriding with a "stronger" recipe.
+ //
+ if (!override)
+ dependents = 0;
+ }
+
+ void target::
reset (action_type)
{
prerequisite_targets.clear ();