diff options
Diffstat (limited to 'libbuild2/rule.cxx')
-rw-r--r-- | libbuild2/rule.cxx | 91 |
1 files changed, 78 insertions, 13 deletions
diff --git a/libbuild2/rule.cxx b/libbuild2/rule.cxx index 6dad685..097e15a 100644 --- a/libbuild2/rule.cxx +++ b/libbuild2/rule.cxx @@ -22,12 +22,43 @@ namespace build2 { } + const target* rule:: + import (const prerequisite_key&, + const optional<string>&, + const location&) const + { + return nullptr; + } + + const rule_match* + match_adhoc_recipe (action, target&, match_extra&); // algorithm.cxx + + bool rule:: + sub_match (const string& n, operation_id o, + action a, target& t, match_extra& me) const + { + // First check for an ad hoc recipe (see match_rule() for details). + // + if (!t.adhoc_recipes.empty ()) + { + // Use scratch match_extra since if there is no recipe, then we don't + // want to keep any changes and if there is, then we want it discarded. + // + match_extra s (true /* locked */); // Not called from adhoc_rule::match(). + if (match_adhoc_recipe (action (a.meta_operation (), o), t, s) != nullptr) + return false; + } + + const string& h (t.find_hint (o)); + return name_rule_map::sub (h, n) && match (a, t, h, me); + } + // simple_rule // bool simple_rule:: - match (action a, target& t, const string& h, match_extra&) const + match (action a, target& t, const string&, match_extra&) const { - return match (a, t, h); + return match (a, t); } recipe simple_rule:: @@ -36,6 +67,20 @@ namespace build2 return apply (a, t); } + bool simple_rule:: + sub_match (const string& n, operation_id o, + action a, target& t) const + { + if (!t.adhoc_recipes.empty ()) + { + match_extra s (true /* locked */); // Not called from adhoc_rule::match(). + if (match_adhoc_recipe (action (a.meta_operation (), o), t, s) != nullptr) + return false; + } + + return name_rule_map::sub (t.find_hint (o), n) && match (a, t); + } + // file_rule // // Note that this rule is special. It is the last, fallback rule. If @@ -46,7 +91,7 @@ namespace build2 // use it as a guide to implement your own, normal, rules. // bool file_rule:: - match (action a, target& t, const string&) const + match (action a, target& t, const string&, match_extra&) const { tracer trace ("file_rule::match"); @@ -56,10 +101,13 @@ namespace build2 // are not doing anything for this action so not checking if the file // exists seems harmless. // + // But we also don't want to match real targets and not cleaning their + // output files. + // switch (a) { case perform_clean_id: - return true; + return t.decl != target_decl::real; default: { // While normally we shouldn't do any of this in match(), no other @@ -121,7 +169,7 @@ namespace build2 } recipe file_rule:: - apply (action a, target& t) const + apply (action a, target& t, match_extra&) const { // Update triggers the update of this target's prerequisites so it would // seem natural that we should also trigger their cleanup. However, this @@ -153,12 +201,12 @@ namespace build2 } const file_rule file_rule::instance; - const rule_match file_rule::rule_match ("file", file_rule::instance); + const rule_match file_rule::rule_match ("build.file", file_rule::instance); // alias_rule // bool alias_rule:: - match (action, target&, const string&) const + match (action, target&) const { return true; } @@ -169,9 +217,25 @@ namespace build2 // Inject dependency on our directory (note: not parent) so that it is // automatically created on update and removed on clean. // - inject_fsdir (a, t, false); + inject_fsdir (a, t, true, false); - match_prerequisites (a, t); + // Handle the alias match-only level. + // + match_search ms; + if (t.ctx.match_only && *t.ctx.match_only == match_only_level::alias) + { + ms = [] (action, + const target& t, + const prerequisite& p, + include_type i) + { + return prerequisite_target ( + p.is_a<alias> () ? &search (t, p) : nullptr, + i); + }; + } + + match_prerequisites (a, t, ms); return default_recipe; } @@ -180,7 +244,7 @@ namespace build2 // fsdir_rule // bool fsdir_rule:: - match (action, target&, const string&) const + match (action, target&) const { return true; } @@ -214,7 +278,7 @@ namespace build2 if (verb >= 2) text << "mkdir " << d; else if (verb && t.ctx.current_diag_noise) - text << "mkdir " << t; + print_diag ("mkdir", t); }; // Note: ignoring the dry_run flag. @@ -315,7 +379,7 @@ namespace build2 // noop_rule // bool noop_rule:: - match (action, target&, const string&) const + match (action, target&) const { return true; } @@ -339,8 +403,9 @@ namespace build2 } bool adhoc_rule:: - match (action a, target& t, const string& h, match_extra& me) const + match (action a, target& xt, const string& h, match_extra& me) const { + const target& t (xt); return pattern == nullptr || pattern->match (a, t, h, me); } |