From f62ff2e840fd92a03b4a3298de938d426f8b5c7a Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 14 Aug 2015 15:47:34 +0200 Subject: Fix several issues in outer operation recipe override logic --- build/bin/rule.cxx | 10 +++++++++- build/target | 24 +----------------------- build/target.cxx | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 24 deletions(-) (limited to 'build') 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 ()) - { - 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 ()); + 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 ()) + { + 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 (); -- cgit v1.1