Skip to content

Commit dc1b4be

Browse files
thewildtreeeli-schwartz
authored andcommitted
linkers: Fix AppleDynamicLinker not returning any rpaths to remove
Fixes regression from commit 78e9009. The above commit relied on rpath_dirs_to_remove being present and correctly filled, which was never the case for the AppleDynamicLinker. The result was that all the build-dir-only RPATHs were being carried over to the installed files. This commit implements returning the list of RPATHs to remove in AppleDynamicLinker, doing pretty much the same thing as what's in the GnuLikeDynamicLinkerMixin. Thanks to that, depfixer now correctly removes build-time Meson-created RPATHs, as it used to before 1.4.1.
1 parent 7b43a2e commit dc1b4be

File tree

8 files changed

+43
-2
lines changed

8 files changed

+43
-2
lines changed

mesonbuild/linkers/linkers.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -819,17 +819,19 @@ def build_rpath_args(self, env: 'Environment', build_dir: str, from_dir: str,
819819
if not rpath_paths and not install_rpath and not build_rpath:
820820
return ([], set())
821821
args: T.List[str] = []
822+
rpath_dirs_to_remove: T.Set[bytes] = set()
822823
# @loader_path is the equivalent of $ORIGIN on macOS
823824
# https://stackoverflow.com/q/26280738
824825
origin_placeholder = '@loader_path'
825826
processed_rpaths = prepare_rpaths(rpath_paths, build_dir, from_dir)
826827
all_paths = mesonlib.OrderedSet([os.path.join(origin_placeholder, p) for p in processed_rpaths])
827828
if build_rpath != '':
828-
all_paths.add(build_rpath)
829+
all_paths.update(build_rpath.split(':'))
829830
for rp in all_paths:
831+
rpath_dirs_to_remove.add(rp.encode('utf8'))
830832
args.extend(self._apply_prefix('-rpath,' + rp))
831833

832-
return (args, set())
834+
return (args, rpath_dirs_to_remove)
833835

834836
def get_thinlto_cache_args(self, path: str) -> T.List[str]:
835837
return ["-Wl,-cache_path_lto," + path]
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#include "foo/foo.h"
2+
3+
void bar() {
4+
foo();
5+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
int foo() {
2+
return 1 + 2;
3+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
int foo();
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
foo = library('foo', 'foo.c',
2+
install: true,
3+
)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
project('proj', 'c')
2+
3+
subdir('foo')
4+
5+
bar = library('bar', 'bar.c',
6+
link_with: foo,
7+
install: true,
8+
)

unittests/baseplatformtests.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ def setUp(self):
7878
self.linuxlike_test_dir = os.path.join(src_root, 'test cases/linuxlike')
7979
self.objc_test_dir = os.path.join(src_root, 'test cases/objc')
8080
self.objcpp_test_dir = os.path.join(src_root, 'test cases/objcpp')
81+
self.darwin_test_dir = os.path.join(src_root, 'test cases/darwin')
8182

8283
# Misc stuff
8384
self.orig_env = os.environ.copy()

unittests/darwintests.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,12 @@ def _get_darwin_versions(self, fname):
100100
self.assertIsNotNone(m, msg=out)
101101
return m.groups()
102102

103+
def _get_darwin_rpaths(self, fname: str) -> T.List[str]:
104+
out = subprocess.check_output(['otool', '-l', fname], universal_newlines=True)
105+
pattern = re.compile(r'path (.*) \(offset \d+\)')
106+
rpaths = pattern.findall(out)
107+
return rpaths
108+
103109
@skipIfNoPkgconfig
104110
def test_library_versioning(self):
105111
'''
@@ -154,3 +160,15 @@ def test_darwin_get_object_archs(self):
154160
from mesonbuild.mesonlib import darwin_get_object_archs
155161
archs = darwin_get_object_archs('/bin/cat')
156162
self.assertEqual(archs, ['x86_64', 'aarch64'])
163+
164+
def test_darwin_meson_rpaths_removed_on_install(self):
165+
testdir = os.path.join(self.darwin_test_dir, '1 rpath removal on install')
166+
self.init(testdir)
167+
self.build()
168+
# Meson-created RPATHs are usually only valid in the build directory
169+
rpaths = self._get_darwin_rpaths(os.path.join(self.builddir, 'libbar.dylib'))
170+
self.assertListEqual(rpaths, ['@loader_path/foo'])
171+
self.install()
172+
# Those RPATHs are no longer valid and should not be present after installation
173+
rpaths = self._get_darwin_rpaths(os.path.join(self.installdir, 'usr/lib/libbar.dylib'))
174+
self.assertListEqual(rpaths, [])

0 commit comments

Comments
 (0)