aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNirbheek Chauhan <nirbheek@centricular.com>2017-06-05 02:11:43 +0530
committerNirbheek Chauhan <nirbheek@centricular.com>2017-06-05 02:19:46 +0530
commit264ce6c0bc27d2998368b7652b1c12729f088d3a (patch)
tree4e4087c99c87ca106b35fa50980f310496115f35
parentd79bdb9b6bc915f146ce2ab2cfdf17d077953f5d (diff)
downloadmeson-264ce6c0bc27d2998368b7652b1c12729f088d3a.zip
meson-264ce6c0bc27d2998368b7652b1c12729f088d3a.tar.gz
meson-264ce6c0bc27d2998368b7652b1c12729f088d3a.tar.bz2
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
-rw-r--r--mesonbuild/compilers.py7
-rwxr-xr-xrun_unittests.py22
2 files changed, 28 insertions, 1 deletions
diff --git a/mesonbuild/compilers.py b/mesonbuild/compilers.py
index 06b0a59..595be60 100644
--- a/mesonbuild/compilers.py
+++ b/mesonbuild/compilers.py
@@ -337,7 +337,12 @@ def build_unix_rpath_args(build_dir, from_dir, rpath_paths, install_rpath):
paths = padding
else:
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):
pass
diff --git a/run_unittests.py b/run_unittests.py
index 34a1a15..6d81b00 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -49,6 +49,9 @@ def get_dynamic_section_entry(fname, entry):
def get_soname(fname):
return get_dynamic_section_entry(fname, 'soname')
+def get_rpath(fname):
+ return get_dynamic_section_entry(fname, 'rpath')
+
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(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):
'''
Tests that should run on Cygwin, MinGW, and MSVC