aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2023-10-27 05:40:52 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2023-10-27 05:40:52 +0200
commit152f83d22861129dba48404632b61b3f00f18715 (patch)
treea83925b5475410132e17ec90a2366f90745ea32d
parenta7c48347e8437d3b699691bc1eea9e76e93604b6 (diff)
WIP: install: ad hoc members
-rw-r--r--libbuild2/cc/install-rule.cxx83
-rw-r--r--libbuild2/cc/install-rule.hxx10
-rw-r--r--libbuild2/install/rule.cxx43
-rw-r--r--libbuild2/install/rule.hxx15
4 files changed, 96 insertions, 55 deletions
diff --git a/libbuild2/cc/install-rule.cxx b/libbuild2/cc/install-rule.cxx
index 4ed674a..fff3bdf 100644
--- a/libbuild2/cc/install-rule.cxx
+++ b/libbuild2/cc/install-rule.cxx
@@ -24,6 +24,41 @@ namespace build2
install_rule (data&& d, const link_rule& l)
: common (move (d)), link_ (l) {}
+ // Wrap the file_rule's recipe into a data-carrying recipe.
+ //
+ struct install_match_data
+ {
+ build2::recipe recipe;
+ uint64_t options; // Match options.
+ link_rule::libs_paths libs_paths;
+
+ target_state
+ operator() (action a, const target& t)
+ {
+ return recipe (a, t);
+ }
+ };
+
+ bool install_rule::
+ filter (action a, const target& t, const target& m) const
+ {
+ if (!t.is_a<exe> ())
+ {
+ // If runtime-only, filter out all known buildtime member types.
+ //
+ const auto& md (t.data<install_match_data> (a));
+
+ if ((md.options & lib::option_install_buildtime) == 0)
+ {
+ if (m.is_a<pc> () || // pkg-config files.
+ m.is_a<libi> ()) // Import library.
+ return false;
+ }
+ }
+
+ return true;
+ }
+
pair<const target*, uint64_t> install_rule::
filter (const scope* is,
action a, const target& t, prerequisite_iterator& i,
@@ -205,21 +240,6 @@ namespace build2
file_rule::match (a, t);
}
- // Wrap the file_rule's recipe into a data-carrying recipe.
- //
- struct install_match_data
- {
- build2::recipe recipe;
- uint64_t options; // Match options.
- link_rule::libs_paths libs_paths;
-
- target_state
- operator() (action a, const target& t)
- {
- return recipe (a, t);
- }
- };
-
recipe install_rule::
apply (action a, target& t, match_extra& me) const
{
@@ -267,13 +287,15 @@ namespace build2
}
else // install or uninstall
{
- // Derive shared library paths and cache them in the target's aux
- // storage if we are un/installing (used in the *_extra() functions
- // below).
- //
- if (file* f = t.is_a<libs> ())
+ file* ls;
+ if ((ls = t.is_a<libs> ()) || t.is_a<liba> ())
{
- if (!f->path ().empty ()) // Not binless.
+ // Derive shared library paths and cache them in the target's aux
+ // storage if we are un/installing (used in the *_extra() functions
+ // below).
+ //
+ link_rule::libs_paths lsp;
+ if (ls != nullptr && !ls->path ().empty ()) // Not binless.
{
// Note: we could omit deriving the paths if cur_options doesn't
// have the buildtime option. But then we would have to duplicate
@@ -283,13 +305,12 @@ namespace build2
const string* p (cast_null<string> (t["bin.lib.prefix"]));
const string* s (cast_null<string> (t["bin.lib.suffix"]));
- return install_match_data {
- move (r),
- me.cur_options,
- link_.derive_libs_paths (*f,
- p != nullptr ? p->c_str (): nullptr,
- s != nullptr ? s->c_str (): nullptr)};
+ lsp = link_.derive_libs_paths (*ls,
+ p != nullptr ? p->c_str (): nullptr,
+ s != nullptr ? s->c_str (): nullptr);
}
+
+ return install_match_data {move (r), me.cur_options, move (lsp)};
}
}
@@ -322,13 +343,9 @@ namespace build2
me.cur_options |= me.new_options;
- // Update options in install_match_data.
+ // We also need to update options in install_match_data.
//
- if (file* f = t.is_a<libs> ())
- {
- if (!f->path ().empty ()) // Not binless.
- t.data<install_match_data> (a).options = me.cur_options;
- }
+ t.data<install_match_data> (a).options = me.cur_options;
}
bool install_rule::
diff --git a/libbuild2/cc/install-rule.hxx b/libbuild2/cc/install-rule.hxx
index 2427fda..9d9211b 100644
--- a/libbuild2/cc/install-rule.hxx
+++ b/libbuild2/cc/install-rule.hxx
@@ -36,6 +36,9 @@ namespace build2
public:
install_rule (data&&, const link_rule&);
+ virtual bool
+ filter (action, const target&, const target&) const override;
+
virtual pair<const target*, uint64_t>
filter (const scope*,
action, const target&, prerequisite_iterator&,
@@ -70,13 +73,14 @@ namespace build2
// through them in case they depend on stuff that we need to install
// (e.g., headers). Note that we use the alias_rule as a base.
//
- class LIBBUILD2_CC_SYMEXPORT libux_install_rule:
- public install::alias_rule,
- virtual common
+ class LIBBUILD2_CC_SYMEXPORT libux_install_rule: public install::alias_rule,
+ virtual common
{
public:
libux_install_rule (data&&, const link_rule&);
+ // Note: utility libraries currently have no ad hoc members.
+
virtual pair<const target*, uint64_t>
filter (const scope*,
action, const target&, prerequisite_iterator&,
diff --git a/libbuild2/install/rule.cxx b/libbuild2/install/rule.cxx
index 7e086a8..788a13f 100644
--- a/libbuild2/install/rule.cxx
+++ b/libbuild2/install/rule.cxx
@@ -193,10 +193,10 @@ namespace build2
alias_rule::match (a, t);
}
- const target* group_rule::
- filter (action, const target&, const target& m) const
+ bool group_rule::
+ filter (action, const target&, const target&) const
{
- return &m;
+ return true;
}
pair<const target*, uint64_t> group_rule::
@@ -250,17 +250,16 @@ namespace build2
auto& pts (t.prerequisite_targets[a]);
for (size_t i (0); i != gv.count; ++i)
{
- const target* m (gv.members[i]);
+ const target* mt (gv.members[i]);
- if (m == nullptr)
+ if (mt == nullptr)
continue;
// Let a customized rule have its say.
//
- const target* mt (filter (a, t, *m));
- if (mt == nullptr)
+ if (!filter (a, t, *mt))
{
- l5 ([&]{trace << "ignoring " << *m << " (filtered out)";});
+ l5 ([&]{trace << "ignoring " << *mt << " (filtered out)";});
continue;
}
@@ -300,6 +299,12 @@ namespace build2
return true;
}
+ bool file_rule::
+ filter (action, const target&, const target&) const
+ {
+ return true;
+ }
+
pair<const target*, uint64_t> file_rule::
filter (const scope* is,
action a, const target& t, prerequisite_iterator& i,
@@ -1177,10 +1182,13 @@ namespace build2
{
if (!mf->path ().empty () && mf->mtime () != timestamp_nonexistent)
{
- if (const path* p = lookup_install<path> (*mf, "install"))
+ if (filter (a, t, *mf))
{
- install_target (*mf, *p, tp.empty () ? 1 : 2);
- r |= target_state::changed;
+ if (const path* p = lookup_install<path> (*mf, "install"))
+ {
+ install_target (*mf, *p, tp.empty () ? 1 : 2);
+ r |= target_state::changed;
+ }
}
}
}
@@ -1556,12 +1564,15 @@ namespace build2
{
if (!mf->path ().empty () && mf->mtime () != timestamp_nonexistent)
{
- if (const path* p = lookup_install<path> (*m, "install"))
+ if (filter (a, t, *mf))
{
- r |= uninstall_target (
- *mf,
- *p,
- tp.empty () || r != target_state::changed ? 1 : 2);
+ if (const path* p = lookup_install<path> (*m, "install"))
+ {
+ r |= uninstall_target (
+ *mf,
+ *p,
+ tp.empty () || r != target_state::changed ? 1 : 2);
+ }
}
}
}
diff --git a/libbuild2/install/rule.hxx b/libbuild2/install/rule.hxx
index 3f30757..2ddacc6 100644
--- a/libbuild2/install/rule.hxx
+++ b/libbuild2/install/rule.hxx
@@ -81,12 +81,12 @@ namespace build2
virtual bool
match (action, target&) const override;
- // Return NULL if this group member should be ignored and pointer to its
- // target otherwise.
+ // Return false if this group member should be ignored and true
+ // otherwise. Note that this filter is called during apply().
//
// The default implementation accepts all members.
//
- virtual const target*
+ virtual bool
filter (action, const target&, const target& group_member) const;
// Return NULL if this prerequisite should be ignored and pointer to its
@@ -116,6 +116,15 @@ namespace build2
virtual bool
match (action, target&) const override;
+ // Return false if this ad hoc group member should be ignored and true
+ // otherwise. Note that this filter is called during execute and only
+ // for install/uninstall (and not update).
+ //
+ // The default implementation accepts all members.
+ //
+ virtual bool
+ filter (action, const target&, const target& adhoc_group_member) const;
+
// Return NULL if this prerequisite should be ignored and pointer to its
// target otherwise. In the latter case, return the match options that
// should be used for this prerequisite (use match_extra::all_options