Skip to content

Commit

Permalink
Let LDFLAGS specify rpath.
Browse files Browse the repository at this point in the history
Fixes #2567
  • Loading branch information
dankegel committed May 12, 2020
1 parent 70791e0 commit 84d7f86
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 0 deletions.
18 changes: 18 additions & 0 deletions mesonbuild/backend/backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,21 @@ def _libdir_is_system(libdir, compilers, env):
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:
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:
Expand All @@ -458,6 +473,9 @@ def rpaths_for_bundled_shared_libraries(self, target, exclude_system=True):
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']:
Expand Down
30 changes: 30 additions & 0 deletions run_unittests.py
Original file line number Diff line number Diff line change
Expand Up @@ -6079,6 +6079,36 @@ def test_build_rpath(self):
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')
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():
Expand Down
3 changes: 3 additions & 0 deletions test cases/unit/77 global-rpath/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
project('global-rpath', 'cpp')
yonder_dep = dependency('yonder')
executable('rpathified', 'rpathified.cpp', dependencies: [yonder_dep], install: true)
6 changes: 6 additions & 0 deletions test cases/unit/77 global-rpath/rpathified.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#include <yonder.h>
#include <string.h>
int main(int argc, char **argv)
{
return strcmp(yonder(), "AB54 6BR");
}
5 changes: 5 additions & 0 deletions test cases/unit/77 global-rpath/yonder/meson.build
Original file line number Diff line number Diff line change
@@ -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)
3 changes: 3 additions & 0 deletions test cases/unit/77 global-rpath/yonder/yonder.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#include "yonder.h"

char *yonder(void) { return "AB54 6BR"; }
1 change: 1 addition & 0 deletions test cases/unit/77 global-rpath/yonder/yonder.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
char *yonder(void);

0 comments on commit 84d7f86

Please sign in to comment.