From f8de93520fd604a3771a2af3ca9564f6085d8baa Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 1 Dec 2022 10:00:37 +0200 Subject: Make dist::rule reusable as base --- libbuild2/dist/init.cxx | 14 +++++--------- libbuild2/dist/module.hxx | 11 ++++------- libbuild2/dist/operation.cxx | 10 +++------- libbuild2/dist/rule.cxx | 20 +++++++++++++++----- libbuild2/dist/rule.hxx | 23 +++++++++++++---------- libbuild2/dist/types.hxx | 1 + 6 files changed, 41 insertions(+), 38 deletions(-) diff --git a/libbuild2/dist/init.cxx b/libbuild2/dist/init.cxx index 9de84ce..26ff86d 100644 --- a/libbuild2/dist/init.cxx +++ b/libbuild2/dist/init.cxx @@ -21,6 +21,8 @@ namespace build2 { namespace dist { + static const rule rule_; + void boot (scope& rs, const location&, module_boot_extra& extra) { @@ -194,7 +196,7 @@ namespace build2 const location& l, bool first, bool, - module_init_extra& extra) + module_init_extra&) { tracer trace ("dist::init"); @@ -206,19 +208,13 @@ namespace build2 l5 ([&]{trace << "for " << rs;}); - module& mod (extra.module_as ()); - auto& vp (rs.var_pool (true /* public */)); // All qualified. // Register our wildcard rule. Do it explicitly for the alias to prevent // something like insert(dist_id, test_id) taking precedence. // - { - const rule& r (mod); - - rs.insert_rule (dist_id, 0, "dist", r); - rs.insert_rule (dist_id, 0, "dist.alias", r); - } + rs.insert_rule (dist_id, 0, "dist", rule_); + rs.insert_rule (dist_id, 0, "dist.alias", rule_); // We need this rule for out-of-any-project dependencies (for example, // executables imported from /usr/bin, etc). We are registering it on diff --git a/libbuild2/dist/module.hxx b/libbuild2/dist/module.hxx index dbe2a3e..da97939 100644 --- a/libbuild2/dist/module.hxx +++ b/libbuild2/dist/module.hxx @@ -11,7 +11,6 @@ #include #include -#include #include @@ -19,8 +18,7 @@ namespace build2 { namespace dist { - class LIBBUILD2_SYMEXPORT module: public build2::module, - public rule + class LIBBUILD2_SYMEXPORT module: public build2::module { public: static const string name; @@ -43,9 +41,9 @@ namespace build2 adhoc.push_back (move (f)); } - // List of postponed prerequisites. + // List of postponed prerequisites (see rule for details). // - postponed_prerequisites postponed; + mutable postponed_prerequisites postponed; // Distribution post-processing callbacks. // @@ -79,8 +77,7 @@ namespace build2 // Implementation details. // public: - module (const variable& v_d_p) - : rule (postponed), var_dist_package (v_d_p) {} + module (const variable& v_d_p): var_dist_package (v_d_p) {} public: bool distributed = false; // True if this project is being distributed. diff --git a/libbuild2/dist/operation.cxx b/libbuild2/dist/operation.cxx index e5c9307..af7b40b 100644 --- a/libbuild2/dist/operation.cxx +++ b/libbuild2/dist/operation.cxx @@ -16,6 +16,7 @@ #include #include +#include #include using namespace std; @@ -237,10 +238,7 @@ namespace build2 fail << "unknown distribution package name" << info << "did you forget to set dist.package?"; - // Need non-const in order to clear postponed. This is safe since only - // doing it when running serially. - // - module& mod (const_cast (*rs.find_module (module::name))); + const module& mod (*rs.find_module (module::name)); const string& dist_package (cast (l)); const process_path& dist_cmd (cast (rs.vars["dist.cmd"])); @@ -301,9 +299,7 @@ namespace build2 for (auto i (mod.postponed.list.begin ()); i != mod.postponed.list.end (); ++i) - { - rule::match_postponed (i->action, i->target, i->prereq); - } + rule::match_postponed (*i); } }; diff --git a/libbuild2/dist/rule.cxx b/libbuild2/dist/rule.cxx index 7233eba..736490e 100644 --- a/libbuild2/dist/rule.cxx +++ b/libbuild2/dist/rule.cxx @@ -8,6 +8,9 @@ #include #include +#include +#include + using namespace std; namespace build2 @@ -91,8 +94,11 @@ namespace build2 // may be unknown because we haven't matched the lib{} group // yet. So we postpone this for later (see match_postponed()). // - mlock l (postponed_.mutex); - postponed_.list.push_back (postponed_prerequisite {a, t, p,}); + const module& mod (*rs.find_module (module::name)); + + mlock l (mod.postponed.mutex); + mod.postponed.list.push_back ( + postponed_prerequisite {a, t, p, t.state[a].rule->first}); continue; } @@ -112,19 +118,23 @@ namespace build2 } void rule:: - match_postponed (action a, const target& t, const prerequisite& p) + match_postponed (const postponed_prerequisite& pp) { + action a (pp.action); + const target& t (pp.target); + const prerequisite& p (pp.prereq); + const prerequisite_key& k (p.key ()); const target* pt (k.tk.type->search (t, k)); if (pt == nullptr) { // Note that we do loose the diag frame that we normally get when - // failing during match. So let's mention the target manually. + // failing during match. So let's mention the target/rule manually. // fail << "prerequisite " << k << " is not existing source file nor " << "known output target" << - info << "while applying rule dist to " << diag_do (a, t); + info << "while applying rule " << pp.rule << " to " << diag_do (a, t); } search_custom (p, *pt); // Cache. diff --git a/libbuild2/dist/rule.hxx b/libbuild2/dist/rule.hxx index ec6c41a..69ab3d9 100644 --- a/libbuild2/dist/rule.hxx +++ b/libbuild2/dist/rule.hxx @@ -13,6 +13,8 @@ #include +#include + namespace build2 { namespace dist @@ -21,27 +23,28 @@ namespace build2 // // A custom rule (usually the same as perform_update) may be necessary to // establish group links (so that we see the dist variable set on a group) - // or to see through non-see-through groups (like lib{}; see the - // bin::lib_rule for an example). Note that in the latter case the rule - // should "see" all its members for the dist case. + // or to see through non-see-through groups (like lib{}, obj{}; see rule + // in the bin module for an example). Note that in the latter case the + // rule should "see" all its members for the dist case. // - class rule: public simple_rule + class LIBBUILD2_SYMEXPORT rule: public simple_rule { public: - explicit - rule (postponed_prerequisites& p): postponed_ (p) {} + rule () {} + // Always matches (returns true). + // virtual bool match (action, target&) const override; + // Matches all the prerequisites (including from group) and returns + // noop_recipe (which will never be executed). + // virtual recipe apply (action, target&) const override; static void - match_postponed (action, const target&, const prerequisite&); - - private: - postponed_prerequisites& postponed_; + match_postponed (const postponed_prerequisite&); }; } } diff --git a/libbuild2/dist/types.hxx b/libbuild2/dist/types.hxx index f3b1009..b833951 100644 --- a/libbuild2/dist/types.hxx +++ b/libbuild2/dist/types.hxx @@ -27,6 +27,7 @@ namespace build2 build2::action action; reference_wrapper target; reference_wrapper prereq; + string rule; }; struct postponed_prerequisites -- cgit v1.1