From 747ff339c4be7d271a33996638b3b026a166d805 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Sat, 17 Dec 2016 11:48:40 +0200 Subject: Don't try to test out-of-project prerequisites --- build2/test/init.cxx | 3 ++- build2/test/rule | 10 +++++++ build2/test/rule.cxx | 74 +++++++++++++++++++++++++++++----------------------- 3 files changed, 54 insertions(+), 33 deletions(-) (limited to 'build2/test') diff --git a/build2/test/init.cxx b/build2/test/init.cxx index 098718b..21a6612 100644 --- a/build2/test/init.cxx +++ b/build2/test/init.cxx @@ -21,6 +21,7 @@ namespace build2 namespace test { static rule rule_; + static alias_rule alias_rule_; void boot (scope& rs, const location&, unique_ptr&) @@ -105,7 +106,7 @@ namespace build2 // Register our test running rule. // r.insert (perform_test_id, "test", rule_); - r.insert (perform_test_id, "test", rule_); // Override generic. + r.insert (perform_test_id, "test", alias_rule_); // Register our rule for the dist meta-operation. We need to do this // because we may have ad hoc prerequisites (test input/output files) diff --git a/build2/test/rule b/build2/test/rule index b915ea7..d1790e0 100644 --- a/build2/test/rule +++ b/build2/test/rule @@ -30,6 +30,16 @@ namespace build2 static target_state perform_test (action, target&); }; + + class alias_rule: public rule + { + public: + virtual recipe + apply (action, target&) const override; + + static target_state + perform_test (action, target&); + }; } } diff --git a/build2/test/rule.cxx b/build2/test/rule.cxx index a8adb9e..d313925 100644 --- a/build2/test/rule.cxx +++ b/build2/test/rule.cxx @@ -147,47 +147,44 @@ namespace build2 return mr; } - recipe rule:: + recipe alias_rule:: apply (action a, target& t) const { - tracer trace ("test::rule::apply"); - match_data md (move (t.data ())); t.clear_data (); // In case delegated-to rule also uses aux storage. - // The alias case is special so handle it first. + // We can only test an alias via a testscript, not a simple test. // - if (t.is_a ()) - { - // We can only test an alias via a testscript, not a simple test. - // - assert (!md.test || md.script); + assert (!md.test || md.script); - // Find the actual alias rule. - // - recipe d (match_delegate (a, t, *this).first); + // If this is the update pre-operation then simply redirect to the + // standard alias rule. + // + if (a.operation () == update_id) + return match_delegate (a, t, *this).first; + + // For the test operation we have to implement our own search and match + // because we need to ignore prerequisites that are outside of our + // project. They can be from projects that don't use the test module + // (and thus won't have a suitable rule). Or they can be from no project + // at all (e.g., installed). Also, generally, not testing stuff that's + // not ours seems right. Note that we still want to make sure they are + // up to date (via the above delegate) since our tests might use them. + // + search_and_match_prerequisites (a, t, t.root_scope ()); - // If not a test or this is the update pre-operation then simply - // redirect to the alias rule. - // - if (!md.test || a.operation () == update_id) - return d; + // If not a test then also redirect to the alias rule. + // + return md.test ? perform_test : default_recipe; + } - // Otherwise, we have to combine the two recipes. Note that we will - // reuse the prerequisite_targets prepared by the alias rule. - // - // Note: this most likely won't fit the small object optimization. We - // could check if the target is a function pointer (which it will most - // likely be) and return an optimized lambda in this case. - // - return [dr = move (d)] (action a, target& t) -> target_state - { - // Run the alias recipe first then the test. - // - target_state r (execute_delegate (dr, a, t)); - return r |= perform_script (a, t); - }; - } + recipe rule:: + apply (action a, target& t) const + { + tracer trace ("test::rule::apply"); + + match_data md (move (t.data ())); + t.clear_data (); // In case delegated-to rule also uses aux storage. if (!md.test) return noop_recipe; @@ -593,5 +590,18 @@ namespace build2 return target_state::changed; } + + target_state alias_rule:: + perform_test (action a, target& t) + { + // Run the alias recipe first then the test. + // + target_state r (execute_prerequisites (a, t)); + + // Note that we reuse the prerequisite_targets prepared by the standard + // search and match. + // + return r |= perform_script (a, t); + } } } -- cgit v1.1