From 9034f7c51ef6437ce9d4547ba5bde217b4740fb2 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 19 Apr 2022 11:10:53 +0200 Subject: Use target recipe for auxiliary data storage during match-apply In particular, we now have separate auxiliary data storage for inner and outer operations. --- libbuild2/bash/rule.cxx | 60 ++++++++++++++++++++++++++++--------------------- libbuild2/bash/rule.hxx | 3 --- 2 files changed, 34 insertions(+), 29 deletions(-) (limited to 'libbuild2/bash') diff --git a/libbuild2/bash/rule.cxx b/libbuild2/bash/rule.cxx index fec85be..55f3cf0 100644 --- a/libbuild2/bash/rule.cxx +++ b/libbuild2/bash/rule.cxx @@ -26,6 +26,9 @@ namespace build2 struct match_data { + explicit + match_data (const in_rule& r): rule (r) {} + // The "for install" condition is signalled to us by install_rule when // it is matched for the update operation. It also verifies that if we // have already been executed, then it was for install. @@ -33,6 +36,25 @@ namespace build2 // See cc::link_rule for a discussion of some subtleties in this logic. // optional for_install; + + const in_rule& rule; + + target_state + operator() (action a, const target& t) + { + // Unless the outer install rule signalled that this is update for + // install, signal back that we've performed plain update. + // + if (!for_install) + for_install = false; + + //@@ TODO: need to verify all the modules we depend on are compatible + // with our for_install value, similar to cc::link_rule's + // append_libraries() (and which is the other half of the check + // in install_rule). + + return rule.perform_update (a, t); + } }; static_assert (sizeof (match_data) <= target::small_data_size, @@ -66,37 +88,23 @@ namespace build2 if (!fm) l4 ([&]{trace << "no bash module prerequisite for target " << t;}); - return (fi && fm); + return fi && fm; } recipe in_rule:: apply (action a, target& t) const { - // Note that for-install is signalled by install_rule and therefore - // can only be relied upon during execute. - // - t.data (match_data ()); + recipe r (rule::apply (a, t)); - return rule::apply (a, t); - } - - target_state in_rule:: - perform_update (action a, const target& t) const - { - // Unless the outer install rule signalled that this is update for - // install, signal back that we've performed plain update. - // - match_data& md (t.data ()); - - if (!md.for_install) - md.for_install = false; - - //@@ TODO: need to verify all the modules we depend on are compatible - // with our for_install value, similar to cc::link_rule's - // append_libraries() (and which is the other half of the check - // in install_rule). + if (a == perform_update_id) + { + // Note that for-install is signalled by install_rule and therefore + // can only be relied upon during execute. + // + return match_data (*this); + } - return rule::perform_update (a, t); + return r; } prerequisite_target in_rule:: @@ -338,7 +346,7 @@ namespace build2 if (ap == nullptr) fail (l) << "unable to resolve import path " << ip; - match_data& md (t.data ()); + match_data& md (t.data (a)); assert (md.for_install); if (*md.for_install) @@ -449,7 +457,7 @@ namespace build2 // Signal to the in rule that this is update for install. And if the // update has already been executed, verify it was done for install. // - auto& md (t.data ()); + auto& md (t.data (a.inner_action ())); if (md.for_install) { diff --git a/libbuild2/bash/rule.hxx b/libbuild2/bash/rule.hxx index 1a0cb36..3da0c73 100644 --- a/libbuild2/bash/rule.hxx +++ b/libbuild2/bash/rule.hxx @@ -37,9 +37,6 @@ namespace build2 virtual recipe apply (action, target&) const override; - virtual target_state - perform_update (action, const target&) const override; - virtual prerequisite_target search (action, const target&, -- cgit v1.1