aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2015-12-12 08:39:10 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2015-12-12 08:39:10 +0200
commitc642d8673124b8667123a01a32fa7e83b6301aab (patch)
tree9d028596a5777d5362a1ddf7d329100bd9da93b0
parent0d0d9a9c56822919e9794658d31db57f8fc3e2bf (diff)
Implement soname/rpath dance for shared libraries
-rw-r--r--build/cxx/link.cxx78
1 files changed, 42 insertions, 36 deletions
diff --git a/build/cxx/link.cxx b/build/cxx/link.cxx
index 7d6b15e..a00b92e 100644
--- a/build/cxx/link.cxx
+++ b/build/cxx/link.cxx
@@ -745,8 +745,12 @@ namespace build
scope& rs (t.root_scope ());
cstrings args;
- string storage1;
- strings rpaths;
+
+ // Storage.
+ //
+ string std;
+ string soname;
+ strings sargs;
if (lt == type::a)
{
@@ -760,7 +764,7 @@ namespace build
{
args.push_back (as<string> (*rs["config.cxx"]).c_str ());
append_options (args, t, "cxx.coptions");
- append_std (args, t, storage1);
+ append_std (args, t, std);
if (so)
args.push_back ("-shared");
@@ -768,52 +772,54 @@ namespace build
args.push_back ("-o");
args.push_back (relt.string ().c_str ());
- if (auto l = t["bin.rpath"])
+ // Set soname.
+ //
+ if (so)
{
- const auto& ps (as<strings> (*l));
- rpaths.reserve (ps.size ()); // Make sure no reallocations.
-
- for (const string& p: ps)
- {
- rpaths.push_back ("-Wl,-rpath," + p);
- args.push_back (rpaths.back ().c_str ());
- }
+ soname = "-Wl,-soname," + relt.leaf ().string ();
+ args.push_back (soname.c_str ());
}
- append_options (args, t, "cxx.loptions");
+ // Add rpaths. First the ones specified by the user so that they
+ // take precedence.
+ //
+ if (auto l = t["bin.rpath"])
+ for (const string& p: as<strings> (*l))
+ sargs.push_back ("-Wl,-rpath," + p);
+
+ // Then the paths of the shared libraries we are linking to.
+ //
+ for (target* pt: t.prerequisite_targets)
+ {
+ if (libso* ls = pt->is_a<libso> ())
+ sargs.push_back (
+ "-Wl,-rpath," + ls->path ().directory ().string ());
+ }
}
- // Reserve enough space so that we don't reallocate. Reallocating
- // means pointers to elements may no longer be valid.
- //
- paths relo;
- relo.reserve (t.prerequisite_targets.size ());
+ size_t oend (sargs.size ()); // Note the end of options.
for (target* pt: t.prerequisite_targets)
{
path_target* ppt;
- if ((ppt = pt->is_a<obja> ()))
- ;
- else if ((ppt = pt->is_a<objso> ()))
- ;
- else if ((ppt = pt->is_a<liba> ()))
- ;
- else if ((ppt = pt->is_a<libso> ()))
+ if ((ppt = pt->is_a<obja> ()) ||
+ (ppt = pt->is_a<objso> ()) ||
+ (ppt = pt->is_a<liba> ()) ||
+ (ppt = pt->is_a<libso> ()))
{
- // Use absolute path for the shared libraries since that's
- // the path the runtime loader will use to try to find it.
- // This is probably temporary until we get into the whole
- // -soname/-rpath mess.
- //
- args.push_back (ppt->path ().string ().c_str ());
- continue;
+ sargs.push_back (relative (ppt->path ()).string ()); // string()&&
}
- else
- continue;
+ }
+
+ // Finish assembling args from sargs.
+ //
+ for (size_t i (0); i != sargs.size (); ++i)
+ {
+ if (lt != type::a && i == oend)
+ append_options (args, t, "cxx.loptions");
- relo.push_back (relative (ppt->path ()));
- args.push_back (relo.back ().string ().c_str ());
+ args.push_back (sargs[i].c_str ());
}
if (lt != type::a)