aboutsummaryrefslogtreecommitdiff
path: root/build2
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2017-03-03 10:05:16 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2017-03-03 10:05:16 +0200
commitbcb5045dff9e87decbad3a785eb1fe42f4fc1410 (patch)
treed5ed2b39f3704e28f0707b61cd50114cfe775d4c /build2
parent2069cbb8f72bceb0fcb968ba05968a24eeb0c15d (diff)
Use final action state after match at top level (operation)
Diffstat (limited to 'build2')
-rw-r--r--build2/operation.cxx17
-rw-r--r--build2/target19
-rw-r--r--build2/target.ixx13
3 files changed, 40 insertions, 9 deletions
diff --git a/build2/operation.cxx b/build2/operation.cxx
index 1fe70df..ff2051d 100644
--- a/build2/operation.cxx
+++ b/build2/operation.cxx
@@ -126,9 +126,20 @@ namespace build2
{
const target& t (*static_cast<const target*> (ts[j]));
- target_state s (j < i
- ? match (a, t, false)
- : target_state::postponed);
+ // Finish matching targets that we have started. Note that we use the
+ // state for the "final" action that will be executed and not our
+ // action. Failed that, we may fail to find a match for a "stronger"
+ // action but will still get unchanged for the original one.
+ //
+ target_state s;
+ if (j < i)
+ {
+ match (a, t, false);
+ s = t.serial_state (false);
+ }
+ else
+ s = target_state::postponed;
+
switch (s)
{
case target_state::postponed:
diff --git a/build2/target b/build2/target
index 563e32f..71571bc 100644
--- a/build2/target
+++ b/build2/target
@@ -453,19 +453,26 @@ namespace build2
mutable atomic_count task_count {0}; // Start offset_touched - 1.
- // This function can only be called during match if we have observed
+ // This function should only be called during match if we have observed
// (synchronization-wise) that the this target has been matched (i.e.,
- // the rule has been applied).
+ // the rule has been applied) for this action.
//
target_state
matched_state (action a, bool fail = true) const;
- // This function can only be called during execution if we have observed
- // (synchronization-wise) that this target has been executed.
+ // This function should only be called during execution if we have
+ // observed (synchronization-wise) that this target has been executed.
//
target_state
executed_state (bool fail = true) const;
+ // This function should only be called between match and execute while
+ // running serially. It returns the group state for the "final" action
+ // that has been matched (and that will be executed).
+ //
+ target_state
+ serial_state (bool fail = true) const;
+
// Number of direct targets that depend on this target in the current
// operation. It is incremented during match and then decremented during
// execution, before running the recipe. As a result, the recipe can
@@ -481,8 +488,8 @@ namespace build2
target_state
state () const;
- // Version that should be used during search & match after the target has
- // been matched for this action (see the recipe override).
+ // Version that should be used during match after the target has been
+ // matched for this action (see the recipe override).
//
target_state
state (action a) const;
diff --git a/build2/target.ixx b/build2/target.ixx
index 661321d..f581e5e 100644
--- a/build2/target.ixx
+++ b/build2/target.ixx
@@ -111,6 +111,19 @@ namespace build2
return r;
}
+ inline target_state target::
+ serial_state (bool fail) const
+ {
+ //assert (sched.serial ());
+
+ target_state r (group_state () ? group->state_ : state_);
+
+ if (fail && r == target_state::failed)
+ throw failed ();
+
+ return r;
+ }
+
inline void target::
recipe (recipe_type r)
{