aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesonbuild/backend/backends.py18
-rwxr-xr-xrun_unittests.py33
-rw-r--r--test cases/unit/77 global-rpath/meson.build3
-rw-r--r--test cases/unit/77 global-rpath/rpathified.cpp6
-rw-r--r--test cases/unit/77 global-rpath/yonder/meson.build5
-rw-r--r--test cases/unit/77 global-rpath/yonder/yonder.cpp3
-rw-r--r--test cases/unit/77 global-rpath/yonder/yonder.h1
7 files changed, 69 insertions, 0 deletions
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py
index 6f6d3db..5649909 100644
--- a/mesonbuild/backend/backends.py
+++ b/mesonbuild/backend/backends.py
@@ -444,6 +444,21 @@ class Backend:
return True
return False
+ def get_external_rpath_dirs(self, target):
+ dirs = set()
+ args = []
+ # FIXME: is there a better way?
+ for lang in ['c', 'cpp']:
+ try:
+ args.extend(self.environment.coredata.get_external_link_args(target.for_machine, lang))
+ except Exception:
+ pass
+ for arg in args:
+ if arg.startswith('-Wl,-rpath='):
+ for dir in arg.replace('-Wl,-rpath=','').split(':'):
+ dirs.add(dir)
+ return dirs
+
def rpaths_for_bundled_shared_libraries(self, target, exclude_system=True):
paths = []
for dep in target.external_deps:
@@ -458,6 +473,9 @@ class Backend:
if exclude_system and self._libdir_is_system(libdir, target.compilers, self.environment):
# No point in adding system paths.
continue
+ # Don't remove rpaths specified in LDFLAGS.
+ if libdir in self.get_external_rpath_dirs(target):
+ continue
# Windows doesn't support rpaths, but we use this function to
# emulate rpaths by setting PATH, so also accept DLLs here
if os.path.splitext(libpath)[1] not in ['.dll', '.lib', '.so', '.dylib']:
diff --git a/run_unittests.py b/run_unittests.py
index d7fc221..8ad64be 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -6079,6 +6079,39 @@ class LinuxlikeTests(BasePlatformTests):
install_rpath = get_rpath(os.path.join(self.installdir, 'usr/bin/progcxx'))
self.assertEqual(install_rpath, 'baz')
+ def test_global_rpath(self):
+ if is_cygwin():
+ raise unittest.SkipTest('Windows PE/COFF binaries do not use RPATH')
+ if is_osx():
+ raise unittest.SkipTest('Global RPATHs via LDFLAGS not yet supported on MacOS (does anybody need it?)')
+
+ testdir = os.path.join(self.unit_test_dir, '77 global-rpath')
+ oldinstalldir = self.installdir
+
+ # Build and install an external library without DESTDIR.
+ # The external library generates a .pc file without an rpath.
+ yonder_dir = os.path.join(testdir, 'yonder')
+ yonder_prefix = os.path.join(oldinstalldir, 'yonder')
+ yonder_libdir = os.path.join(yonder_prefix, self.libdir)
+ self.prefix = yonder_prefix
+ self.installdir = yonder_prefix
+ self.init(yonder_dir)
+ self.build()
+ self.install(use_destdir=False)
+ self.new_builddir()
+
+ # Build an app that uses that installed library.
+ # Supply the rpath to the installed library via LDFLAGS
+ # (as systems like buildroot and guix are wont to do)
+ # and verify install preserves that rpath.
+ env = {'LDFLAGS': '-Wl,-rpath=' + yonder_libdir,
+ 'PKG_CONFIG_PATH': os.path.join(yonder_libdir, 'pkgconfig')}
+ self.init(testdir, override_envvars=env)
+ self.build()
+ self.install(use_destdir=False)
+ got_rpath = get_rpath(os.path.join(yonder_prefix, 'bin/rpathified'))
+ self.assertEqual(got_rpath, yonder_libdir)
+
@skip_if_not_base_option('b_sanitize')
def test_pch_with_address_sanitizer(self):
if is_cygwin():
diff --git a/test cases/unit/77 global-rpath/meson.build b/test cases/unit/77 global-rpath/meson.build
new file mode 100644
index 0000000..c67d9e0
--- /dev/null
+++ b/test cases/unit/77 global-rpath/meson.build
@@ -0,0 +1,3 @@
+project('global-rpath', 'cpp')
+yonder_dep = dependency('yonder')
+executable('rpathified', 'rpathified.cpp', dependencies: [yonder_dep], install: true)
diff --git a/test cases/unit/77 global-rpath/rpathified.cpp b/test cases/unit/77 global-rpath/rpathified.cpp
new file mode 100644
index 0000000..3788906
--- /dev/null
+++ b/test cases/unit/77 global-rpath/rpathified.cpp
@@ -0,0 +1,6 @@
+#include <yonder.h>
+#include <string.h>
+int main(int argc, char **argv)
+{
+ return strcmp(yonder(), "AB54 6BR");
+}
diff --git a/test cases/unit/77 global-rpath/yonder/meson.build b/test cases/unit/77 global-rpath/yonder/meson.build
new file mode 100644
index 0000000..e32f383
--- /dev/null
+++ b/test cases/unit/77 global-rpath/yonder/meson.build
@@ -0,0 +1,5 @@
+project('yonder', 'cpp')
+yonder = shared_library('yonder', 'yonder.cpp', install: true)
+install_headers('yonder.h')
+pkgconfig = import('pkgconfig')
+pkgconfig.generate(yonder)
diff --git a/test cases/unit/77 global-rpath/yonder/yonder.cpp b/test cases/unit/77 global-rpath/yonder/yonder.cpp
new file mode 100644
index 0000000..b182d34
--- /dev/null
+++ b/test cases/unit/77 global-rpath/yonder/yonder.cpp
@@ -0,0 +1,3 @@
+#include "yonder.h"
+
+char *yonder(void) { return "AB54 6BR"; }
diff --git a/test cases/unit/77 global-rpath/yonder/yonder.h b/test cases/unit/77 global-rpath/yonder/yonder.h
new file mode 100644
index 0000000..9d9ad16
--- /dev/null
+++ b/test cases/unit/77 global-rpath/yonder/yonder.h
@@ -0,0 +1 @@
+char *yonder(void);