Use absolute RPATHs while linking due to a binutils bug

Use -rpath-link with the absolute paths to the respective build dirs
to work around a binutils bug that causes $ORIGIN to not be used while
linking.

Includes a unit test that manually checks the RPATH value written out
to ensure that it uses $ORIGIN.

See: https://sourceware.org/bugzilla/show_bug.cgi?id=16936

Closes https://github.com/mesonbuild/meson/issues/1897
pull/1898/head
Nirbheek Chauhan 8 years ago
parent d79bdb9b6b
commit 264ce6c0bc
  1. 7
      mesonbuild/compilers.py
  2. 22
      run_unittests.py

@ -337,7 +337,12 @@ def build_unix_rpath_args(build_dir, from_dir, rpath_paths, install_rpath):
paths = padding paths = padding
else: else:
paths = paths + ':' + padding paths = paths + ':' + padding
return ['-Wl,-rpath,' + paths] # Rpaths to use while linking must be absolute. These are not used
# while running and are not written to the binary.
# https://github.com/mesonbuild/meson/issues/1897
# https://sourceware.org/bugzilla/show_bug.cgi?id=16936
linkpaths = ':'.join([os.path.join(build_dir, p) for p in rpath_paths])
return ['-Wl,-rpath,' + paths, '-Wl,-rpath-link,' + linkpaths]
class CrossNoRunException(MesonException): class CrossNoRunException(MesonException):
pass pass

@ -49,6 +49,9 @@ def get_dynamic_section_entry(fname, entry):
def get_soname(fname): def get_soname(fname):
return get_dynamic_section_entry(fname, 'soname') return get_dynamic_section_entry(fname, 'soname')
def get_rpath(fname):
return get_dynamic_section_entry(fname, 'rpath')
class InternalTests(unittest.TestCase): class InternalTests(unittest.TestCase):
@ -1133,6 +1136,25 @@ int main(int argc, char **argv) {
self.assertTrue(os.path.exists(distfile)) self.assertTrue(os.path.exists(distfile))
self.assertTrue(os.path.exists(checksumfile)) self.assertTrue(os.path.exists(checksumfile))
def test_rpath_uses_ORIGIN(self):
'''
Test that built targets use $ORIGIN in rpath, which ensures that they
are relocatable and ensures that builds are reproducible since the
build directory won't get embedded into the built binaries.
'''
if is_windows() or is_cygwin():
raise unittest.SkipTest('Windows PE/COFF binaries do not use RPATH')
testdir = os.path.join(self.common_test_dir, '46 library chain')
self.init(testdir)
self.build()
for each in ('prog', 'subdir/liblib1.so', 'subdir/subdir2/liblib2.so',
'subdir/subdir3/liblib3.so'):
rpath = get_rpath(os.path.join(self.builddir, each))
self.assertTrue(rpath)
for path in rpath.split(':'):
self.assertTrue(path.startswith('$ORIGIN'), msg=(each, path))
class WindowsTests(BasePlatformTests): class WindowsTests(BasePlatformTests):
''' '''
Tests that should run on Cygwin, MinGW, and MSVC Tests that should run on Cygwin, MinGW, and MSVC

Loading…
Cancel
Save