Skip to content

Commit

Permalink
linkers: Fix AppleDynamicLinker not returning any rpaths to remove
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
thewildtree authored and eli-schwartz committed Jun 30, 2024
1 parent 7b43a2e commit dc1b4be
Show file tree
Hide file tree
Showing 8 changed files with 43 additions and 2 deletions.
6 changes: 4 additions & 2 deletions mesonbuild/linkers/linkers.py
Original file line number Diff line number Diff line change
Expand Up @@ -819,17 +819,19 @@ def build_rpath_args(self, env: 'Environment', build_dir: str, from_dir: str,
if not rpath_paths and not install_rpath and not build_rpath:
return ([], set())
args: T.List[str] = []
rpath_dirs_to_remove: T.Set[bytes] = set()
# @loader_path is the equivalent of $ORIGIN on macOS
# https://stackoverflow.com/q/26280738
origin_placeholder = '@loader_path'
processed_rpaths = prepare_rpaths(rpath_paths, build_dir, from_dir)
all_paths = mesonlib.OrderedSet([os.path.join(origin_placeholder, p) for p in processed_rpaths])
if build_rpath != '':
all_paths.add(build_rpath)
all_paths.update(build_rpath.split(':'))
for rp in all_paths:
rpath_dirs_to_remove.add(rp.encode('utf8'))
args.extend(self._apply_prefix('-rpath,' + rp))

return (args, set())
return (args, rpath_dirs_to_remove)

def get_thinlto_cache_args(self, path: str) -> T.List[str]:
return ["-Wl,-cache_path_lto," + path]
Expand Down
5 changes: 5 additions & 0 deletions test cases/darwin/1 rpath removal on install/bar.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#include "foo/foo.h"

void bar() {
foo();
}
3 changes: 3 additions & 0 deletions test cases/darwin/1 rpath removal on install/foo/foo.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
int foo() {
return 1 + 2;
}
1 change: 1 addition & 0 deletions test cases/darwin/1 rpath removal on install/foo/foo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
int foo();
3 changes: 3 additions & 0 deletions test cases/darwin/1 rpath removal on install/foo/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
foo = library('foo', 'foo.c',
install: true,
)
8 changes: 8 additions & 0 deletions test cases/darwin/1 rpath removal on install/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
project('proj', 'c')

subdir('foo')

bar = library('bar', 'bar.c',
link_with: foo,
install: true,
)
1 change: 1 addition & 0 deletions unittests/baseplatformtests.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ def setUp(self):
self.linuxlike_test_dir = os.path.join(src_root, 'test cases/linuxlike')
self.objc_test_dir = os.path.join(src_root, 'test cases/objc')
self.objcpp_test_dir = os.path.join(src_root, 'test cases/objcpp')
self.darwin_test_dir = os.path.join(src_root, 'test cases/darwin')

# Misc stuff
self.orig_env = os.environ.copy()
Expand Down
18 changes: 18 additions & 0 deletions unittests/darwintests.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,12 @@ def _get_darwin_versions(self, fname):
self.assertIsNotNone(m, msg=out)
return m.groups()

def _get_darwin_rpaths(self, fname: str) -> T.List[str]:
out = subprocess.check_output(['otool', '-l', fname], universal_newlines=True)
pattern = re.compile(r'path (.*) \(offset \d+\)')
rpaths = pattern.findall(out)
return rpaths

@skipIfNoPkgconfig
def test_library_versioning(self):
'''
Expand Down Expand Up @@ -154,3 +160,15 @@ def test_darwin_get_object_archs(self):
from mesonbuild.mesonlib import darwin_get_object_archs
archs = darwin_get_object_archs('/bin/cat')
self.assertEqual(archs, ['x86_64', 'aarch64'])

def test_darwin_meson_rpaths_removed_on_install(self):
testdir = os.path.join(self.darwin_test_dir, '1 rpath removal on install')
self.init(testdir)
self.build()
# Meson-created RPATHs are usually only valid in the build directory
rpaths = self._get_darwin_rpaths(os.path.join(self.builddir, 'libbar.dylib'))
self.assertListEqual(rpaths, ['@loader_path/foo'])
self.install()
# Those RPATHs are no longer valid and should not be present after installation
rpaths = self._get_darwin_rpaths(os.path.join(self.installdir, 'usr/lib/libbar.dylib'))
self.assertListEqual(rpaths, [])

0 comments on commit dc1b4be

Please sign in to comment.