aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/cc
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2022-04-06 11:26:52 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2022-04-06 13:51:56 +0200
commit76be0a35f6c37cda7ba65530330f1ac246fb52a8 (patch)
treef613ceafcf6c7208984d4536653061c4e0c23be7 /libbuild2/cc
parent0a9dd0c7d31cbba2170fdfda4b747a1fe5ce665a (diff)
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.
Diffstat (limited to 'libbuild2/cc')
-rw-r--r--libbuild2/cc/common.hxx9
-rw-r--r--libbuild2/cc/compile-rule.cxx2
-rw-r--r--libbuild2/cc/compile-rule.hxx2
-rw-r--r--libbuild2/cc/install-rule.cxx17
-rw-r--r--libbuild2/cc/install-rule.hxx8
-rw-r--r--libbuild2/cc/link-rule.cxx6
-rw-r--r--libbuild2/cc/link-rule.hxx8
-rw-r--r--libbuild2/cc/module.cxx24
-rw-r--r--libbuild2/cc/target.cxx12
9 files changed, 43 insertions, 45 deletions
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<exe> (perform_install_id, x_install, ir);
- r.insert<exe> (perform_uninstall_id, x_uninstall, ir);
+ r.insert<exe> (perform_install_id, x_install, ir);
+ r.insert<exe> (perform_uninstall_id, x_install, ir);
- r.insert<liba> (perform_install_id, x_install, ir);
- r.insert<liba> (perform_uninstall_id, x_uninstall, ir);
+ r.insert<liba> (perform_install_id, x_install, ir);
+ r.insert<liba> (perform_uninstall_id, x_install, ir);
if (s)
{
- r.insert<libs> (perform_install_id, x_install, ir);
- r.insert<libs> (perform_uninstall_id, x_uninstall, ir);
+ r.insert<libs> (perform_install_id, x_install, ir);
+ r.insert<libs> (perform_uninstall_id, x_install, ir);
}
const libux_install_rule& lr (*this);
- r.insert<libue> (perform_install_id, x_install, lr);
- r.insert<libue> (perform_uninstall_id, x_uninstall, lr);
+ r.insert<libue> (perform_install_id, x_install, lr);
+ r.insert<libue> (perform_uninstall_id, x_install, lr);
- r.insert<libua> (perform_install_id, x_install, lr);
- r.insert<libua> (perform_uninstall_id, x_uninstall, lr);
+ r.insert<libua> (perform_install_id, x_install, lr);
+ r.insert<libua> (perform_uninstall_id, x_install, lr);
if (s)
{
- r.insert<libus> (perform_install_id, x_install, lr);
- r.insert<libus> (perform_uninstall_id, x_uninstall, lr);
+ r.insert<libus> (perform_install_id, x_install, lr);
+ r.insert<libus> (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<h_ext_def>,
nullptr,
&file_search,
- false
+ target_type::flag::none
};
extern const char c_ext_def[] = "c";
@@ -51,7 +51,7 @@ namespace build2
&target_pattern_var<c_ext_def>,
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<pc_ext>,
&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<pca_ext>,
&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<pcs_ext>,
&target_print_0_ext_verb, // Fixed extension, no use printing.
&file_search,
- false
+ target_type::flag::none
};
}
}