diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2023-05-29 07:56:33 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2023-05-29 14:12:00 +0200 |
commit | 9bea2f465cc2b47e06d65d6a29cb0f0f0c37f29c (patch) | |
tree | 5eb14ac196fce453c33c06c497e25b8d8f9259a1 /libbuild2/algorithm.cxx | |
parent | 59014204d94e67d243cce45ff83ca85212237433 (diff) |
Extend special match_rule() logic to all groups with dynamic targets
Diffstat (limited to 'libbuild2/algorithm.cxx')
-rw-r--r-- | libbuild2/algorithm.cxx | 51 |
1 files changed, 27 insertions, 24 deletions
diff --git a/libbuild2/algorithm.cxx b/libbuild2/algorithm.cxx index cf972e7..581da2e 100644 --- a/libbuild2/algorithm.cxx +++ b/libbuild2/algorithm.cxx @@ -521,42 +521,45 @@ namespace build2 return dynamic_cast<const fallback_rule*> (&r.second.get ()); }; - // If this is a member of group-based target, then first try to find a - // matching ad hoc recipe/rule by matching (to an ad hoc recipe/rule) the - // group but applying to the member. See adhoc_rule::match() for - // background, including for why const_cast should be safe. - // - // To put it another way, if a group is matched by an ad hoc recipe/rule, - // then we want all the member to be matched to the same recipe/rule. - // - if (const group* g = t.group != nullptr ? t.group->is_a<group> () : nullptr) + if (const target* g = t.group) { - assert (pme == nullptr); - - // As an optimization, check if the group is already matched for this - // action. Note that this can become important when matching adhoc regex - // rules since we can potentially call match() for many members. This is - // probably ok for static members (of which we don't expect more than a - // handful) but can become an issue for dynamic members. + // If this is a group with dynamic members, then match it with the + // group's rule automatically. See dyndep_rule::inject_group_member() + // for background. // - if (g->matched (a, memory_order_acquire)) + if ((g->type ().flags & target_type::flag::dyn_members) == + target_type::flag::dyn_members) { - const rule_match* r (g->state[a].rule); - - if (r != nullptr && adhoc_rule_match (*r)) + if (g->matched (a, memory_order_acquire)) + { + const rule_match* r (g->state[a].rule); + assert (r != nullptr); // Shouldn't happen with dyn_members. return r; + } - // Fall through: if some rule matched the group then it must also deal - // with the members. + // Assume static member and fall through. } - else + + // If this is a member of group-based target, then first try to find a + // matching ad hoc recipe/rule by matching (to an ad hoc recipe/rule) the + // group but applying to the member. See adhoc_rule::match() for + // background, including for why const_cast should be safe. + // + // To put it another way, if a group is matched by an ad hoc + // recipe/rule, then we want all the member to be matched to the same + // recipe/rule. + // + // Note that such a group is dyn_members so we would have tried the + // "already matched" case above. + // + if (g->is_a<group> ()) { // We cannot init match_extra from the target if it's unlocked so use // a temporary (it shouldn't be modified if unlocked). // match_extra me (false /* locked */); if (const rule_match* r = match_rule ( - a, const_cast<group&> (*g), skip, true /* try_match */, &me)) + a, const_cast<target&> (*g), skip, true /* try_match */, &me)) return r; // Fall through to normal match of the member. |