Skip to content

Commit

Permalink
environment: Use arguments specified in machine files when detecting …
Browse files Browse the repository at this point in the history
…linkers

There are at least two cases that we could run into here, one is someone
could use an argument -fuse-ld=...; which would cause is to misdetect
the linker being used. The other is that someone could use clang
--target=, which will cause clang to use a different linker than without
--target=; causing more mis-detection.

Fixes mesonbuild#6057
  • Loading branch information
dcbaker committed Oct 17, 2019
1 parent e6bafea commit a831d00
Showing 1 changed file with 28 additions and 16 deletions.
44 changes: 28 additions & 16 deletions mesonbuild/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -755,9 +755,8 @@ def _guess_win_linker(compiler: typing.List[str], for_machine: MachineChoice,
version=search_version(o))
raise MesonException('Cannot guess dynamic linker')

@staticmethod
def _guess_nix_linker(compiler: typing.List[str], for_machine: MachineChoice,
prefix: typing.Union[str, typing.List[str]], *,
def _guess_nix_linker(self, compiler: typing.List[str], for_machine: MachineChoice,
prefix: typing.Union[str, typing.List[str]], lang: str, *,
extra_args: typing.Optional[typing.List[str]] = None) -> 'DynamicLinker':
"""Helper for guessing what linker to use on Unix-Like OSes.
Expand All @@ -771,6 +770,15 @@ def _guess_nix_linker(compiler: typing.List[str], for_machine: MachineChoice,
:extra_args: Any addtional arguments rquired (such as a source file)
"""
extra_args = typing.cast(typing.List[str], extra_args or [])

# We aditionally need to use the arguments in the cross/native file, as
# they may affect the linker chosen: https://github.com/mesonbuild/meson/issues/6057
#
# TODO: We should also check the environment variables, but there isn't
# a good way to do that, since that's tied up in the Compiler.
extra_args.extend(self.properties[for_machine].get(lang + '_args', []))
extra_args.extend(self.properties[for_machine].get(lang + '_link_args', []))

if isinstance(prefix, str):
check_args = [prefix + '--version'] + extra_args
else:
Expand Down Expand Up @@ -893,7 +901,7 @@ def sanitize(p):
version = self.get_gnu_version_from_defines(defines)
cls = GnuCCompiler if lang == 'c' else GnuCPPCompiler

linker = self._guess_nix_linker(compiler, for_machine, cls.LINKER_PREFIX)
linker = self._guess_nix_linker(compiler, for_machine, cls.LINKER_PREFIX, lang)
return cls(
ccache + compiler, version, for_machine, is_cross,
info, exe_wrap, defines, full_version=full_version,
Expand Down Expand Up @@ -962,7 +970,7 @@ def sanitize(p):
except MesonException:
pass
if linker is None:
linker = self._guess_nix_linker(compiler, for_machine, cls.LINKER_PREFIX)
linker = self._guess_nix_linker(compiler, for_machine, cls.LINKER_PREFIX, lang)

return cls(
ccache + compiler, version, for_machine, is_cross, info,
Expand Down Expand Up @@ -1106,23 +1114,23 @@ def detect_fortran_compiler(self, for_machine: MachineChoice):
version = self.get_gnu_version_from_defines(defines)
cls = GnuFortranCompiler
linker = self._guess_nix_linker(
compiler, for_machine, cls.LINKER_PREFIX)
compiler, for_machine, cls.LINKER_PREFIX, 'fortran')
return cls(
compiler, version, for_machine, is_cross, info,
exe_wrap, defines, full_version=full_version,
linker=linker)

if 'G95' in out:
linker = self._guess_nix_linker(
compiler, for_machine, cls.LINKER_PREFIX)
compiler, for_machine, cls.LINKER_PREFIX, 'fortran')
return G95FortranCompiler(
compiler, version, for_machine, is_cross, info,
exe_wrap, full_version=full_version, linker=linker)

if 'Sun Fortran' in err:
version = search_version(err)
linker = self._guess_nix_linker(
compiler, for_machine, cls.LINKER_PREFIX)
compiler, for_machine, cls.LINKER_PREFIX, 'fortran')
return SunFortranCompiler(
compiler, version, for_machine, is_cross, info,
exe_wrap, full_version=full_version, linker=linker)
Expand Down Expand Up @@ -1158,21 +1166,21 @@ def detect_fortran_compiler(self, for_machine: MachineChoice):

