aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/rule.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'libbuild2/rule.cxx')
-rw-r--r--libbuild2/rule.cxx91
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);
}