|
|
|
@ -733,55 +733,85 @@ class Environment: |
|
|
|
|
errmsg += '\nRunning "{0}" gave "{1}"'.format(c, e) |
|
|
|
|
raise EnvironmentException(errmsg) |
|
|
|
|
|
|
|
|
|
@staticmethod |
|
|
|
|
def _guess_win_linker(compiler: typing.List[str], for_machine: MachineChoice, |
|
|
|
|
prefix: typing.Union[str, typing.List[str]]) -> 'DynamicLinker': |
|
|
|
|
def _guess_win_linker(self, compiler: typing.List[str], comp_class: Compiler, |
|
|
|
|
for_machine: MachineChoice, |
|
|
|
|
prefix: typing.Union[str, typing.List[str]], |
|
|
|
|
*, use_linker_prefix: bool = True) -> 'DynamicLinker': |
|
|
|
|
# Explicitly pass logo here so that we can get the version of link.exe |
|
|
|
|
if isinstance(prefix, str): |
|
|
|
|
check_args = [prefix + '/logo', prefix + '--version'] |
|
|
|
|
else: |
|
|
|
|
check_args = prefix + ['/logo'] + prefix + ['--version'] |
|
|
|
|
if not use_linker_prefix or comp_class.LINKER_PREFIX is None: |
|
|
|
|
check_args = ['/logo', '--version'] |
|
|
|
|
elif isinstance(comp_class.LINKER_PREFIX, str): |
|
|
|
|
check_args = [comp_class.LINKER_PREFIX + '/logo', comp_class.LINKER_PREFIX + '--version'] |
|
|
|
|
elif isinstance(comp_class.LINKER_PREFIX, list): |
|
|
|
|
check_args = comp_class.LINKER_PREFIX + ['/logo'] + comp_class.LINKER_PREFIX + ['--version'] |
|
|
|
|
|
|
|
|
|
override = [] # type: typing.List[str] |
|
|
|
|
value = self.binaries[for_machine].lookup_entry('ld') |
|
|
|
|
if value is not None: |
|
|
|
|
override = comp_class.use_linker_args(value[0]) |
|
|
|
|
check_args += override |
|
|
|
|
|
|
|
|
|
p, o, _ = Popen_safe(compiler + check_args) |
|
|
|
|
if o.startswith('LLD'): |
|
|
|
|
if '(compatible with GNU linkers)' in o: |
|
|
|
|
return LLVMDynamicLinker(compiler, for_machine, 'lld', prefix, version=search_version(o)) |
|
|
|
|
else: |
|
|
|
|
return ClangClDynamicLinker(for_machine, exelist=compiler, prefix=prefix, version=search_version(o)) |
|
|
|
|
elif o.startswith('Microsoft'): |
|
|
|
|
match = re.search(r'.*(X86|X64|ARM|ARM64).*', o) |
|
|
|
|
return LLVMDynamicLinker( |
|
|
|
|
compiler, for_machine, 'lld', comp_class.LINKER_PREFIX, |
|
|
|
|
override, version=search_version(o)) |
|
|
|
|
|
|
|
|
|
if value is not None: |
|
|
|
|
compiler = value |
|
|
|
|
|
|
|
|
|
p, o, e = Popen_safe(compiler + check_args) |
|
|
|
|
if o.startswith('LLD'): |
|
|
|
|
return ClangClDynamicLinker( |
|
|
|
|
for_machine, [], |
|
|
|
|
prefix=comp_class.LINKER_PREFIX if use_linker_prefix else [], |
|
|
|
|
exelist=compiler, version=search_version(o)) |
|
|
|
|
elif 'OPTLINK' in o: |
|
|
|
|
# Opltink's stdout *may* beging with a \r character. |
|
|
|
|
return OptlinkDynamicLinker(for_machine, version=search_version(o)) |
|
|
|
|
elif o.startswith('Microsoft') or e.startswith('Microsoft'): |
|
|
|
|
out = o or e |
|
|
|
|
match = re.search(r'.*(X86|X64|ARM|ARM64).*', out) |
|
|
|
|
if match: |
|
|
|
|
target = str(match.group(1)) |
|
|
|
|
else: |
|
|
|
|
target = 'x86' |
|
|
|
|
|
|
|
|
|
return MSVCDynamicLinker( |
|
|
|
|
for_machine, machine=target, exelist=compiler, prefix=prefix, |
|
|
|
|
version=search_version(o)) |
|
|
|
|
raise MesonException('Cannot guess dynamic linker') |
|
|
|
|
for_machine, [], machine=target, exelist=compiler, |
|
|
|
|
prefix=comp_class.LINKER_PREFIX if use_linker_prefix else [], |
|
|
|
|
version=search_version(out)) |
|
|
|
|
raise EnvironmentException('Unable to determine dynamic linker') |
|
|
|
|
|
|
|
|
|
@staticmethod |
|
|
|
|
def _guess_nix_linker(compiler: typing.List[str], for_machine: MachineChoice, |
|
|
|
|
def _guess_nix_linker(self, compiler: typing.List[str], comp_class: typing.Type[Compiler], |
|
|
|
|
for_machine: MachineChoice, |
|
|
|
|
prefix: typing.Union[str, typing.List[str]], *, |
|
|
|
|
extra_args: typing.Optional[typing.List[str]] = None) -> 'DynamicLinker': |
|
|
|
|
"""Helper for guessing what linker to use on Unix-Like OSes. |
|
|
|
|
|
|
|
|
|
:prefix: The prefix that the compiler uses to proxy arguments to the |
|
|
|
|
linker, if required. This can be passed as a string or a list of |
|
|
|
|
strings. If it is passed as a string then the arguments to be |
|
|
|
|
proxied to the linker will be concatenated, if it is a list they |
|
|
|
|
will be appended. This means that if a space is required (such as |
|
|
|
|
with swift which wants `-Xlinker --version` and *not* |
|
|
|
|
`-Xlinker=--version`) you must pass as a list. |
|
|
|
|
:compiler: Invocation to use to get linker |
|
|
|
|
:comp_class: The Compiler Type (uninstantiated) |
|
|
|
|
:for_machine: which machine this linker targets |
|
|
|
|
:extra_args: Any additional arguments required (such as a source file) |
|
|
|
|
""" |
|
|
|
|
extra_args = typing.cast(typing.List[str], extra_args or []) |
|
|
|
|
|
|
|
|
|
if isinstance(prefix, str): |
|
|
|
|
check_args = [prefix + '--version'] + extra_args |
|
|
|
|
else: |
|
|
|
|
check_args = prefix + ['--version'] + extra_args |
|
|
|
|
|
|
|
|
|
override = [] # type: typing.List[str] |
|
|
|
|
value = self.binaries[for_machine].lookup_entry('ld') |
|
|
|
|
if value is not None: |
|
|
|
|
override = comp_class.use_linker_args(value[0]) |
|
|
|
|
check_args += override |
|
|
|
|
|
|
|
|
|
_, o, e = Popen_safe(compiler + check_args) |
|
|
|
|
v = search_version(o) |
|
|
|
|
if o.startswith('LLD'): |
|
|
|
|
linker = LLVMDynamicLinker(compiler, for_machine, 'lld', prefix, version=v) # type: DynamicLinker |
|
|
|
|
linker = LLVMDynamicLinker(compiler, for_machine, 'lld', prefix, override, version=v) # type: DynamicLinker |
|
|
|
|
elif e.startswith('lld-link: '): |
|
|
|
|
# Toolchain wrapper got in the way; this happens with e.g. https://github.com/mstorsjo/llvm-mingw |
|
|
|
|
# Let's try to extract the linker invocation command to grab the version. |
|
|
|
@ -797,7 +827,7 @@ class Environment: |
|
|
|
|
_, o, e = Popen_safe([linker_cmd, '--version']) |
|
|
|
|
v = search_version(o) |
|
|
|
|
|
|
|
|
|
linker = LLVMDynamicLinker(compiler, for_machine, 'lld', prefix, version=v) |
|
|
|
|
linker = LLVMDynamicLinker(compiler, for_machine, 'lld', prefix, override, version=v) |
|
|
|
|
# first is for apple clang, second is for real gcc |
|
|
|
|
elif e.endswith('(use -v to see invocation)\n') or 'macosx_version' in e: |
|
|
|
|
if isinstance(prefix, str): |
|
|
|
@ -811,19 +841,19 @@ class Environment: |
|
|
|
|
break |
|
|
|
|
else: |
|
|
|
|
v = 'unknown version' |
|
|
|
|
linker = AppleDynamicLinker(compiler, for_machine, i, prefix, version=v) |
|
|
|
|
linker = AppleDynamicLinker(compiler, for_machine, i, prefix, override, version=v) |
|
|
|
|
elif 'GNU' in o: |
|
|
|
|
if 'gold' in o: |
|
|
|
|
i = 'GNU ld.gold' |
|
|
|
|
else: |
|
|
|
|
i = 'GNU ld.bfd' |
|
|
|
|
linker = GnuDynamicLinker(compiler, for_machine, i, prefix, version=v) |
|
|
|
|
linker = GnuDynamicLinker(compiler, for_machine, i, prefix, override, version=v) |
|
|
|
|
elif 'Solaris' in e or 'Solaris' in o: |
|
|
|
|
linker = SolarisDynamicLinker( |
|
|
|
|
compiler, for_machine, 'solaris', prefix, |
|
|
|
|
compiler, for_machine, 'solaris', prefix, override, |
|
|
|
|
version=search_version(e)) |
|
|
|
|
else: |
|
|
|
|
raise MesonException('Unable to determine dynamic linker.') |
|
|
|
|
raise EnvironmentException('Unable to determine dynamic linker') |
|
|
|
|
return linker |
|
|
|
|
|
|
|
|
|
def _detect_c_or_cpp_compiler(self, lang: str, for_machine: MachineChoice) -> Compiler: |
|
|
|
@ -898,7 +928,7 @@ class Environment: |
|
|
|
|
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, cls, for_machine, cls.LINKER_PREFIX) |
|
|
|
|
return cls( |
|
|
|
|
ccache + compiler, version, for_machine, is_cross, |
|
|
|
|
info, exe_wrap, defines, full_version=full_version, |
|
|
|
@ -925,7 +955,7 @@ class Environment: |
|
|
|
|
version = search_version(arm_ver_str) |
|
|
|
|
full_version = arm_ver_str |
|
|
|
|
cls = ArmclangCCompiler if lang == 'c' else ArmclangCPPCompiler |
|
|
|
|
linker = ArmClangDynamicLinker(for_machine, version=version) |
|
|
|
|
linker = ArmClangDynamicLinker(for_machine, [], version=version) |
|
|
|
|
return cls( |
|
|
|
|
ccache + compiler, version, for_machine, is_cross, info, |
|
|
|
|
exe_wrap, full_version=full_version, linker=linker) |
|
|
|
@ -944,7 +974,7 @@ class Environment: |
|
|
|
|
else: |
|
|
|
|
target = 'unknown target' |
|
|
|
|
cls = ClangClCCompiler if lang == 'c' else ClangClCPPCompiler |
|
|
|
|
linker = ClangClDynamicLinker(for_machine, version=version) |
|
|
|
|
linker = self._guess_win_linker(['lld-link'], cls, for_machine) |
|
|
|
|
return cls( |
|
|
|
|
compiler, version, for_machine, is_cross, info, exe_wrap, |
|
|
|
|
target, linker=linker) |
|
|
|
@ -963,11 +993,11 @@ class Environment: |
|
|
|
|
# style ld, but for clang on "real" windows we'll use |
|
|
|
|
# either link.exe or lld-link.exe |
|
|
|
|
try: |
|
|
|
|
linker = self._guess_win_linker(compiler, for_machine, cls.LINKER_PREFIX) |
|
|
|
|
linker = self._guess_win_linker(compiler, cls, for_machine, cls.LINKER_PREFIX) |
|
|
|
|
except MesonException: |
|
|
|
|
pass |
|
|
|
|
if linker is None: |
|
|
|
|
linker = self._guess_nix_linker(compiler, for_machine, cls.LINKER_PREFIX) |
|
|
|
|
linker = self._guess_nix_linker(compiler, cls, for_machine, cls.LINKER_PREFIX) |
|
|
|
|
|
|
|
|
|
return cls( |
|
|
|
|
ccache + compiler, version, for_machine, is_cross, info, |
|
|
|
@ -999,23 +1029,23 @@ class Environment: |
|
|
|
|
else: |
|
|
|
|
m = 'Failed to detect MSVC compiler target architecture: \'cl /?\' output is\n{}' |
|
|
|
|
raise EnvironmentException(m.format(cl_signature)) |
|
|
|
|
linker = MSVCDynamicLinker(for_machine, version=version) |
|
|
|
|
cls = VisualStudioCCompiler if lang == 'c' else VisualStudioCPPCompiler |
|
|
|
|
linker = self._guess_win_linker(['link'], cls, for_machine) |
|
|
|
|
return cls( |
|
|
|
|
compiler, version, for_machine, is_cross, info, exe_wrap, |
|
|
|
|
target, linker=linker) |
|
|
|
|
if 'PGI Compilers' in out: |
|
|
|
|
cls = PGICCompiler if lang == 'c' else PGICPPCompiler |
|
|
|
|
linker = PGIDynamicLinker(compiler, for_machine, 'pgi', cls.LINKER_PREFIX, version=version) |
|
|
|
|
linker = PGIDynamicLinker(compiler, for_machine, 'pgi', cls.LINKER_PREFIX, [], version=version) |
|
|
|
|
return cls( |
|
|
|
|
ccache + compiler, version, for_machine, is_cross, |
|
|
|
|
info, exe_wrap, linker=linker) |
|
|
|
|
if '(ICC)' in out: |
|
|
|
|
cls = IntelCCompiler if lang == 'c' else IntelCPPCompiler |
|
|
|
|
if self.machines[for_machine].is_darwin(): |
|
|
|
|
l = XildAppleDynamicLinker(compiler, for_machine, 'xild', cls.LINKER_PREFIX, version=version) |
|
|
|
|
l = XildAppleDynamicLinker(compiler, for_machine, 'xild', cls.LINKER_PREFIX, [], version=version) |
|
|
|
|
else: |
|
|
|
|
l = XildLinuxDynamicLinker(compiler, for_machine, 'xild', cls.LINKER_PREFIX, version=version) |
|
|
|
|
l = XildLinuxDynamicLinker(compiler, for_machine, 'xild', cls.LINKER_PREFIX, [], version=version) |
|
|
|
|
return cls( |
|
|
|
|
ccache + compiler, version, for_machine, is_cross, info, |
|
|
|
|
exe_wrap, full_version=full_version, linker=l) |
|
|
|
@ -1113,7 +1143,7 @@ class Environment: |
|
|
|
|
version = self.get_gnu_version_from_defines(defines) |
|
|
|
|
cls = GnuFortranCompiler |
|
|
|
|
linker = self._guess_nix_linker( |
|
|
|
|
compiler, for_machine, cls.LINKER_PREFIX) |
|
|
|
|
compiler, cls, for_machine, cls.LINKER_PREFIX) |
|
|
|
|
return cls( |
|
|
|
|
compiler, version, for_machine, is_cross, info, |
|
|
|
|
exe_wrap, defines, full_version=full_version, |
|
|
|
@ -1121,7 +1151,7 @@ class Environment: |
|
|
|
|
|
|
|
|
|
if 'G95' in out: |
|
|
|
|
linker = self._guess_nix_linker( |
|
|
|
|
compiler, for_machine, cls.LINKER_PREFIX) |
|
|
|
|
compiler, cls, for_machine, cls.LINKER_PREFIX) |
|
|
|
|
return G95FortranCompiler( |
|
|
|
|
compiler, version, for_machine, is_cross, info, |
|
|
|
|
exe_wrap, full_version=full_version, linker=linker) |
|
|
|
@ -1129,7 +1159,7 @@ class Environment: |
|
|
|
|
if 'Sun Fortran' in err: |
|
|
|
|
version = search_version(err) |
|
|
|
|
linker = self._guess_nix_linker( |
|
|
|
|
compiler, for_machine, cls.LINKER_PREFIX) |
|
|
|
|
compiler, cls, for_machine, cls.LINKER_PREFIX) |
|
|
|
|
return SunFortranCompiler( |
|
|
|
|
compiler, version, for_machine, is_cross, info, |
|
|
|
|
exe_wrap, full_version=full_version, linker=linker) |
|
|
|
@ -1137,14 +1167,14 @@ class Environment: |
|
|
|
|
if 'Intel(R) Visual Fortran' in err: |
|
|
|
|
version = search_version(err) |
|
|
|
|
target = 'x86' if 'IA-32' in err else 'x86_64' |
|
|
|
|
linker = XilinkDynamicLinker(for_machine, version=version) |
|
|
|
|
linker = XilinkDynamicLinker(for_machine, [], version=version) |
|
|
|
|
return IntelClFortranCompiler( |
|
|
|
|
compiler, version, for_machine, is_cross, target, |
|
|
|
|
info, exe_wrap, linker=linker) |
|
|
|
|
|
|
|
|
|
if 'ifort (IFORT)' in out: |
|
|
|
|
linker = XildLinuxDynamicLinker( |
|
|
|
|
compiler, for_machine, 'xild', IntelFortranCompiler.LINKER_PREFIX, version=version) |
|
|
|
|
compiler, for_machine, 'xild', IntelFortranCompiler.LINKER_PREFIX, [], version=version) |
|
|
|
|
return IntelFortranCompiler( |
|
|
|
|
compiler, version, for_machine, is_cross, info, |
|
|
|
|
exe_wrap, full_version=full_version, linker=linker) |
|
|
|
@ -1164,21 +1194,21 @@ class Environment: |
|
|
|
|
|
|
|
|
|
if 'flang' in out or 'clang' in out: |
|
|
|
|
linker = self._guess_nix_linker( |
|
|
|
|
compiler, for_machine, FlangFortranCompiler.LINKER_PREFIX) |
|
|
|
|
compiler, FlangFortranCompiler, for_machine, FlangFortranCompiler.LINKER_PREFIX) |
|
|
|
|
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, Open64FortranCompiler, for_machine, Open64FortranCompiler.LINKER_PREFIX) |
|
|
|
|
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, NAGFortranCompiler, for_machine, NAGFortranCompiler.LINKER_PREFIX) |
|
|
|
|
return NAGFortranCompiler( |
|
|
|
|
compiler, version, for_machine, is_cross, info, |
|
|
|
|
exe_wrap, full_version=full_version, linker=linker) |
|
|
|
@ -1217,7 +1247,7 @@ class Environment: |
|
|
|
|
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, comp, for_machine, comp.LINKER_PREFIX) |
|
|
|
|
return comp( |
|
|
|
|
ccache + compiler, version, for_machine, is_cross, info, |
|
|
|
|
exe_wrap, defines, linker=linker) |
|
|
|
@ -1227,13 +1257,13 @@ class Environment: |
|
|
|
|
if 'windows' in out or self.machines[for_machine].is_windows(): |
|
|
|
|
# If we're in a MINGW context this actually will use a gnu style ld |
|
|
|
|
try: |
|
|
|
|
linker = self._guess_win_linker(compiler, for_machine, comp.LINKER_PREFIX) |
|
|
|
|
linker = self._guess_win_linker(compiler, comp, for_machine, comp.LINKER_PREFIX) |
|
|
|
|
except MesonException: |
|
|
|
|
pass |
|
|
|
|
|
|
|
|
|
if not linker: |
|
|
|
|
linker = self._guess_nix_linker( |
|
|
|
|
compiler, for_machine, comp.LINKER_PREFIX) |
|
|
|
|
compiler, comp, for_machine, comp.LINKER_PREFIX) |
|
|
|
|
return comp( |
|
|
|
|
ccache + compiler, version, for_machine, |
|
|
|
|
is_cross, info, exe_wrap, linker=linker) |
|
|
|
@ -1316,19 +1346,36 @@ class Environment: |
|
|
|
|
version = search_version(out) |
|
|
|
|
|
|
|
|
|
if 'rustc' in out: |
|
|
|
|
# Chalk up another quirk for rust. There is no way (AFAICT) to |
|
|
|
|
# figure out what linker rustc is using for a non-nightly compiler |
|
|
|
|
# (On nightly you can pass -Z print-link-args). So we're going to |
|
|
|
|
# hard code the linker based on the platform. |
|
|
|
|
# Currently gnu ld is used for everything except apple by |
|
|
|
|
# default, and apple ld is used on mac. |
|
|
|
|
# TODO: find some better way to figure this out. |
|
|
|
|
if self.machines[for_machine].is_darwin(): |
|
|
|
|
linker = AppleDynamicLinker( |
|
|
|
|
[], for_machine, 'Apple ld', RustCompiler.LINKER_PREFIX) |
|
|
|
|
if info.is_windows() or info.is_cygwin(): |
|
|
|
|
# On windows rustc invokes link.exe |
|
|
|
|
linker = self._guess_win_linker(['link'], for_machine) |
|
|
|
|
else: |
|
|
|
|
linker = GnuDynamicLinker( |
|
|
|
|
[], for_machine, 'GNU ld', RustCompiler.LINKER_PREFIX) |
|
|
|
|
# On Linux and mac rustc will invoke gcc (clang for mac |
|
|
|
|
# presumably), for dynamic linking. this means the easiest |
|
|
|
|
# way to C compiler for dynamic linking. figure out what |
|
|
|
|
# linker to use !windows it to just get the value of the C |
|
|
|
|
# compiler and use that as the basis of the rust linker. |
|
|
|
|
# However, there are two things we need to change, if CC is |
|
|
|
|
# not the default use that, and second add the necessary |
|
|
|
|
# arguments to rust to use -fuse-ld |
|
|
|
|
cc = self.detect_c_compiler(for_machine) |
|
|
|
|
|
|
|
|
|
extra_args = [] |
|
|
|
|
if not ((info.is_darwin() and isinstance(cc, AppleClangCCompiler)) or |
|
|
|
|
isinstance(cc, GnuCCompiler)): |
|
|
|
|
c = cc.exelist[1] if cc.exelist[0].endswith('ccache') else cc.exelist[0] |
|
|
|
|
extra_args.extend(['-C', 'linker={}'.format(c)]) |
|
|
|
|
|
|
|
|
|
value = self.binaries[for_machine].lookup_entry('ld') |
|
|
|
|
if value is not None: |
|
|
|
|
for a in cc.use_linker_args(value[0]): |
|
|
|
|
extra_args.extend(['-C', 'link-arg={}'.format(a)]) |
|
|
|
|
|
|
|
|
|
# This trickery with type() gets us the class of the linker |
|
|
|
|
# so we can initialize a new copy for the Rust Compiler |
|
|
|
|
linker = type(cc.linker)(compiler, for_machine, cc.linker.id, cc.LINKER_PREFIX, |
|
|
|
|
always_args=extra_args, version=cc.linker.version) |
|
|
|
|
|
|
|
|
|
return RustCompiler( |
|
|
|
|
compiler, version, for_machine, is_cross, info, exe_wrap, |
|
|
|
|
linker=linker) |
|
|
|
@ -1375,26 +1422,25 @@ class Environment: |
|
|
|
|
# LDC seems to require a file |
|
|
|
|
m = self.machines[for_machine] |
|
|
|
|
if m.is_windows() or m.is_cygwin(): |
|
|
|
|
if is_msvc: |
|
|
|
|
linker = MSVCDynamicLinker(for_machine, version=version) |
|
|
|
|
else: |
|
|
|
|
# Getting LDC on windows to give useful linker output when not |
|
|
|
|
# doing real work is painfully hard. It ships with a version of |
|
|
|
|
# lld-link, so just assume that we're going to use lld-link |
|
|
|
|
# with it. |
|
|
|
|
_, o, _ = Popen_safe(['lld-link.exe', '--version']) |
|
|
|
|
linker = ClangClDynamicLinker(for_machine, version=search_version(o)) |
|
|
|
|
# Getting LDC on windows to give useful linker output when |
|
|
|
|
# not doing real work is painfully hard. It ships with a |
|
|
|
|
# version of lld-link, so unless we think the user wants |
|
|
|
|
# link.exe, just assume that we're going to use lld-link |
|
|
|
|
# with it. |
|
|
|
|
linker = self._guess_win_linker( |
|
|
|
|
['link' if is_msvc else 'lld-link'], |
|
|
|
|
compilers.LLVMDCompiler, for_machine, use_linker_prefix=False) |
|
|
|
|
else: |
|
|
|
|
with tempfile.NamedTemporaryFile(suffix='.d') as f: |
|
|
|
|
linker = self._guess_nix_linker( |
|
|
|
|
exelist, for_machine, |
|
|
|
|
exelist, compilers.LLVMDCompiler, for_machine, |
|
|
|
|
compilers.LLVMDCompiler.LINKER_PREFIX, |
|
|
|
|
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, compilers.GnuDCompiler, for_machine, compilers.GnuDCompiler.LINKER_PREFIX) |
|
|
|
|
return compilers.GnuDCompiler( |
|
|
|
|
exelist, version, for_machine, info, arch, is_cross, exe_wrap, |
|
|
|
|
full_version=full_version, linker=linker) |
|
|
|
@ -1403,17 +1449,17 @@ class Environment: |
|
|
|
|
m = self.machines[for_machine] |
|
|
|
|
if m.is_windows() or m.is_cygwin(): |
|
|
|
|
if is_msvc: |
|
|
|
|
linker = MSVCDynamicLinker(for_machine, version=version) |
|
|
|
|
linker_cmd = ['link'] |
|
|
|
|
elif arch == 'x86': |
|
|
|
|
linker = OptlinkDynamicLinker(for_machine, version=full_version) |
|
|
|
|
linker_cmd = ['optlink'] |
|
|
|
|
else: |
|
|
|
|
# DMD ships with lld-link |
|
|
|
|
_, o, _ = Popen_safe(['lld-link.exe', '--version']) |
|
|
|
|
linker = ClangClDynamicLinker(for_machine, version=search_version(o)) |
|
|
|
|
linker_cmd = ['lld-link'] |
|
|
|
|
linker = self._guess_win_linker(linker_cmd, compilers.DmdDCompiler, for_machine, |
|
|
|
|
use_linker_prefix=False) |
|
|
|
|
else: |
|
|
|
|
with tempfile.NamedTemporaryFile(suffix='.d') as f: |
|
|
|
|
linker = self._guess_nix_linker( |
|
|
|
|
exelist, for_machine, |
|
|
|
|
exelist, compilers.DmdDCompiler, for_machine, |
|
|
|
|
compilers.LLVMDCompiler.LINKER_PREFIX, |
|
|
|
|
extra_args=[f.name]) |
|
|
|
|
return compilers.DmdDCompiler( |
|
|
|
@ -1440,7 +1486,7 @@ class Environment: |
|
|
|
|
# As for 5.0.1 swiftc *requires* a file to check the linker: |
|
|
|
|
with tempfile.NamedTemporaryFile(suffix='.swift') as f: |
|
|
|
|
linker = self._guess_nix_linker( |
|
|
|
|
exelist, for_machine, |
|
|
|
|
exelist, compilers.SwiftCompiler, for_machine, |
|
|
|
|
compilers.SwiftCompiler.LINKER_PREFIX, |
|
|
|
|
extra_args=[f.name]) |
|
|
|
|
return compilers.SwiftCompiler( |
|
|
|
|