diff options
Diffstat (limited to 'libbuild2/cc/link-rule.cxx')
-rw-r--r-- | libbuild2/cc/link-rule.cxx | 70 |
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); } } |