diff options
Diffstat (limited to 'build/algorithm.cxx')
-rw-r--r-- | build/algorithm.cxx | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/build/algorithm.cxx b/build/algorithm.cxx index 40d4b0b..bec51aa 100644 --- a/build/algorithm.cxx +++ b/build/algorithm.cxx @@ -278,25 +278,26 @@ namespace build { // Implementation with some multi-threading ideas in mind. // - switch (target_state ts = t.state) + switch (t.raw_state) { + case target_state::group: case target_state::unknown: case target_state::postponed: { - t.state = target_state::failed; // So the rule can just throw. + t.raw_state = target_state::failed; // So the rule can just throw. auto g ( make_exception_guard ( [](action a, target& t){info << "while " << diag_doing (a, t);}, a, t)); - ts = t.recipe (a) (a, t); + target_state ts (t.recipe (a) (a, t)); assert (ts != target_state::unknown && ts != target_state::failed); // The recipe may have set the target's state manually. // - if (t.state == target_state::failed) - t.state = ts; + if (t.raw_state == target_state::failed) + t.raw_state = ts; return ts; } @@ -395,6 +396,23 @@ namespace build } target_state + group_action (action a, target& t) + { + target_state r (execute (a, *t.group)); + + // The standard execute() logic sets the state to failed just + // before calling the recipe (so that the recipe can just throw + // to indicate a failure). After the recipe is successfully + // executed and unless the recipe has updated the state manually, + // the recipe's return value is set as the new state. But we + // don't want that. So we are going to set it manually. + // + t.raw_state = target_state::group; + + return r; + } + + target_state default_action (action a, target& t) { return current_mode == execution_mode::first |