aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/rule.hxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2020-04-28 08:48:53 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2020-05-27 15:47:28 +0200
commitb808c255b6a9ddba085bf5646e7d20ec344f2e2d (patch)
tree32730291f7e6de8ef0a227905520dd66fb4ec0f3 /libbuild2/rule.hxx
parent3552356a87402727e663131994fa87f48b3cd4fb (diff)
Initial support for ad hoc recipes (still work in progress)
Diffstat (limited to 'libbuild2/rule.hxx')
-rw-r--r--libbuild2/rule.hxx142
1 files changed, 141 insertions, 1 deletions
diff --git a/libbuild2/rule.hxx b/libbuild2/rule.hxx
index 9eab1f6..efa4ec3 100644
--- a/libbuild2/rule.hxx
+++ b/libbuild2/rule.hxx
@@ -12,6 +12,8 @@
#include <libbuild2/target.hxx>
#include <libbuild2/recipe.hxx>
+#include <libbuild2/build/script/script.hxx>
+
#include <libbuild2/export.hxx>
namespace build2
@@ -22,7 +24,7 @@ namespace build2
//
// Note: match() is only called once but may not be followed by apply().
//
- class rule
+ class LIBBUILD2_SYMEXPORT rule
{
public:
virtual bool
@@ -33,6 +35,9 @@ namespace build2
rule () = default;
+ virtual
+ ~rule ();
+
rule (const rule&) = delete;
rule& operator= (const rule&) = delete;
};
@@ -108,6 +113,141 @@ namespace build2
noop_rule () {}
static const noop_rule instance;
};
+
+ // Ad hoc rule.
+ //
+ // Note: not exported
+ //
+ class adhoc_rule: public rule
+ {
+ public:
+ location_value loc; // Buildfile location of the recipe.
+ size_t braces; // Number of braces in multi-brace tokens.
+
+ adhoc_rule (const location& l, size_t b)
+ : loc (l),
+ braces (b),
+ rule_match ("adhoc", static_cast<const rule&> (*this)) {}
+
+ public:
+ // Some of the operations come in compensating pairs, such as update and
+ // clean, install and uninstall. An ad hoc rule implementation may choose
+ // to provide a fallback implementation of a compensating operation if it
+ // is providing the other half (passed in the fallback argument).
+ //
+ // The default implementation calls rule::match() if fallback is absent
+ // and returns false if fallback is present. So an implementation that
+ // doesn't care about this semantics can implement the straight rule
+ // interface.
+ //
+ virtual bool
+ match (action, target&, const string&, optional<action> fallback) const;
+
+ virtual bool
+ match (action, target&, const string&) const override;
+
+ virtual void
+ dump (ostream&, string& indentation) const = 0;
+
+ // Implementation details.
+ //
+ public:
+ build2::rule_match rule_match;
+
+ static const dir_path recipes_build_dir;
+
+ // Scope operation callback that cleans up ad hoc recipe builds.
+ //
+ static target_state
+ clean_recipes_build (action, const scope&, const dir&);
+ };
+
+ // Ad hoc script rule.
+ //
+ // Note: not exported and should not be used directly (i.e., registered).
+ //
+ class adhoc_script_rule: public adhoc_rule
+ {
+ public:
+ virtual bool
+ match (action, target&, const string&, optional<action>) const override;
+
+ virtual recipe
+ apply (action, target&) const override;
+
+ target_state
+ perform_update_file (action, const target&) const;
+
+ target_state
+ default_action (action, const target&) const;
+
+ virtual void
+ dump (ostream&, string&) const override;
+
+ using script_type = build::script::script;
+
+ adhoc_script_rule (optional<string> d, const location& l, size_t b)
+ : adhoc_rule (l, b), diag (move (d)) {}
+
+ public:
+ const optional<string> diag; // Command name for low-verbosity diag.
+ string checksum; // Script text hashsum.
+ script_type script;
+
+ };
+
+ // Ad hoc C++ rule.
+ //
+ // Note: exported but should not be used directly (i.e., registered).
+ //
+ class LIBBUILD2_SYMEXPORT cxx_rule: public rule
+ {
+ public:
+
+ // A robust recipe may want to incorporate the recipe_state into its
+ // up-to-date decision as if the recipe library was a prerequisite (it
+ // cannot be injected as a real prerequisite since it's from a different
+ // build context).
+ //
+ const location recipe_loc; // Buildfile location of the recipe.
+ const target_state recipe_state; // State of recipe library target.
+
+ cxx_rule (const location& l, target_state s)
+ : recipe_loc (l), recipe_state (s) {}
+
+ // Return true by default.
+ //
+ virtual bool
+ match (action, target&, const string&) const override;
+ };
+
+ // Note: not exported.
+ //
+ class adhoc_cxx_rule: public adhoc_rule
+ {
+ public:
+ virtual bool
+ match (action, target&, const string&) const override;
+
+ virtual recipe
+ apply (action, target&) const override;
+
+ virtual void
+ dump (ostream&, string&) const override;
+
+ adhoc_cxx_rule (string c, const location& l, size_t b)
+ : adhoc_rule (l, b), code (move (c)), impl (nullptr) {}
+
+ virtual
+ ~adhoc_cxx_rule () override;
+
+ public:
+ // Note that this recipe (rule instance) can be shared between multiple
+ // targets which could all be matched in parallel.
+ //
+ const string code;
+ mutable atomic<cxx_rule*> impl;
+ };
}
#endif // LIBBUILD2_RULE_HXX