aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/rule.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'libbuild2/rule.hxx')
-rw-r--r--libbuild2/rule.hxx112
1 files changed, 94 insertions, 18 deletions
diff --git a/libbuild2/rule.hxx b/libbuild2/rule.hxx
index 3eb7775..4f77432 100644
--- a/libbuild2/rule.hxx
+++ b/libbuild2/rule.hxx
@@ -22,7 +22,12 @@ namespace build2
// you need to modify some state (e.g., counters or some such), then make
// sure things are MT-safe.
//
- // Note: match() is only called once but may not be followed by apply().
+ // Note: match() could be called multiple times (so should be idempotent)
+ // and it may not be followed by apply().
+ //
+ // The hint argument is the rule hint, if any, that was used to select this
+ // rule. While normally not factored into the match decision, a rule may
+ // "try harder" if a hint was specified (see cc::link_rule for an example).
//
// The match_extra argument (the type is defined in target.hxx) is used to
// pass additional information that is only needed by some rule
@@ -47,15 +52,45 @@ namespace build2
rule (const rule&) = delete;
rule& operator= (const rule&) = delete;
+
+ // Resolve a project-qualified target in a rule-specific manner.
+ //
+ // This is optional functionality that may be provided by some rules to
+ // facilitate immediate importation of certain target types. See the
+ // import machinery for details. The default implementation always returns
+ // NULL.
+ //
+ // Note that if this function returns a target, it should have the
+ // extension assigned so that as_name() returns a stable name.
+ //
+ virtual const target*
+ import (const prerequisite_key&,
+ const optional<string>& metadata,
+ const location&) const;
+
+ // Sometimes we want to match only if another rule of ours would match
+ // another operation. For example, we would want our install rule to match
+ // only if our update rule also matches.
+ //
+ // Arranging this, however, is not a simple matter of calling the other
+ // rule's match(): we also have to take into account ad hoc recipes and
+ // rule hints for that operation. This helper performs all the necessary
+ // checks. Note: should only be called from match() (see
+ // target::find_hint() for details). Note also that ad hoc recipes are
+ // checked for hint_op, not action's operation.
+ //
+ bool
+ sub_match (const string& rule_name, operation_id hint_op,
+ action, target&, match_extra&) const;
};
- // Simplified interface for rules that don't care about the extras.
+ // Simplified interface for rules that don't care about the hint or extras.
//
class LIBBUILD2_SYMEXPORT simple_rule: public rule
{
public:
virtual bool
- match (action, target&, const string& hint) const = 0;
+ match (action, target&) const = 0;
virtual recipe
apply (action, target&) const = 0;
@@ -65,19 +100,31 @@ namespace build2
virtual recipe
apply (action, target&, match_extra&) const override;
+
+ // The simplified version of sub_match() above.
+ //
+ // Note that it calls the simplified match() directly rather than going
+ // through the original.
+ //
+ bool
+ sub_match (const string& rule_name, operation_id hint_op,
+ action, target&) const;
};
// Fallback rule that only matches if the file exists. It will also match
// an mtime_target provided it has a set timestamp.
//
- class LIBBUILD2_SYMEXPORT file_rule: public simple_rule
+ // Note: this rule is "hot" because it matches every static source file and
+ // so we don't use simple_rule to avoid two extra virtual calls.
+ //
+ class LIBBUILD2_SYMEXPORT file_rule: public rule
{
public:
virtual bool
- match (action, target&, const string&) const override;
+ match (action, target&, const string&, match_extra&) const override;
virtual recipe
- apply (action, target&) const override;
+ apply (action, target&, match_extra&) const override;
file_rule () {}
@@ -89,7 +136,7 @@ namespace build2
{
public:
virtual bool
- match (action, target&, const string&) const override;
+ match (action, target&) const override;
virtual recipe
apply (action, target&) const override;
@@ -105,7 +152,7 @@ namespace build2
{
public:
virtual bool
- match (action, target&, const string&) const override;
+ match (action, target&) const override;
virtual recipe
apply (action, target&) const override;
@@ -132,7 +179,7 @@ namespace build2
{
public:
virtual bool
- match (action, target&, const string&) const override;
+ match (action, target&) const override;
virtual recipe
apply (action, target&) const override;
@@ -145,9 +192,14 @@ namespace build2
//
// Used for both ad hoc pattern rules and ad hoc recipes. For recipes, it's
// essentially a rule of one case. Note that when used as part of a pattern,
- // the implementation cannot use the match_extra::buffer nor the target
- // auxiliary data storage until the pattern's apply_*() calls have been
- // made.
+ // the implementation cannot use the match_extra::data() facility nor the
+ // target auxiliary data storage until the pattern's apply_*() calls have
+ // been made.
+ //
+ // Note also that when used as part of a pattern, the rule is also register
+ // for the dist meta-operation (unless there is an explicit recipe for dist)
+ // in order to inject additional pattern prerequisites which may "pull"
+ // additional sources into the distribution.
//
// Note: not exported.
//
@@ -200,6 +252,16 @@ namespace build2
// The default implementation forwards to the pattern's match() if there
// is a pattern and returns true otherwise.
//
+ // Note also that in case of a member of a group-based target, match() is
+ // called on the group while apply() on the member (see match_rule() in
+ // algorithms.cxx for details). This means that match() may be called
+ // without having the target locked and as a result match() should (unless
+ // known to only match a non-group) treat the target as const and only
+ // rely on immutable information (type, name, etc) since the group could
+ // be matched concurrenly. This case can be detected by examining
+ // match_extra::locked (see adhoc_rule_regex_pattern::match() for a
+ // use-case).
+ //
virtual bool
match (action, target&, const string&, match_extra&) const override;
@@ -214,8 +276,8 @@ namespace build2
// Implementation details.
//
public:
- // The name in rule_match is used as a hint and as a name in diagnostics.
- // The former does not apply to ad hoc recipes (but does apply to ad hoc
+ // The name in rule_match is used to match hints and in diagnostics. The
+ // former does not apply to ad hoc recipes (but does apply to ad hoc
// rules).
//
const build2::rule_match rule_match;
@@ -266,14 +328,28 @@ namespace build2
~adhoc_rule_pattern ();
public:
+ // Note: the adhoc_rule::match() restrictions apply here as well.
+ //
virtual bool
- match (action, target&, const string&, match_extra&) const = 0;
+ match (action, const target&, const string&, match_extra&) const = 0;
+ // Append additional group members. Note that this function should handle
+ // both ad hoc and explicit groups.
+ //
virtual void
- apply_adhoc_members (action, target&, match_extra&) const = 0;
-
+ apply_group_members (action, target&,
+ const scope& base,
+ match_extra&) const = 0;
+
+ // The implementation should append pattern prerequisites to
+ // t.prerequisite_targets[a] but not match. It should set bit 2 in
+ // prerequisite_target::include to indicate update=match and bit 3
+ // to indicate update=unmatch.
+ //
virtual void
- apply_prerequisites (action, target&, match_extra&) const = 0;
+ apply_prerequisites (action, target&,
+ const scope& base,
+ match_extra&) const = 0;
// Dump support.
//