From f7e9830c0c413f05737002dcc8d06e73cb379980 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 1 Jul 2015 10:45:14 +0200 Subject: Group state support --- build/algorithm.ixx | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) (limited to 'build/algorithm.ixx') diff --git a/build/algorithm.ixx b/build/algorithm.ixx index ddd63f6..d4d0ec8 100644 --- a/build/algorithm.ixx +++ b/build/algorithm.ixx @@ -95,16 +95,39 @@ namespace build { t.dependents--; - switch (t.state) + switch (target_state ts = t.state ()) { case target_state::unchanged: - case target_state::changed: return t.state; + case target_state::changed: return ts; default: { // Handle the "last" execution mode. // + // This gets interesting when we consider interaction with + // groups. It seem to make sense to treat group members as + // dependents of the group, so, for example, if we try to + // clean the group via three of its members, only the last + // attempt will actually execute the clean. This means that + // when we match a group member, inside we should also match + // the group in order to increment the dependents count. + // Though this seems to be a natural requirement (if we + // are delegating to the group, we need to find a recipe + // for it, just like we would for a prerequisite). + // + // Note that below we are going to change the group state + // to postponed. This is not a mistake: until we execute + // the recipe, we want to keep returning postponed. And + // once the recipe is executed, it will reset the state + // to group (see group_action()). To put it another way, + // the execution of this member is postponed, not of the + // group. + // + // One important invariant to keep in mind: the return + // value from execute() should always be the same as what + // would get returned by a subsequent call to state(). + // if (current_mode == execution_mode::last && t.dependents != 0) - return (t.state = target_state::postponed); + return (t.raw_state = target_state::postponed); return execute_impl (a, t); } @@ -114,10 +137,10 @@ namespace build inline target_state execute_direct (action a, target& t) { - switch (t.state) + switch (target_state ts = t.state ()) { case target_state::unchanged: - case target_state::changed: return t.state; + case target_state::changed: return ts; default: return execute_impl (a, t); } } -- cgit v1.1