aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2017-03-14 14:44:03 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2017-03-14 14:44:03 +0200
commitbee7ac72e5cf6856c1dd94875eb3026aeedf702d (patch)
tree9415eb7e9afd860032c1e3e0d1488d291ed7290a
parent0275a8661dce5b89960d2baf6245bf08679fb596 (diff)
Preserve failed state even if recipe is overridden
-rw-r--r--build2/target4
-rw-r--r--build2/target.cxx5
-rw-r--r--build2/target.ixx21
3 files changed, 20 insertions, 10 deletions
diff --git a/build2/target b/build2/target
index c196060..e7e15ab 100644
--- a/build2/target
+++ b/build2/target
@@ -500,8 +500,10 @@ namespace build2
bool
group_state () const;
+ // Raw state, normally not accessed directly.
+ //
public:
- target_state state_; // Raw state, normally not accessed directly.
+ target_state state_ = target_state::unknown;
// Recipe.
//
diff --git a/build2/target.cxx b/build2/target.cxx
index 668db92..81d0e4b 100644
--- a/build2/target.cxx
+++ b/build2/target.cxx
@@ -174,10 +174,11 @@ namespace build2
// We have the spin-lock. Quickly get the matched action and unlock.
//
action_type ma (action);
+ bool failed (state_ == target_state::failed);
task_count.store (e, memory_order_release);
- if (ma > a)
- return target_state::unchanged; // Overriden.
+ if (ma > a) // Overriden.
+ return failed ? target_state::failed: target_state::unchanged;
// Otherwise we should have a matched target.
//
diff --git a/build2/target.ixx b/build2/target.ixx
index 0be5aed..eb7dbaa 100644
--- a/build2/target.ixx
+++ b/build2/target.ixx
@@ -129,15 +129,22 @@ namespace build2
{
recipe_ = move (r);
- // If this is a noop recipe, then mark the target unchanged to allow for
- // some optimizations.
+ // Do not clear the failed target state in case of an override (and we
+ // should never see the failed state from the previous operation since we
+ // should abort the execution in this case).
//
- state_ = target_state::unknown;
-
- if (recipe_function** f = recipe_.target<recipe_function*> ())
+ if (state_ != target_state::failed)
{
- if (*f == &noop_action)
- state_ = target_state::unchanged;
+ // If this is a noop recipe, then mark the target unchanged to allow for
+ // some optimizations.
+ //
+ state_ = target_state::unknown;
+
+ if (recipe_function** f = recipe_.target<recipe_function*> ())
+ {
+ if (*f == &noop_action)
+ state_ = target_state::unchanged;
+ }
}
}