Skip to content

Commit

Permalink
Fix compiler/linker interface assumptions for swiftc
Browse files Browse the repository at this point in the history
Not all compilers (swiftc in this case) concatenate linker arguments
with ','. This removes that assumption and instead always passes the
arguments in a list where applicable.

Some Apple ld arguments, notably -install_name, are also not exposed
directly on the compiler options interface, hence add the linker
prefix here.
  • Loading branch information
2xsaiko committed Mar 1, 2025
1 parent be6540e commit 38be825
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 18 deletions.
7 changes: 4 additions & 3 deletions mesonbuild/compilers/rust.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,15 +205,16 @@ def get_optimization_args(self, optimization_level: str) -> T.List[str]:
def build_rpath_args(self, env: 'Environment', build_dir: str, from_dir: str,
rpath_paths: T.Tuple[str, ...], build_rpath: str,
install_rpath: str) -> T.Tuple[T.List[str], T.Set[bytes]]:
# add rustc's sysroot to account for rustup installations
rpath_paths = tuple(f'{path}:{self.get_target_libdir()}' for path in rpath_paths)

args, to_remove = super().build_rpath_args(env, build_dir, from_dir, rpath_paths,
build_rpath, install_rpath)

# ... but then add rustc's sysroot to account for rustup
# installations
rustc_rpath_args = []
for arg in args:
rustc_rpath_args.append('-C')
rustc_rpath_args.append(f'link-arg={arg}:{self.get_target_libdir()}')
rustc_rpath_args.append(f'link-arg={arg}')
return rustc_rpath_args, to_remove

