aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/cc/link-rule.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'libbuild2/cc/link-rule.cxx')
-rw-r--r--libbuild2/cc/link-rule.cxx70
1 files changed, 61 insertions, 9 deletions
diff --git a/libbuild2/cc/link-rule.cxx b/libbuild2/cc/link-rule.cxx
index 08a60b9..417cba5 100644
--- a/libbuild2/cc/link-rule.cxx
+++ b/libbuild2/cc/link-rule.cxx
@@ -2585,6 +2585,24 @@ namespace build2
// We don't rpath system libraries. Why, you may ask? There are many
// good reasons and I have them written on a napkin somewhere...
//
+ // Well, the main reason is that we naturally assume the dynamic
+ // linker searches there by default and so there is no need for rpath.
+ // Plus, rpath would prevent "overriding" distribution-system
+ // (/usr/lib) libraries with user-system (/usr/local/lib).
+ //
+ // Note, however, that some operating systems don't search in
+ // /usr/local/lib by default (for example, Fedora, RHEL, Mac OS since
+ // version 13). In a sense, on these platforms /usr/local is
+ // "half-system" in that the system compiler by default searches in
+ // /usr/local/include and/or /usr/local/lib (see config_module::init()
+ // for background) but the dynamic linker does not. While we could
+ // hack this test for such platforms and add rpath for /usr/local/lib,
+ // this is still feels wrong (the user can always "fix" such an
+ // operating system by instructing the dynamic linker to search in
+ // /usr/local/lib, as many, including ourselves, do). So for now we
+ // are not going to do anything. In the end, the user can always add
+ // an rpath for /usr/local/lib manually.
+ //
// We also assume system libraries can only depend on other system
// libraries and so can prune the traversal.
//
@@ -2596,18 +2614,26 @@ namespace build2
size_t p (path::traits_type::rfind_separator (f));
assert (p != string::npos);
+ // For good measure, also suppress duplicates at the options level.
+ // This will take care of different libraries built in the same
+ // directory, system-installed, etc.
+
if (d.rpath)
{
string o ("-Wl,-rpath,");
o.append (f, 0, (p != 0 ? p : 1)); // Don't include trailing slash.
- d.args.push_back (move (o));
+
+ if (find (d.args.begin (), d.args.end (), o) == d.args.end ())
+ d.args.push_back (move (o));
}
if (d.rpath_link)
{
string o ("-Wl,-rpath-link,");
o.append (f, 0, (p != 0 ? p : 1));
- d.args.push_back (move (o));
+
+ if (find (d.args.begin (), d.args.end (), o) == d.args.end ())
+ d.args.push_back (move (o));
}
};
@@ -2660,7 +2686,9 @@ namespace build2
if ((c
? f.compare (p, string::npos, e)
: icasecmp (f.c_str () + p, e)) == 0)
+ {
append (f);
+ }
}
}
@@ -2671,13 +2699,22 @@ namespace build2
{
// Top-level shared library dependency.
//
+ // As above, suppress duplicates.
+ //
+ if (find (d.ls.begin (), d.ls.end (), &l) != d.ls.end ())
+ return;
+
if (!l.path ().empty ()) // Not binless.
{
// It is either matched or imported so should be a cc library.
//
if (!cast_false<bool> (l.vars[c_system]))
{
- args.push_back ("-Wl,-rpath," + l.path ().directory ().string ());
+ string o ("-Wl,-rpath," + l.path ().directory ().string ());
+
+ if (find (args.begin (), args.end (), o) == args.end ())
+ args.push_back (move (o));
+
ls.push_back (&l);
}
}
@@ -3332,6 +3369,9 @@ namespace build2
origin = p.directory ();
}
+ // Note: suppress duplicates at the options level, similar to
+ // rpath_libraries().
+
bool origin_used (false);
for (const dir_path& p: cast<dir_paths> (l))
{
@@ -3368,7 +3408,8 @@ namespace build2
else
o += p.string ();
- sargs.push_back (move (o));
+ if (find (sargs.begin (), sargs.end (), o) == sargs.end ())
+ sargs.push_back (move (o));
}
// According to the Internet, `-Wl,-z,origin` is not needed except
@@ -3386,7 +3427,12 @@ namespace build2
fail << ctgt << " does not support rpath-link";
for (const dir_path& p: cast<dir_paths> (l))
- sargs.push_back ("-Wl,-rpath-link," + p.string ());
+ {
+ string o ("-Wl,-rpath-link," + p.string ());
+
+ if (find (sargs.begin (), sargs.end (), o) == sargs.end ())
+ sargs.push_back (move (o));
+ }
}
}
@@ -3433,13 +3479,19 @@ namespace build2
append_args (sargs1);
}
- else
+ else if (b != x)
{
- append_option_values (
- args,
+ // Use the more canonical combined form (-L/usr/local/lib) even
+ // though it's less efficient (the split one is just too much of an
+ // eye-sore in the logs).
+ //
+ append_combined_option_values (
+ sargs1,
"-L",
b, x,
- [] (const dir_path& d) {return d.string ().c_str ();});
+ [] (const dir_path& d) -> const string& {return d.string ();});
+
+ append_args (sargs1);
}
}