aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/cc/install-rule.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2023-09-21 09:33:13 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2023-09-21 09:33:13 +0200
commitce14007653e22f7cb8906317d80c5968f7b53a95 (patch)
tree9d528fd7d7aaf4d1b76195debfe9cb447c447c52 /libbuild2/cc/install-rule.cxx
parent77bef9b64857b1d2ae96dafc2f531cadb374f561 (diff)
Don't install static library prerequisites of executable
Diffstat (limited to 'libbuild2/cc/install-rule.cxx')
-rw-r--r--libbuild2/cc/install-rule.cxx30
1 files changed, 30 insertions, 0 deletions
diff --git a/libbuild2/cc/install-rule.cxx b/libbuild2/cc/install-rule.cxx
index dae65db..ac4a897 100644
--- a/libbuild2/cc/install-rule.cxx
+++ b/libbuild2/cc/install-rule.cxx
@@ -38,15 +38,29 @@ namespace build2
// Less obvious: we also want to install a static library prerequisite
// of a library (since it could be referenced from its .pc file, etc).
//
+ // This is also the place were we make sure we don't install static
+ // library prerequisites of an executable (we cannot do it later, where
+ // we handle headers, because we may need to resolve the member).
+ // However, there is a nuance: we still have to update such static
+ // libraries in order to signal that they are being built for install.
+ //
// Note: for now we assume these prerequisites never come from see-
// through groups.
//
// Note: we install ad hoc prerequisites by default.
//
+ if (a.operation () != update_id && t.is_a<exe> () && p.is_a<liba> ())
+ return nullptr;
+
otype ot (link_type (t).type);
+ // Note: at least one must be true since we only register this rule for
+ // exe{}, and lib[as]{} (this makes sure the following if-condition will
+ // always be true for libx{}).
+ //
bool st (t.is_a<exe> () || t.is_a<libs> ()); // Target needs shared.
bool at (t.is_a<liba> () || t.is_a<libs> ()); // Target needs static.
+ assert (st || at);
if ((st && (p.is_a<libx> () || p.is_a<libs> ())) ||
(at && (p.is_a<libx> () || p.is_a<liba> ())))
@@ -57,8 +71,14 @@ namespace build2
// link. For libu*{} we want the "see through" logic.
//
if (const libx* l = pt->is_a<libx> ())
+ {
pt = link_member (*l, a, link_info (t.base_scope (), ot));
+ if (a.operation () != update_id &&
+ t.is_a<exe> () && pt->is_a<liba> ())
+ return nullptr;
+ }
+
// Note: not redundant since we are returning a member.
//
if ((st && pt->is_a<libs> ()) || (at && pt->is_a<liba> ()))
@@ -312,10 +332,14 @@ namespace build2
// above. In particular, here we use libue/libua/libus{} as proxies for
// exe/liba/libs{} there.
//
+ if (a.operation () != update_id && t.is_a<libue> () && p.is_a<liba> ())
+ return nullptr;
+
otype ot (link_type (t).type);
bool st (t.is_a<libue> () || t.is_a<libus> ()); // Target needs shared.
bool at (t.is_a<libua> () || t.is_a<libus> ()); // Target needs static.
+ assert (at || at);
if ((st && (p.is_a<libx> () || p.is_a<libs> ())) ||
(at && (p.is_a<libx> () || p.is_a<liba> ())))
@@ -323,8 +347,14 @@ namespace build2
const target* pt (&search (t, p));
if (const libx* l = pt->is_a<libx> ())
+ {
pt = link_member (*l, a, link_info (t.base_scope (), ot));
+ if (a.operation () != update_id &&
+ t.is_a<libue> () && pt->is_a<liba> ())
+ return nullptr;
+ }
+
if ((st && pt->is_a<libs> ()) || (at && pt->is_a<liba> ()))
return is == nullptr || pt->in (*is) ? pt : nullptr;