def compute_parameters_with_absolute_paths(self, parameter_list: T.List[str],
Expand Down
26 changes: 13 additions & 13 deletions mesonbuild/linkers/linkers.py
Original file line number Diff line number Diff line change
Expand Up @@ -689,7 +689,7 @@ def get_soname_args(self, env: 'Environment', prefix: str, shlib_name: str,
# For PE/COFF the soname argument has no effect
return []
sostr = '' if soversion is None else '.' + soversion
return self._apply_prefix(f'-soname,{prefix}{shlib_name}.{suffix}{sostr}')
return self._apply_prefix(['-soname', f'{prefix}{shlib_name}.{suffix}{sostr}'])

def build_rpath_args(self, env: 'Environment', build_dir: str, from_dir: str,
rpath_paths: T.Tuple[str, ...], build_rpath: str,
Expand Down Expand Up @@ -722,7 +722,7 @@ def build_rpath_args(self, env: 'Environment', build_dir: str, from_dir: str,
# by default, but is not on dragonfly/openbsd for some reason. Without this
# $ORIGIN in the runtime path will be undefined and any binaries
# linked against local libraries will fail to resolve them.
args.extend(self._apply_prefix('-z,origin'))
args.extend(self._apply_prefix(['-z', 'origin']))

# In order to avoid relinking for RPATH removal, the binary needs to contain just
# enough space in the ELF header to hold the final installation RPATH.
Expand All @@ -735,7 +735,7 @@ def build_rpath_args(self, env: 'Environment', build_dir: str, from_dir: str,
paths = padding
else:
paths = paths + ':' + padding
args.extend(self._apply_prefix('-rpath,' + paths))
args.extend(self._apply_prefix(['-rpath', paths]))

# TODO: should this actually be "for solaris/sunos"?
# NOTE: Remove the zigcc check once zig support "-rpath-link"
Expand All @@ -759,7 +759,7 @@ def build_rpath_args(self, env: 'Environment', build_dir: str, from_dir: str,
#
# -Wl,-rpath-link,/path/to/folder1:/path/to/folder2:...
for p in rpath_paths:
args.extend(self._apply_prefix('-rpath-link,' + os.path.join(build_dir, p)))
args.extend(self._apply_prefix(['-rpath-link', os.path.join(build_dir, p)]))

return (args, rpath_dirs_to_remove)

Expand All @@ -776,7 +776,7 @@ def get_win_subsystem_args(self, value: str) -> T.List[str]:
if newvalue is not None:
if versionsuffix is not None:
newvalue += f':{versionsuffix}'
args = [f'--subsystem,{newvalue}']
args = ['--subsystem', newvalue]
else:
raise mesonlib.MesonBugException(f'win_subsystem: {value!r} not handled in MinGW linker. This should not be possible.')

Expand All @@ -793,10 +793,10 @@ def get_asneeded_args(self) -> T.List[str]:
return self._apply_prefix('-dead_strip_dylibs')

def get_allow_undefined_args(self) -> T.List[str]:
return self._apply_prefix('-undefined,dynamic_lookup')
return self._apply_prefix(['-undefined', 'dynamic_lookup'])

def get_std_shared_module_args(self, target: 'BuildTarget') -> T.List[str]:
return ['-bundle'] + self._apply_prefix('-undefined,dynamic_lookup')
return ['-bundle'] + self._apply_prefix(['-undefined', 'dynamic_lookup'])

def get_pie_args(self) -> T.List[str]:
return []
Expand Down Expand Up @@ -846,7 +846,7 @@ def get_soname_args(self, env: 'Environment', prefix: str, shlib_name: str,
if darwin_versions:
args.extend(['-compatibility_version', darwin_versions[0],
'-current_version', darwin_versions[1]])
return args
return self._apply_prefix(args)

def build_rpath_args(self, env: 'Environment', build_dir: str, from_dir: str,
rpath_paths: T.Tuple[str, ...], build_rpath: str,
Expand All @@ -864,12 +864,12 @@ def build_rpath_args(self, env: 'Environment', build_dir: str, from_dir: str,
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))
args.extend(self._apply_prefix(['-rpath', rp]))

return (args, rpath_dirs_to_remove)

def get_thinlto_cache_args(self, path: str) -> T.List[str]:
return ["-Wl,-cache_path_lto," + path]
return self._apply_prefix(['-cache_path_lto', path])

def export_dynamic_args(self, env: 'Environment') -> T.List[str]:
if mesonlib.version_compare(self.version, '>=224.1'):
Expand All @@ -892,7 +892,7 @@ class GnuGoldDynamicLinker(GnuDynamicLinker):
id = 'ld.gold'

def get_thinlto_cache_args(self, path: str) -> T.List[str]:
return ['-Wl,-plugin-opt,cache-dir=' + path]
return self._apply_prefix(['-plugin-opt', 'cache-dir=' + path])


class GnuBFDDynamicLinker(GnuDynamicLinker):
Expand All @@ -905,7 +905,7 @@ class MoldDynamicLinker(GnuDynamicLinker):
id = 'ld.mold'

def get_thinlto_cache_args(self, path: str) -> T.List[str]:
return ['-Wl,--thinlto-cache-dir=' + path]
return self._apply_prefix(['--thinlto-cache-dir=' + path])


class LLVMDynamicLinker(GnuLikeDynamicLinkerMixin, PosixDynamicLinkerMixin, DynamicLinker):
Expand Down Expand Up @@ -955,7 +955,7 @@ def no_undefined_args(self) -> T.List[str]:
return []

def get_thinlto_cache_args(self, path: str) -> T.List[str]:
return ['-Wl,--thinlto-cache-dir=' + path]
return self._apply_prefix(['--thinlto-cache-dir=' + path])

def get_win_subsystem_args(self, value: str) -> T.List[str]:
# lld does not support a numeric subsystem value
Expand Down
4 changes: 2 additions & 2 deletions unittests/linuxliketests.py
Original file line number Diff line number Diff line change
Expand Up @@ -1284,9 +1284,9 @@ def test_deterministic_rpath_order(self):
testdir = os.path.join(self.unit_test_dir, '41 rpath order')
self.init(testdir)
if is_osx():
rpathre = re.compile(r'-rpath,.*/subprojects/sub1.*-rpath,.*/subprojects/sub2')
rpathre = re.compile(r'-Wl,-rpath -Wl,.*/subprojects/sub1.*-Wl,-rpath -Wl,.*/subprojects/sub2')
else:
rpathre = re.compile(r'-rpath,\$\$ORIGIN/subprojects/sub1:\$\$ORIGIN/subprojects/sub2')
rpathre = re.compile(r'-Wl,-rpath -Wl,\$\$ORIGIN/subprojects/sub1:\$\$ORIGIN/subprojects/sub2')
with open(os.path.join(self.builddir, 'build.ninja'), encoding='utf-8') as bfile:
for line in bfile:
if '-rpath' in line:
Expand Down

0 comments on commit 38be825

Please sign in to comment.