aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/rule.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'libbuild2/rule.hxx')
-rw-r--r--libbuild2/rule.hxx80
1 files changed, 69 insertions, 11 deletions
diff --git a/libbuild2/rule.hxx b/libbuild2/rule.hxx
index 77c2d2c..eceb6ad 100644
--- a/libbuild2/rule.hxx
+++ b/libbuild2/rule.hxx
@@ -22,7 +22,8 @@ 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
@@ -33,6 +34,13 @@ namespace build2
// implementations. It is also a way for us to later pass more information
// without breaking source compatibility.
//
+ // A rule may adjust post hoc prerequisites by overriding apply_posthoc().
+ // See match_extra::posthoc_prerequisite_targets for background and details.
+ //
+ // A rule may support match options and if such a rule is rematched with
+ // different options, then reapply() is called. See
+ // match_extra::{cur,new}_options for background and details.
+ //
struct match_extra;
class LIBBUILD2_SYMEXPORT rule
@@ -44,6 +52,12 @@ namespace build2
virtual recipe
apply (action, target&, match_extra&) const = 0;
+ virtual void
+ apply_posthoc (action, target&, match_extra&) const;
+
+ virtual void
+ reapply (action, target&, match_extra&) const;
+
rule () = default;
virtual
@@ -52,15 +66,31 @@ 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 the rule hints for
- // that operation. This helper performs all the necessary steps. Note:
- // should only be called from match() (see target::find_hint() for
- // details).
+ // 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,
@@ -109,10 +139,19 @@ namespace build2
virtual recipe
apply (action, target&, match_extra&) const override;
- file_rule () {}
+ // While this rule expects an mtime_target-based target, sometimes it's
+ // necessary to register it for something less specific (normally target)
+ // in order to achieve the desired rule matching priority (see the dist
+ // and config modules for an example). For such cases this rule can be
+ // instructed to check the type and only match if it's mtime_target-based.
+ //
+ file_rule (bool match_type = false): match_type_ (match_type) {}
- static const file_rule instance;
+ static const file_rule instance; // Note: does not match the target type.
static const build2::rule_match rule_match;
+
+ private:
+ bool match_type_;
};
class LIBBUILD2_SYMEXPORT alias_rule: public simple_rule
@@ -150,7 +189,10 @@ namespace build2
// of fsdir{} without the overhead of switching to the execute phase.
//
static void
- perform_update_direct (action, const target&);
+ perform_update_direct (action, const fsdir&);
+
+ static void
+ perform_clean_direct (action, const fsdir&);
fsdir_rule () {}
static const fsdir_rule instance;
@@ -235,6 +277,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_impl()
+ // 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;
@@ -301,18 +353,24 @@ 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&,
+ 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.
+ // to indicate update=unmatch. It should also avoid adding duplicate
+ // fsdir{} similar to the search_prerequisite*() functions.
//
virtual void
apply_prerequisites (action, target&,