aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libbuild2/algorithm.cxx8
-rw-r--r--libbuild2/algorithm.hxx12
-rw-r--r--libbuild2/algorithm.ixx18
3 files changed, 26 insertions, 12 deletions
diff --git a/libbuild2/algorithm.cxx b/libbuild2/algorithm.cxx
index 88aec85..a414356 100644
--- a/libbuild2/algorithm.cxx
+++ b/libbuild2/algorithm.cxx
@@ -1151,13 +1151,11 @@ namespace build2
{
if (r.second != target_state::failed)
{
- // Note: in particular, this makes sure we will never re-lock this
- // member if already applied/executed.
+ // Note: in particular, passing all_options makes sure we will
+ // never re-lock this member if already applied/executed.
//
- s.match_extra.cur_options = match_extra::all_options;
-
match_inc_dependents (a, g);
- match_recipe (l, group_recipe);
+ match_recipe (l, group_recipe, match_extra::all_options);
// Note: no need to call match_posthoc() since an ad hoc member
// has no own prerequisites and the group's ones will be matched
diff --git a/libbuild2/algorithm.hxx b/libbuild2/algorithm.hxx
index 32ab7be..889eefc 100644
--- a/libbuild2/algorithm.hxx
+++ b/libbuild2/algorithm.hxx
@@ -418,14 +418,22 @@ namespace build2
// Apply the specified recipe directly and without incrementing the
// dependency counts. The target must be locked.
//
+ // Note that there will be no way to rematch on options change (since there
+ // is no rule), so passing anything other than all_options is most likely a
+ // bad idea.
+ //
void
- match_recipe (target_lock&, recipe);
+ match_recipe (target_lock&,
+ recipe,
+ uint64_t options = match_extra::all_options);
// Match (but do not apply) the specified rule directly and without
// incrementing the dependency counts. The target must be locked.
//
void
- match_rule (target_lock&, const rule_match&);
+ match_rule (target_lock&,
+ const rule_match&,
+ uint64_t options = match_extra::all_options);
// Match a "delegate rule" from withing another rules' apply() function
// avoiding recursive matches (thus the third argument). Unless try_match is
diff --git a/libbuild2/algorithm.ixx b/libbuild2/algorithm.ixx
index 615cef0..5b7238c 100644
--- a/libbuild2/algorithm.ixx
+++ b/libbuild2/algorithm.ixx
@@ -539,7 +539,7 @@ namespace build2
return match_direct_sync (a, t, fail);
}
- // Clear rule match-specific target data.
+ // Clear rule match-specific target data (except match_extra).
//
inline void
clear_target (action a, target& t)
@@ -608,12 +608,16 @@ namespace build2
}
inline void
- match_recipe (target_lock& l, recipe r)
+ match_recipe (target_lock& l, recipe r, uint64_t o)
{
assert (l.target != nullptr &&
- l.offset != target::offset_matched &&
+ l.offset < target::offset_matched &&
l.target->ctx.phase == run_phase::match);
+ match_extra& me ((*l.target)[l.action].match_extra);
+
+ me.reinit (false /* fallback */);
+ me.cur_options = o; // Already applied, so cur_, not new_options.
clear_target (l.action, *l.target);
set_rule (l, nullptr); // No rule.
set_recipe (l, move (r));
@@ -621,12 +625,16 @@ namespace build2
}
inline void
- match_rule (target_lock& l, const rule_match& r)
+ match_rule (target_lock& l, const rule_match& r, uint64_t o)
{
assert (l.target != nullptr &&
- l.offset != target::offset_matched &&
+ l.offset < target::offset_matched &&
l.target->ctx.phase == run_phase::match);
+ match_extra& me ((*l.target)[l.action].match_extra);
+
+ me.reinit (false /* fallback */);
+ me.new_options = o;
clear_target (l.action, *l.target);
set_rule (l, &r);
l.offset = target::offset_matched;