Let LDFLAGS specify rpath.

Fixes #2567
pull/7103/head
Dan Kegel 5 years ago
parent d7235c5905
commit f8cfb74e9b
  1. 18
      mesonbuild/backend/backends.py
  2. 33
      run_unittests.py
  3. 3
      test cases/unit/77 global-rpath/meson.build
  4. 6
      test cases/unit/77 global-rpath/rpathified.cpp
  5. 5
      test cases/unit/77 global-rpath/yonder/meson.build
  6. 3
      test cases/unit/77 global-rpath/yonder/yonder.cpp
  7. 1
      test cases/unit/77 global-rpath/yonder/yonder.h

@ -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']:

@ -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():

@ -0,0 +1,3 @@
project('global-rpath', 'cpp')
yonder_dep = dependency('yonder')
executable('rpathified', 'rpathified.cpp', dependencies: [yonder_dep], install: true)

@ -0,0 +1,6 @@
#include <yonder.h>
#include <string.h>
int main(int argc, char **argv)
{
return strcmp(yonder(), "AB54 6BR");
}

@ -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)

@ -0,0 +1,3 @@
#include "yonder.h"
char *yonder(void) { return "AB54 6BR"; }
Loading…
Cancel
Save