From 76be0a35f6c37cda7ba65530330f1ac246fb52a8 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 6 Apr 2022 11:26:52 +0200 Subject: 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. --- libbuild2/cc/common.hxx | 9 +++------ libbuild2/cc/compile-rule.cxx | 2 +- libbuild2/cc/compile-rule.hxx | 2 +- libbuild2/cc/install-rule.cxx | 17 ++++++++--------- libbuild2/cc/install-rule.hxx | 8 ++++++-- libbuild2/cc/link-rule.cxx | 6 +++--- libbuild2/cc/link-rule.hxx | 8 +++----- libbuild2/cc/module.cxx | 24 ++++++++++++------------ libbuild2/cc/target.cxx | 12 ++++++------ 9 files changed, 43 insertions(+), 45 deletions(-) (limited to 'libbuild2/cc') diff --git a/libbuild2/cc/common.hxx b/libbuild2/cc/common.hxx index 56cde19..017573d 100644 --- a/libbuild2/cc/common.hxx +++ b/libbuild2/cc/common.hxx @@ -156,10 +156,9 @@ namespace build2 struct data: config_data { - const char* x_compile; // Rule names. - const char* x_link; - const char* x_install; - const char* x_uninstall; + string x_compile; // Rule names. + string x_link; + string x_install; // Cached values for some commonly-used variables/values. // @@ -243,7 +242,6 @@ namespace build2 const char* compile, const char* link, const char* install, - const char* uninstall, compiler_type ct, const string& cv, compiler_class cl, @@ -270,7 +268,6 @@ namespace build2 x_compile (compile), x_link (link), x_install (install), - x_uninstall (uninstall), ctype (ct), cvariant (cv), cclass (cl), cmaj (mj), cmin (mi), cvmaj (vmj), cvmin (vmi), diff --git a/libbuild2/cc/compile-rule.cxx b/libbuild2/cc/compile-rule.cxx index e7e90ad..24c9b2b 100644 --- a/libbuild2/cc/compile-rule.cxx +++ b/libbuild2/cc/compile-rule.cxx @@ -406,7 +406,7 @@ namespace build2 } bool compile_rule:: - match (action a, target& t, const string&) const + match (action a, target& t) const { tracer trace (x, "compile_rule::match"); diff --git a/libbuild2/cc/compile-rule.hxx b/libbuild2/cc/compile-rule.hxx index dbb2dd5..00965fc 100644 --- a/libbuild2/cc/compile-rule.hxx +++ b/libbuild2/cc/compile-rule.hxx @@ -45,7 +45,7 @@ namespace build2 compile_rule (data&&); virtual bool - match (action, target&, const string&) const override; + match (action, target&) const override; virtual recipe apply (action, target&) const override; diff --git a/libbuild2/cc/install-rule.cxx b/libbuild2/cc/install-rule.cxx index 560b8a7..e8c87ae 100644 --- a/libbuild2/cc/install-rule.cxx +++ b/libbuild2/cc/install-rule.cxx @@ -97,7 +97,7 @@ namespace build2 { if (header_source (p)) pt = nullptr; - else if (p.type.see_through) + else if (p.type.see_through ()) { for (i.enter_group (); i.group (); ) { @@ -151,15 +151,13 @@ namespace build2 } bool install_rule:: - match (action a, target& t, const string& hint) const + match (action a, target& t, const string&, match_extra& me) const { - // @@ How do we split the hint between the two? - // - // We only want to handle installation if we are also the ones building // this target. So first run link's match(). // - return link_.match (a, t, hint) && file_rule::match (a, t, ""); + return link_.sub_match (x_link, update_id, a, t, me) && + file_rule::match (a, t); } recipe install_rule:: @@ -332,7 +330,7 @@ namespace build2 { if (header_source (p)) pt = nullptr; - else if (p.type.see_through) + else if (p.type.see_through ()) { for (i.enter_group (); i.group (); ) { @@ -372,12 +370,13 @@ namespace build2 } bool libux_install_rule:: - match (action a, target& t, const string& hint) const + match (action a, target& t, const string&, match_extra& me) const { // We only want to handle installation if we are also the ones building // this target. So first run link's match(). // - return link_.match (a, t, hint) && alias_rule::match (a, t, ""); + return link_.sub_match (x_link, update_id, a, t, me) && + alias_rule::match (a, t); } } } diff --git a/libbuild2/cc/install-rule.hxx b/libbuild2/cc/install-rule.hxx index acd1bd8..70ee711 100644 --- a/libbuild2/cc/install-rule.hxx +++ b/libbuild2/cc/install-rule.hxx @@ -38,8 +38,10 @@ namespace build2 filter (const scope*, action, const target&, prerequisite_iterator&) const override; + // Note: rule::match() override. + // 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; @@ -71,8 +73,10 @@ namespace build2 filter (const scope*, action, const target&, prerequisite_iterator&) const override; + // Note: rule::match() override. + // virtual bool - match (action, target&, const string&) const override; + match (action, target&, const string&, match_extra&) const override; private: const link_rule& link_; diff --git a/libbuild2/cc/link-rule.cxx b/libbuild2/cc/link-rule.cxx index b5cc63b..30024ce 100644 --- a/libbuild2/cc/link-rule.cxx +++ b/libbuild2/cc/link-rule.cxx @@ -446,7 +446,7 @@ namespace build2 } bool link_rule:: - match (action a, target& t, const string& hint) const + match (action a, target& t, const string& hint, match_extra&) const { // NOTE: may be called multiple times and for both inner and outer // operations (see the install rules). @@ -495,7 +495,7 @@ namespace build2 // We will only chain a C source if there is also an X source or we were // explicitly told to. // - if (r.seen_c && !r.seen_x && hint < x) + if (r.seen_c && !r.seen_x && hint.empty ()) { l4 ([&]{trace << "C prerequisite without " << x_lang << " or hint " << "for target " << t;}); @@ -850,7 +850,7 @@ namespace build2 }; recipe link_rule:: - apply (action a, target& xt) const + apply (action a, target& xt, match_extra&) const { tracer trace (x, "link_rule::apply"); diff --git a/libbuild2/cc/link-rule.hxx b/libbuild2/cc/link-rule.hxx index c6d06d2..f0052e9 100644 --- a/libbuild2/cc/link-rule.hxx +++ b/libbuild2/cc/link-rule.hxx @@ -18,7 +18,7 @@ namespace build2 { namespace cc { - class LIBBUILD2_CC_SYMEXPORT link_rule: public simple_rule, virtual common + class LIBBUILD2_CC_SYMEXPORT link_rule: public rule, virtual common { public: link_rule (data&&); @@ -46,10 +46,10 @@ namespace build2 match (action, const target&, const target*, otype, bool) const; 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; target_state perform_update (action, const target&) const; @@ -57,8 +57,6 @@ namespace build2 target_state perform_clean (action, const target&) const; - using simple_rule::match; // To make Clang happy. - public: // Library handling. // diff --git a/libbuild2/cc/module.cxx b/libbuild2/cc/module.cxx index 871cfb6..c930d49 100644 --- a/libbuild2/cc/module.cxx +++ b/libbuild2/cc/module.cxx @@ -1083,30 +1083,30 @@ namespace build2 { const install_rule& ir (*this); - r.insert (perform_install_id, x_install, ir); - r.insert (perform_uninstall_id, x_uninstall, ir); + r.insert (perform_install_id, x_install, ir); + r.insert (perform_uninstall_id, x_install, ir); - r.insert (perform_install_id, x_install, ir); - r.insert (perform_uninstall_id, x_uninstall, ir); + r.insert (perform_install_id, x_install, ir); + r.insert (perform_uninstall_id, x_install, ir); if (s) { - r.insert (perform_install_id, x_install, ir); - r.insert (perform_uninstall_id, x_uninstall, ir); + r.insert (perform_install_id, x_install, ir); + r.insert (perform_uninstall_id, x_install, ir); } const libux_install_rule& lr (*this); - r.insert (perform_install_id, x_install, lr); - r.insert (perform_uninstall_id, x_uninstall, lr); + r.insert (perform_install_id, x_install, lr); + r.insert (perform_uninstall_id, x_install, lr); - r.insert (perform_install_id, x_install, lr); - r.insert (perform_uninstall_id, x_uninstall, lr); + r.insert (perform_install_id, x_install, lr); + r.insert (perform_uninstall_id, x_install, lr); if (s) { - r.insert (perform_install_id, x_install, lr); - r.insert (perform_uninstall_id, x_uninstall, lr); + r.insert (perform_install_id, x_install, lr); + r.insert (perform_uninstall_id, x_install, lr); } } } diff --git a/libbuild2/cc/target.cxx b/libbuild2/cc/target.cxx index b17e1ef..3f71eb1 100644 --- a/libbuild2/cc/target.cxx +++ b/libbuild2/cc/target.cxx @@ -21,7 +21,7 @@ namespace build2 nullptr, nullptr, &target_search, - false + target_type::flag::none }; extern const char h_ext_def[] = "h"; @@ -36,7 +36,7 @@ namespace build2 &target_pattern_var, nullptr, &file_search, - false + target_type::flag::none }; extern const char c_ext_def[] = "c"; @@ -51,7 +51,7 @@ namespace build2 &target_pattern_var, nullptr, &file_search, - false + target_type::flag::none }; extern const char pc_ext[] = "pc"; // VC14 rejects constexpr. @@ -66,7 +66,7 @@ namespace build2 &target_pattern_fix, &target_print_0_ext_verb, // Fixed extension, no use printing. &file_search, - false + target_type::flag::none }; extern const char pca_ext[] = "static.pc"; // VC14 rejects constexpr. @@ -81,7 +81,7 @@ namespace build2 &target_pattern_fix, &target_print_0_ext_verb, // Fixed extension, no use printing. &file_search, - false + target_type::flag::none }; extern const char pcs_ext[] = "shared.pc"; // VC14 rejects constexpr. @@ -96,7 +96,7 @@ namespace build2 &target_pattern_fix, &target_print_0_ext_verb, // Fixed extension, no use printing. &file_search, - false + target_type::flag::none }; } } -- cgit v1.1