aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2020-11-14 13:47:39 +0200
committerGitHub <noreply@github.com>2020-11-14 13:47:39 +0200
commit299a67781e8330e110bd2aee76464ac6b755322c (patch)
tree8772aa52e79947a60a22b2a034a46f9b0da37f8a /mesonbuild
parent8dcc7d3ef3cb95029c41a0d4accef86415f29cb8 (diff)
parent6ce3812762405393d912ca8f222fa86cb2d6bed3 (diff)
downloadmeson-299a67781e8330e110bd2aee76464ac6b755322c.zip
meson-299a67781e8330e110bd2aee76464ac6b755322c.tar.gz
meson-299a67781e8330e110bd2aee76464ac6b755322c.tar.bz2
Merge pull request #7843 from dcbaker/submit/rustc-fixes
A few fixups for rust
Diffstat (limited to 'mesonbuild')
-rw-r--r--mesonbuild/backend/ninjabackend.py5
-rw-r--r--mesonbuild/build.py9
-rw-r--r--mesonbuild/compilers/rust.py4
-rw-r--r--mesonbuild/environment.py67
4 files changed, 58 insertions, 27 deletions
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index 1ed742b..c3c5705 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -1489,7 +1489,7 @@ int dummy;
self.create_target_source_introspection(target, valac, args, all_files, [])
return other_src[0], other_src[1], vala_c_src
- def generate_rust_target(self, target):
+ def generate_rust_target(self, target: build.BuildTarget) -> None:
rustc = target.compilers['rust']
# Rust compiler takes only the main file as input and
# figures out what other files are needed via import
@@ -1539,7 +1539,8 @@ int dummy;
depfile = os.path.join(target.subdir, target.name + '.d')
args += ['--emit', 'dep-info={}'.format(depfile), '--emit', 'link']
args += target.get_extra_args('rust')
- args += ['-o', os.path.join(target.subdir, target.get_filename())]
+ args += rustc.get_output_args(os.path.join(target.subdir, target.get_filename()))
+ args += self.environment.coredata.get_external_args(target.for_machine, rustc.language)
orderdeps = [os.path.join(t.subdir, t.get_filename()) for t in target.link_targets]
linkdirs = OrderedDict()
for d in target.link_targets:
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index 78292f2..36d4e19 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -1359,11 +1359,12 @@ You probably should put it in link_with instead.''')
for link_target in self.link_targets:
if isinstance(link_target, SharedModule):
if self.environment.machines[self.for_machine].is_darwin():
- raise MesonException('''target links against shared modules.
-This is not permitted on OSX''')
+ raise MesonException(
+ 'target links against shared modules. This is not permitted on OSX')
else:
- mlog.warning('''target links against shared modules. This is not
-recommended as it is not supported on some platforms''')
+ mlog.warning('target links against shared modules. This '
+ 'is not recommended as it is not supported on some '
+ 'platforms')
return
class Generator:
diff --git a/mesonbuild/compilers/rust.py b/mesonbuild/compilers/rust.py
index 1be0cd8..312b3b6 100644
--- a/mesonbuild/compilers/rust.py
+++ b/mesonbuild/compilers/rust.py
@@ -125,6 +125,10 @@ class RustCompiler(Compiler):
def get_output_args(self, outputname: str) -> T.List[str]:
return ['-o', outputname]
+ @classmethod
+ def use_linker_args(cls, linker: str) -> T.List[str]:
+ return ['-C', 'linker={}'.format(linker)]
+
# Rust does not have a use_linker_args because it dispatches to a gcc-like
# C compiler for dynamic linking, as such we invoke the C compiler's
# use_linker_args method instead.
diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py
index 588005b..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]
@@ -1619,9 +1630,9 @@ class Environment:
return comp_class(exelist, version, for_machine, info, is_cross)
raise EnvironmentException('Unknown compiler "' + ' '.join(exelist) + '"')
- def detect_rust_compiler(self, for_machine):
- popen_exceptions = {}
- compilers, ccache, exe_wrap = self._get_compilers('rust', for_machine)
+ def detect_rust_compiler(self, for_machine: MachineChoice) -> RustCompiler:
+ popen_exceptions = {} # type: T.Dict[str, Exception]
+ compilers, _, exe_wrap = self._get_compilers('rust', for_machine)
is_cross = self.is_cross_build(for_machine)
info = self.machines[for_machine]
@@ -1634,7 +1645,7 @@ class Environment:
compiler = [compiler]
arg = ['--version']
try:
- p, out = Popen_safe(compiler + arg)[0:2]
+ out = Popen_safe(compiler + arg)[1]
except OSError as e:
popen_exceptions[' '.join(compiler + arg)] = e
continue
@@ -1651,17 +1662,30 @@ class Environment:
# the default use that, and second add the necessary arguments
# to rust to use -fuse-ld
+ if any(a.startswith('linker=') for a in compiler):
+ mlog.warning(
+ 'Please do not put -C linker= in your compiler '
+ 'command, set rust_ld=command in your cross file '
+ 'or use the RUST_LD environment variable. meson '
+ 'will override your seletion otherwise.')
+
if override is None:
extra_args = {}
always_args = []
if is_link_exe:
- compiler.extend(['-C', 'linker={}'.format(cc.linker.exelist[0])])
+ compiler.extend(RustCompiler.use_linker_args(cc.linker.exelist[0]))
extra_args['direct'] = True
extra_args['machine'] = cc.linker.machine
- elif 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]
- compiler.extend(['-C', 'linker={}'.format(c)])
+ else:
+ 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
@@ -1675,21 +1699,22 @@ class Environment:
elif 'link' in override[0]:
linker = self._guess_win_linker(
override, RustCompiler, for_machine, use_linker_prefix=False)
+ # rustc takes linker arguments without a prefix, and
+ # inserts the correct prefix itself.
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.
- b = type('b', (type(cc), ), {})
- b.language = RustCompiler.language
- linker = self._guess_nix_linker(cc.exelist, 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]
- compiler.extend(['-C', 'linker={}'.format(c)])
- compiler.extend(['-C', 'link-args={}'.format(' '.join(cc.use_linker_args(override[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)
return RustCompiler(