if 'flang' in out or 'clang' in out:
linker = self._guess_nix_linker(
compiler, for_machine, FlangFortranCompiler.LINKER_PREFIX)
compiler, for_machine, FlangFortranCompiler.LINKER_PREFIX, 'fortran')
return FlangFortranCompiler(
compiler, version, for_machine, is_cross, info,
exe_wrap, full_version=full_version, linker=linker)

if 'Open64 Compiler Suite' in err:
linker = self._guess_nix_linker(
compiler, for_machine, Open64FortranCompiler.LINKER_PREFIX)
compiler, for_machine, Open64FortranCompiler.LINKER_PREFIX, 'fortran')
return Open64FortranCompiler(
compiler, version, for_machine, is_cross, info,
exe_wrap, full_version=full_version, linker=linker)

if 'NAG Fortran' in err:
linker = self._guess_nix_linker(
compiler, for_machine, NAGFortranCompiler.LINKER_PREFIX)
compiler, for_machine, NAGFortranCompiler.LINKER_PREFIX, 'fortran')
return NAGFortranCompiler(
compiler, version, for_machine, is_cross, info,
exe_wrap, full_version=full_version, linker=linker)
Expand All @@ -1188,9 +1196,10 @@ def detect_objc_compiler(self, for_machine: MachineInfo) -> 'Compiler':
def detect_objcpp_compiler(self, for_machine: MachineInfo) -> 'Compiler':
return self._detect_objc_or_objcpp_compiler(for_machine, False)

def _detect_objc_or_objcpp_compiler(self, for_machine: MachineInfo, objc: bool) -> 'Compiler':
def _detect_objc_or_objcpp_compiler(self, for_machine: MachineChoice, objc: bool) -> 'Compiler':
popen_exceptions = {}
compilers, ccache, exe_wrap = self._get_compilers('objc' if objc else 'objcpp', for_machine)
lang = 'objc' if objc else 'objcpp'
compilers, ccache, exe_wrap = self._get_compilers(lang, for_machine)
is_cross = not self.machines.matches_build_machine(for_machine)
info = self.machines[for_machine]

Expand All @@ -1211,7 +1220,7 @@ def _detect_objc_or_objcpp_compiler(self, for_machine: MachineInfo, objc: bool)
continue
version = self.get_gnu_version_from_defines(defines)
comp = GnuObjCCompiler if objc else GnuObjCPPCompiler
linker = self._guess_nix_linker(compiler, for_machine, comp.LINKER_PREFIX)
linker = self._guess_nix_linker(compiler, for_machine, comp.LINKER_PREFIX, lang)
return comp(
ccache + compiler, version, for_machine, is_cross, info,
exe_wrap, defines, linker=linker)
Expand All @@ -1227,7 +1236,7 @@ def _detect_objc_or_objcpp_compiler(self, for_machine: MachineInfo, objc: bool)

if not linker:
linker = self._guess_nix_linker(
compiler, for_machine, comp.LINKER_PREFIX)
compiler, for_machine, comp.LINKER_PREFIX, lang)
return comp(
ccache + compiler, version, for_machine,
is_cross, info, exe_wrap, linker=linker)
Expand Down Expand Up @@ -1381,12 +1390,13 @@ def detect_d_compiler(self, for_machine: MachineChoice):
linker = self._guess_nix_linker(
exelist, for_machine,
compilers.LLVMDCompiler.LINKER_PREFIX,
'd',
extra_args=[f.name])
return compilers.LLVMDCompiler(
exelist, version, for_machine, info, arch,
full_version=full_version, linker=linker)
elif 'gdc' in out:
linker = self._guess_nix_linker(exelist, for_machine, compilers.GnuDCompiler.LINKER_PREFIX)
linker = self._guess_nix_linker(exelist, for_machine, compilers.GnuDCompiler.LINKER_PREFIX, 'd')
return compilers.GnuDCompiler(
exelist, version, for_machine, info, arch,
full_version=full_version, linker=linker)
Expand All @@ -1400,6 +1410,7 @@ def detect_d_compiler(self, for_machine: MachineChoice):
linker = self._guess_nix_linker(
exelist, for_machine,
compilers.LLVMDCompiler.LINKER_PREFIX,
'd',
extra_args=[f.name])
return compilers.DmdDCompiler(
exelist, version, for_machine, info, arch,
Expand All @@ -1425,6 +1436,7 @@ def detect_swift_compiler(self, for_machine):
linker = self._guess_nix_linker(
exelist, for_machine,
compilers.SwiftCompiler.LINKER_PREFIX,
'swift',
extra_args=[f.name])
return compilers.SwiftCompiler(
exelist, version, for_machine, info, is_cross, linker=linker)
Expand Down

0 comments on commit a831d00

Please sign in to comment.