diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2017-03-03 10:05:16 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2017-03-03 10:05:16 +0200 |
commit | bcb5045dff9e87decbad3a785eb1fe42f4fc1410 (patch) | |
tree | d5ed2b39f3704e28f0707b61cd50114cfe775d4c | |
parent | 2069cbb8f72bceb0fcb968ba05968a24eeb0c15d (diff) |
Use final action state after match at top level (operation)
-rw-r--r-- | build2/operation.cxx | 17 | ||||
-rw-r--r-- | build2/target | 19 | ||||
-rw-r--r-- | build2/target.ixx | 13 |
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) { |