From 8e42d1ec329ac16ec5ae9692f18cdb0f2444d2fb Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 8 Jun 2020 08:12:54 +0200 Subject: Fix handling of inner/outer operations in ad hoc recipes machinery --- libbuild2/action.hxx | 2 ++ libbuild2/algorithm.cxx | 23 ++++++++++++----------- libbuild2/rule.cxx | 18 +++++++++++++++--- 3 files changed, 29 insertions(+), 14 deletions(-) diff --git a/libbuild2/action.hxx b/libbuild2/action.hxx index 906d7eb..e149574 100644 --- a/libbuild2/action.hxx +++ b/libbuild2/action.hxx @@ -115,6 +115,8 @@ namespace build2 bool operator>= (action, action) = delete; bool operator<= (action, action) = delete; + // Note: prints in numeric form (mostly used in tracing). + // LIBBUILD2_SYMEXPORT ostream& operator<< (ostream&, action); // operation.cxx diff --git a/libbuild2/algorithm.cxx b/libbuild2/algorithm.cxx index 6ea1e1f..077bdf2 100644 --- a/libbuild2/algorithm.cxx +++ b/libbuild2/algorithm.cxx @@ -326,33 +326,34 @@ namespace build2 dr << info << "while matching ad hoc recipe to " << diag_do (a, t); }); - // @@ TODO: + // The action could be Y-for-X while the ad hoc recipes are always for + // X. So strip the Y-for part for comparison (but not for the match() + // calls; see below for the hairy inner/outer semantics details). // - // If action is Y-for-X, how would we distinguish between X and Y-for-X? - // See match_rule() for the hairy details. We could start with - // supporting just the inner case. Or we could try to just match an - // inner rule by default? I think need a clear use-case to see what's - // the correct semantics. + action ca (a.outer () + ? action (a.meta_operation (), a.outer_operation ()) + : a); auto b (t.adhoc_recipes.begin ()), e (t.adhoc_recipes.end ()); auto i (find_if ( b, e, - [a, &t] (const adhoc_recipe& r) + [a, ca, &t] (const adhoc_recipe& r) { auto& as (r.actions); - return (find (as.begin (), as.end (), a) != as.end () && + return (find (as.begin (), as.end (), ca) != as.end () && r.rule->match (a, t, string () /* hint */, nullopt)); })); if (i == e) i = find_if ( b, e, - [a, &t] (const adhoc_recipe& r) + [a, ca, &t] (const adhoc_recipe& r) { - // See the adhoc_rule::match() documentation for details. + // See the adhoc_rule::match() documentation for details on what's + // going on here. // auto& as (r.actions); - if (find (as.begin (), as.end (), a) == as.end ()) + if (find (as.begin (), as.end (), ca) == as.end ()) { for (auto ra: as) if (r.rule->match (a, t, string () /* hint */, ra)) diff --git a/libbuild2/rule.cxx b/libbuild2/rule.cxx index fb769fd..f257b62 100644 --- a/libbuild2/rule.cxx +++ b/libbuild2/rule.cxx @@ -472,12 +472,24 @@ namespace build2 recipe adhoc_script_rule:: apply (action a, target& t) const { + // If this is an outer operation (e.g., update-for-test), then delegate to + // the inner. + // + if (a.outer ()) + { + match_inner (a, t); + return execute_inner; + } + // Derive file names for the target and its ad hoc group members, if any. // - for (target* m (&t); m != nullptr; m = m->adhoc_member) + if (a == perform_update_id || a == perform_clean_id) { - if (auto* p = m->is_a ()) - p->derive_path (); + for (target* m (&t); m != nullptr; m = m->adhoc_member) + { + if (auto* p = m->is_a ()) + p->derive_path (); + } } // Inject dependency on the output directory. -- cgit v1.1