From 5c3982d9d2dbe775b9876f1c48e865012bacbe40 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Sun, 22 Oct 2023 12:34:44 +0200 Subject: WIP: add options to match_rule(), match_recipe() --- libbuild2/algorithm.cxx | 8 +++----- libbuild2/algorithm.hxx | 12 ++++++++++-- libbuild2/algorithm.ixx | 18 +++++++++++++----- 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; -- cgit v1.1