aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDylan Baker <dylan@pnwbakers.com>2020-10-16 09:42:59 -0700
committerDylan Baker <dylan@pnwbakers.com>2020-11-13 09:00:35 -0800
commit6ce3812762405393d912ca8f222fa86cb2d6bed3 (patch)
tree2a9f6e73321e7f6a770c950f83891c1b12b99127
parent86957cfc90161fa672043e6bcdd3ccb1de12436e (diff)
downloadmeson-6ce3812762405393d912ca8f222fa86cb2d6bed3.zip
meson-6ce3812762405393d912ca8f222fa86cb2d6bed3.tar.gz
meson-6ce3812762405393d912ca8f222fa86cb2d6bed3.tar.bz2
environment: Fix detection of rust compilers, more
-rw-r--r--mesonbuild/environment.py38
-rwxr-xr-xrun_unittests.py3
2 files changed, 29 insertions, 12 deletions
diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py
index 6545a00..7194d03 100644
--- a/mesonbuild/environment.py
+++ b/mesonbuild/environment.py
@@ -129,6 +129,9 @@ from .compilers import (
VisualStudioCPPCompiler,
)
+if T.TYPE_CHECKING:
+ from .dependencies import ExternalProgram
+
build_filename = 'meson.build'
CompilersDict = T.Dict[str, Compiler]
@@ -869,7 +872,7 @@ class Environment:
defines[rest[0]] = rest[1]
return defines
- def _get_compilers(self, lang, for_machine):
+ def _get_compilers(self, lang: str, for_machine: MachineChoice) -> T.Tuple[T.List[T.List[str]], T.List[str], T.Optional['ExternalProgram']]:
'''
The list of compilers is detected in the exact same way for
C, C++, ObjC, ObjC++, Fortran, CS so consolidate it here.
@@ -1062,9 +1065,17 @@ class Environment:
self.__failed_to_detect_linker(compiler, check_args, o, e)
return linker
- def _detect_c_or_cpp_compiler(self, lang: str, for_machine: MachineChoice) -> Compiler:
+ def _detect_c_or_cpp_compiler(self, lang: str, for_machine: MachineChoice, *, override_compiler: T.Optional[T.List[str]] = None) -> Compiler:
+ """Shared implementation for finding the C or C++ compiler to use.
+
+ the override_compiler option is provided to allow compilers which use
+ the compiler (GCC or Clang usually) as their shared linker, to find
+ the linker they need.
+ """
popen_exceptions = {}
compilers, ccache, exe_wrap = self._get_compilers(lang, for_machine)
+ if override_compiler is not None:
+ compilers = [override_compiler]
is_cross = self.is_cross_build(for_machine)
info = self.machines[for_machine]
@@ -1666,9 +1677,16 @@ class Environment:
extra_args['direct'] = True
extra_args['machine'] = cc.linker.machine
else:
- c = cc.linker.exelist[1] if cc.linker.exelist[0].endswith('ccache') else cc.linker.exelist[0]
+ exelist = cc.linker.exelist.copy()
+ if 'ccache' in exelist[0]:
+ del exelist[0]
+ c = exelist.pop(0)
compiler.extend(RustCompiler.use_linker_args(c))
+ # Also ensure that we pass any extra arguments to the linker
+ for l in exelist:
+ compiler.extend(['-C', 'link-arg={}'.format(l)])
+
# This trickery with type() gets us the class of the linker
# so we can initialize a new copy for the Rust Compiler
if is_link_exe:
@@ -1686,18 +1704,16 @@ class Environment:
linker.direct = True
compiler.extend(RustCompiler.use_linker_args(linker.exelist[0]))
else:
- # We're creating a new type of "C" compiler, that has rust
- # as it's language. This is gross, but I can't figure out
- # another way to handle this, because rustc is actually
- # invoking the c compiler as it's linker.
- breakpoint()
- b = type('b', (type(cc), ), {})
- linker = self._guess_nix_linker(override, b, for_machine)
+ # On linux and macos rust will invoke the c compiler for
+ # linking, on windows it will use lld-link or link.exe.
+ # we will simply ask for the C compiler that coresponds to
+ # it, and use that.
+ cc = self._detect_c_or_cpp_compiler('c', for_machine, override_compiler=override)
linker = cc.linker
# Of course, we're not going to use any of that, we just
# need it to get the proper arguments to pass to rustc
- c = cc.exelist[1] if cc.exelist[0].endswith('ccache') else cc.exelist[0]
+ c = linker.exelist[1] if linker.exelist[0].endswith('ccache') else linker.exelist[0]
compiler.extend(RustCompiler.use_linker_args(c))
self.coredata.add_lang_args(RustCompiler.language, RustCompiler, for_machine, self)
diff --git a/run_unittests.py b/run_unittests.py
index 0e8d62c..7f7df36 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -7360,8 +7360,9 @@ class LinuxlikeTests(BasePlatformTests):
self._check_ld('ld.lld', 'lld', 'c', 'ld.lld')
@skip_if_not_language('rust')
+ @skipIfNoExecutable('ld.gold') # need an additional check here because _check_ld checks for gcc
def test_ld_environment_variable_rust(self):
- self._check_ld('ld.gold', 'gold', 'rust', 'ld.gold')
+ self._check_ld('gcc', 'gcc -fuse-ld=gold', 'rust', 'ld.gold')
def test_ld_environment_variable_cpp(self):
self._check_ld('ld.gold', 'gold', 'cpp', 'ld.gold')