linkers: Fix AppleDynamicLinker not returning any rpaths to remove

Fixes regression from commit 78e9009ff9.

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.

(cherry picked from commit dc1b4be6be)
1.4
Piotr Brzeziński 8 months ago committed by Eli Schwartz
parent 7eea0c4e55
commit 51d27b5c5c
No known key found for this signature in database
GPG Key ID: CEB167EFB5722BD6
  1. 6
      mesonbuild/linkers/linkers.py
  2. 5
      test cases/darwin/1 rpath removal on install/bar.c
  3. 3
      test cases/darwin/1 rpath removal on install/foo/foo.c
  4. 1
      test cases/darwin/1 rpath removal on install/foo/foo.h
  5. 3
      test cases/darwin/1 rpath removal on install/foo/meson.build
  6. 8
      test cases/darwin/1 rpath removal on install/meson.build
  7. 1
      unittests/baseplatformtests.py
  8. 18
      unittests/darwintests.py

@ -816,17 +816,19 @@ class AppleDynamicLinker(PosixDynamicLinkerMixin, DynamicLinker):
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]

@ -0,0 +1,5 @@
#include "foo/foo.h"
void bar() {
foo();
}

@ -0,0 +1,3 @@
foo = library('foo', 'foo.c',
install: true,
)

@ -0,0 +1,8 @@
project('proj', 'c')
subdir('foo')
bar = library('bar', 'bar.c',
link_with: foo,
install: true,
)

@ -78,6 +78,7 @@ class BasePlatformTests(TestCase):
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()

@ -88,6 +88,12 @@ class DarwinTests(BasePlatformTests):
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):
'''
@ -142,3 +148,15 @@ class DarwinTests(BasePlatformTests):
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, [])

Loading…
Cancel
Save