aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/algorithm.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2022-04-06 11:26:52 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2022-04-06 13:51:56 +0200
commit76be0a35f6c37cda7ba65530330f1ac246fb52a8 (patch)
treef613ceafcf6c7208984d4536653061c4e0c23be7 /libbuild2/algorithm.cxx
parent0a9dd0c7d31cbba2170fdfda4b747a1fe5ce665a (diff)
Add support for rule hints
A rule hint is a target attribute, for example: [rule_hint=cxx] exe{hello}: c{hello} Rule hints can be used to resolve ambiguity when multiple rules match the same target as well as to override an unambiguous match.
Diffstat (limited to 'libbuild2/algorithm.cxx')
-rw-r--r--libbuild2/algorithm.cxx30
1 files changed, 13 insertions, 17 deletions
diff --git a/libbuild2/algorithm.cxx b/libbuild2/algorithm.cxx
index 217e7af..61ab92c 100644
--- a/libbuild2/algorithm.cxx
+++ b/libbuild2/algorithm.cxx
@@ -447,6 +447,8 @@ namespace build2
meta_operation_id mo (a.meta_operation ());
operation_id o (a.inner () ? a.operation () : a.outer_operation ());
+ const string& hint (t.find_hint (o)); // MT-safe (target locked).
+
for (auto tt (&t.type ()); tt != nullptr; tt = tt->base)
{
// Search scopes outwards, stopping at the project root.
@@ -478,23 +480,11 @@ namespace build2
if (i == ttm->end () || i->second.empty ())
continue; // No rules registered for this target type.
- const auto& rules (i->second); // Hint map.
+ const auto& rules (i->second); // Name map.
- // @@ TODO hint
- //
- // Different rules can be used for different operations (update vs
- // test is a good example). So, at some point, we will probably have
- // to support a list of hints or even an operation-hint map (e.g.,
- // 'hint=cxx test=foo' if cxx supports the test operation but we
- // want the foo rule instead). This is also the place where the
- // '{build clean}=cxx' construct (which we currently do not support)
- // can come handy.
- //
- // Also, ignore the hint (that is most likely ment for a different
- // operation) if this is a unique match.
+ // Filter against the hint, if any.
//
- string hint;
- auto rs (rules.size () == 1
+ auto rs (hint.empty ()
? make_pair (rules.begin (), rules.end ())
: rules.find_sub (hint));
@@ -622,8 +612,14 @@ namespace build2
if (!try_match)
{
- diag_record dr;
- dr << fail << "no rule to " << diag_do (a, t);
+ diag_record dr (fail);
+
+ if (hint.empty ())
+ dr << "no rule to ";
+ else
+ dr << "no rule with hint " << hint << " to ";
+
+ dr << diag_do (a, t);
// Try to give some hints of the common causes.
//