aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2019-04-04 10:58:36 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2019-04-04 10:58:36 +0200
commit39a17ba7ef506192218f24047f129cb635efb02b (patch)
tree454ce4d2a11554a47c7f7dc6ecb4efe9d91199fc
parent6e126ac30038502acf7016f0e76b3183f1304042 (diff)
Add ability to disable automatic rpath, support for custom rpath-link
Specifically, the new config.bin.rpath.auto variable can be used to disable automatic addition of prerequisite library rpaths, for example: $ b config.bin.rpath.auto=false Note that in this case rpath-link is still added where normally required and for targets that support it (Linux and *BSD). The new config.bin.rpath_link and config.bin.rpath_link.auto have the same semantics as config.bin.rpath* but for rpath-link.
-rw-r--r--build2/bin/init.cxx47
-rw-r--r--build2/cc/link-rule.cxx57
2 files changed, 81 insertions, 23 deletions
diff --git a/build2/bin/init.cxx b/build2/bin/init.cxx
index 52197d2..f334769 100644
--- a/build2/bin/init.cxx
+++ b/build2/bin/init.cxx
@@ -61,11 +61,25 @@ namespace build2
vp.insert<string> ("config.bin.target", true);
vp.insert<string> ("config.bin.pattern", true);
+ // Library types to build.
+ //
vp.insert<string> ("config.bin.lib", true);
+
+ // Library types to use (in priority order).
+ //
vp.insert<strings> ("config.bin.exe.lib", true);
vp.insert<strings> ("config.bin.liba.lib", true);
vp.insert<strings> ("config.bin.libs.lib", true);
- vp.insert<dir_paths> ("config.bin.rpath", true);
+
+ // The rpath[_link].auto flag controls automatic rpath behavior, for
+ // example, addition of rpaths for prerequisite libraries (see the cc
+ // module for an example). Default is true.
+ //
+ vp.insert<dir_paths> ("config.bin.rpath", true);
+ vp.insert<bool> ("config.bin.rpath.auto", true);
+
+ vp.insert<dir_paths> ("config.bin.rpath_link", true);
+ vp.insert<bool> ("config.bin.rpath_link.auto", true);
vp.insert<string> ("config.bin.prefix", true);
vp.insert<string> ("config.bin.suffix", true);
@@ -75,10 +89,16 @@ namespace build2
vp.insert<string> ("config.bin.exe.suffix", true);
vp.insert<string> ("bin.lib");
+
vp.insert<strings> ("bin.exe.lib");
vp.insert<strings> ("bin.liba.lib");
vp.insert<strings> ("bin.libs.lib");
+
vp.insert<dir_paths> ("bin.rpath");
+ vp.insert<bool> ("bin.rpath.auto");
+
+ vp.insert<dir_paths> ("bin.rpath_link");
+ vp.insert<bool> ("bin.rpath_link.auto");
// Link whole archive. Note: non-overridable with target visibility.
//
@@ -183,14 +203,33 @@ namespace build2
v = *required (rs, "config.bin.libs.lib", libs_lib).first;
}
- // config.bin.rpath
+ // config.bin.rpath[_link]
//
- // This one is optional and we merge it into bin.rpath, if any.
- // See the cxx module for details on merging.
+ // These ones are optional and we merge them into bin.rpath[_link], if
+ // any.
//
rs.assign ("bin.rpath") += cast_null<dir_paths> (
optional (rs, "config.bin.rpath"));
+ rs.assign ("bin.rpath_link") += cast_null<dir_paths> (
+ optional (rs, "config.bin.rpath_link"));
+
+ // config.bin.rpath[_link].auto
+ //
+ {
+ lookup l;
+
+ rs.assign ("bin.rpath.auto") =
+ (l = omitted (rs, "config.bin.rpath.auto").first)
+ ? cast<bool> (l)
+ : true;
+
+ rs.assign ("bin.rpath_link.auto") =
+ (l = omitted (rs, "config.bin.rpath_link.auto").first)
+ ? cast<bool> (l)
+ : true;
+ }
+
// config.bin.{lib,exe}.{prefix,suffix}
//
// These ones are not used very often so we will omit them from the
diff --git a/build2/cc/link-rule.cxx b/build2/cc/link-rule.cxx
index cffd731..ebfe452 100644
--- a/build2/cc/link-rule.cxx
+++ b/build2/cc/link-rule.cxx
@@ -1457,20 +1457,20 @@ namespace build2
const scope& bs,
action a,
linfo li,
- bool for_install) const
+ bool link) const
{
- // Use -rpath-link on targets that support it (Linux, *BSD). Note
+ // Use -rpath-link only on targets that support it (Linux, *BSD). Note
// that we don't really need it for top-level libraries.
//
- if (for_install)
+ if (link)
{
if (tclass != "linux" && tclass != "bsd")
return;
}
- auto imp = [for_install] (const file& l, bool la)
+ auto imp = [link] (const file& l, bool la)
{
- // If we are not installing, then we only need to rpath interface
+ // If we are not rpath-link'ing, then we only need to rpath interface
// libraries (they will include rpath's for their implementations)
// Otherwise, we have to do this recursively. In both cases we also
// want to see through utility libraries.
@@ -1484,7 +1484,7 @@ namespace build2
// except for some noise on the command line.
//
//
- return (for_install ? !la : false) || l.is_a<libux> ();
+ return (link ? !la : false) || l.is_a<libux> ();
};
// Package the data to keep within the 2-pointer small std::function
@@ -1493,8 +1493,8 @@ namespace build2
struct
{
strings& args;
- bool for_install;
- } d {args, for_install};
+ bool link;
+ } d {args, link};
auto lib = [&d, this] (const file* const* lc,
const string& f,
@@ -1547,7 +1547,7 @@ namespace build2
// Ok, if we are here then it means we have a non-system, shared
// library and its absolute path is in f.
//
- string o (d.for_install ? "-Wl,-rpath-link," : "-Wl,-rpath,");
+ string o (d.link ? "-Wl,-rpath-link," : "-Wl,-rpath,");
size_t p (path::traits::rfind_separator (f));
assert (p != string::npos);
@@ -1574,7 +1574,7 @@ namespace build2
(la = (f = pt->is_a<libux> ())) ||
( f = pt->is_a<libs> ()))
{
- if (!for_install && !la)
+ if (!link && !la)
{
// Top-level shared library dependency.
//
@@ -1613,6 +1613,9 @@ namespace build2
const file& t (xt.as<file> ());
const path& tp (t.path ());
+ const scope& bs (t.base_scope ());
+ const scope& rs (*bs.root_scope ());
+
match_data& md (t.data<match_data> ());
// Unless the outer install rule signalled that this is update for
@@ -1623,9 +1626,6 @@ namespace build2
bool for_install (*md.for_install);
- const scope& bs (t.base_scope ());
- const scope& rs (*bs.root_scope ());
-
ltype lt (link_type (t));
otype ot (lt.type);
linfo li (link_info (bs, ot));
@@ -1682,7 +1682,7 @@ namespace build2
// assembly itself is generated later, after updating the target. Omit
// it if we are updating for install.
//
- if (!for_install)
+ if (!for_install && cast_true<bool> (t["bin.rpath.auto"]))
rpath_timestamp = windows_rpath_timestamp (t, bs, a, li);
auto p (windows_manifest (t, rpath_timestamp != timestamp_nonexistent));
@@ -1921,12 +1921,15 @@ namespace build2
if (tclass == "windows")
{
// Limited emulation for Windows with no support for user-defined
- // rpaths.
+ // rpath/rpath-link.
//
- auto l (t["bin.rpath"]);
+ lookup l;
- if (l && !l->empty ())
+ if ((l = t["bin.rpath"]) && !l->empty ())
fail << ctgt << " does not support rpath";
+
+ if ((l = t["bin.rpath_link"]) && !l->empty ())
+ fail << ctgt << " does not support rpath-link";
}
else
{
@@ -1970,11 +1973,27 @@ namespace build2
// rpath of the imported libraries (i.e., we assume they are also
// installed). But we add -rpath-link for some platforms.
//
- rpath_libraries (sargs, t, bs, a, li, for_install);
+ if (cast_true<bool> (t[for_install
+ ? "bin.rpath_link.auto"
+ : "bin.rpath.auto"]))
+ rpath_libraries (sargs, t, bs, a, li, for_install /* link */);
- if (auto l = t["bin.rpath"])
+ lookup l;
+
+ if ((l = t["bin.rpath"]) && !l->empty ())
for (const dir_path& p: cast<dir_paths> (l))
sargs.push_back ("-Wl,-rpath," + p.string ());
+
+ if ((l = t["bin.rpath_link"]) && !l->empty ())
+ {
+ // Only certain targets support -rpath-link (Linux, *BSD).
+ //
+ if (tclass != "linux" && tclass != "bsd")
+ fail << ctgt << " does not support rpath-link";
+
+ for (const dir_path& p: cast<dir_paths> (l))
+ sargs.push_back ("-Wl,-rpath-link," + p.string ());
+ }
}
}