aboutsummaryrefslogtreecommitdiff
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
parent77bef9b64857b1d2ae96dafc2f531cadb374f561 (diff)
Don't install static library prerequisites of executable
-rw-r--r--libbuild2/cc/install-rule.cxx30
-rw-r--r--libbuild2/cc/install-rule.hxx3
2 files changed, 32 insertions, 1 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;
diff --git a/libbuild2/cc/install-rule.hxx b/libbuild2/cc/install-rule.hxx
index 6998d63..5039309 100644
--- a/libbuild2/cc/install-rule.hxx
+++ b/libbuild2/cc/install-rule.hxx
@@ -24,7 +24,8 @@ namespace build2
//
// 1. Signal to the link rule that this is update for install.
//
- // 2. Custom filtering of prerequisites (e.g., headers of an exe{}).
+ // 2. Custom filtering of prerequisites (e.g., headers and static
+ // libraries of an exe{}).
//
// 3. Extra un/installation (e.g., libs{} symlinks).
//