Skip to content

Commit 3345c31

Browse files
committed
[WIP] Restore usage of macOS @rpath
1 parent a145d86 commit 3345c31

2 files changed

Lines changed: 42 additions & 34 deletions

File tree

‎bfg9000/tools/cc/linker.py‎

Lines changed: 35 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -119,33 +119,44 @@ def _always_flags(self):
119119
return []
120120

121121
def _local_rpath(self, library, output):
122-
if ( not isinstance(library, Library) or
123-
self.builder.object_format != 'elf' ):
122+
if not isinstance(library, Library):
124123
return None, []
125-
126-
rpath = patchelf.local_rpath(self.env, library, output)
127-
if rpath is None:
124+
elif self.builder.object_format == 'elf':
125+
rpath = patchelf.local_rpath(self.env, library, output)
126+
if rpath is None:
127+
return None, []
128+
129+
# Prior to binutils 2.28, GNU's BFD-based ld doesn't correctly
130+
# respect $ORIGIN in a shared library's DT_RPATH/DT_RUNPATH field.
131+
# This results in ld being unable to find other shared libraries
132+
# needed by the directly-linked library. For more information, see:
133+
# <https://sourceware.org/bugzilla/show_bug.cgi?id=20535>.
134+
try:
135+
ld = self.builder.linker('raw')
136+
fix_rpath = (ld.brand == 'bfd' and ld.version in
137+
SpecifierSet('<2.28'))
138+
except KeyError:
139+
fix_rpath = False
140+
141+
rpath_link = []
142+
if output and fix_rpath:
143+
rpath_link = [
144+
i.path.parent() for i in
145+
recursive_walk(library.runtime_file, 'runtime_deps')
146+
]
147+
148+
return rpath, rpath_link
149+
elif self.builder.object_format == 'mach-o':
150+
if not library.runtime_file:
151+
return None, []
152+
rpath = Path('.', library.runtime_file.path.root).cross(self.env)
153+
if rpath.root == output.path.root:
154+
rpath = rpath.relpath(output.path.parent(),
155+
prefix='@loader_path')
156+
return rpath, []
157+
else:
128158
return None, []
129159

130-
# Prior to binutils 2.28, GNU's BFD-based ld doesn't correctly respect
131-
# $ORIGIN in a shared library's DT_RPATH/DT_RUNPATH field. This results
132-
# in ld being unable to find other shared libraries needed by the
133-
# directly-linked library. For more information, see:
134-
# <https://sourceware.org/bugzilla/show_bug.cgi?id=20535>.
135-
try:
136-
ld = self.builder.linker('raw')
137-
fix_rpath = (ld.brand == 'bfd' and ld.version in
138-
SpecifierSet('<2.28'))
139-
except KeyError:
140-
fix_rpath = False
141-
142-
rpath_link = []
143-
if output and fix_rpath:
144-
rpath_link = [i.path.parent() for i in
145-
recursive_walk(library.runtime_file, 'runtime_deps')]
146-
147-
return rpath, rpath_link
148-
149160
def always_libs(self, primary):
150161
# XXX: Don't just asssume that these are the right libraries to use.
151162
# For instance, clang users might want to use libc++ instead.

‎bfg9000/tools/install_name_tool.py‎

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import os
2+
13
from . import tool
24
from .. import file_types, options as opts
35
from .common import SimpleCommand
@@ -25,18 +27,13 @@ def _call(self, cmd, file, *, id=None, changes=[]):
2527

2628

2729
def darwin_install_name(library, env, strict=True):
28-
while isinstance(library, file_types.LinkLibrary):
29-
library = library.library
30-
31-
if isinstance(library, file_types.VersionedSharedLibrary):
32-
return library.soname.path.string(env.base_dirs)
33-
elif isinstance(library, file_types.SharedLibrary):
34-
return library.path.string(env.base_dirs)
35-
elif strict: # pragma: no cover
36-
raise TypeError('unable to create darwin install_name')
37-
else:
30+
if isinstance(library, file_types.SharedLibrary):
31+
return os.path.join('@rpath', library.runtime_file.path.suffix)
32+
elif not strict:
3833
return None
3934

35+
raise TypeError('unable to create darwin install_name') # pragma: no cover
36+
4037

4138
def post_install(env, options, output, install_db, *, is_library=False):
4239
change_opts = options.filter(opts.install_name_change)

0 commit comments

Comments
 (0)