summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesonbuild/backend/ninjabackend.py50
-rw-r--r--mesonbuild/compilers/rust.py16
2 files changed, 25 insertions, 41 deletions
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index e332971d9..0c984eadf 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -1951,40 +1951,16 @@ class NinjaBackend(backends.Backend):
linkdirs = mesonlib.OrderedSet()
external_deps = target.external_deps.copy()
- # Have we already injected msvc-crt args?
- #
- # If we don't have A C, C++, or Fortran compiler that is
- # VisualStudioLike treat this as if we've already injected them
- #
- # We handle this here rather than in the rust compiler because in
- # general we don't want to link rust targets to a non-default crt.
- # However, because of the way that MSCRTs work you can only link to one
- # per target, so if A links to the debug one, and B links to the normal
- # one you can't link A and B. Rust is hardcoded to the default one,
- # so if we compile C/C++ code and link against a non-default MSCRT then
- # linking will fail. We can work around this by injecting MSCRT link
- # arguments early in the rustc command line
+ # Rustc always use non-debug Windows runtime. Inject the one selected
+ # by Meson options instead.
# https://github.com/rust-lang/rust/issues/39016
- crt_args_injected = not any(x is not None and x.get_argument_syntax() == 'msvc' for x in
- (self.environment.coredata.compilers[target.for_machine].get(l)
- for l in ['c', 'cpp', 'fortran']))
-
- crt_link_args: T.List[str] = []
- try:
- buildtype = target.get_option(OptionKey('buildtype'))
- crt = target.get_option(OptionKey('b_vscrt'))
- crt = rustc.get_crt_val(crt, buildtype)
- if crt == 'mdd':
- crt_link_args = ['-l', 'static=msvcrtd']
- elif crt == 'md':
- # this is the default, no need to inject anything
- crt_args_injected = True
- elif crt == 'mtd':
- crt_link_args = ['-l', 'static=libcmtd']
- elif crt == 'mt':
- crt_link_args = ['-l', 'static=libcmt']
- except KeyError:
- crt_args_injected = True
+ if not isinstance(target, build.StaticLibrary):
+ try:
+ buildtype = target.get_option(OptionKey('buildtype'))
+ crt = target.get_option(OptionKey('b_vscrt'))
+ args += rustc.get_crt_link_args(crt, buildtype)
+ except KeyError:
+ pass
# TODO: we likely need to use verbatim to handle name_prefix and name_suffix
for d in target.link_targets:
@@ -2001,10 +1977,6 @@ class NinjaBackend(backends.Backend):
project_deps.append(RustDep(d_name, self.rust_crates[d.name].order))
continue
- if not crt_args_injected and not {'c', 'cpp', 'fortran'}.isdisjoint(d.compilers):
- args += crt_link_args
- crt_args_injected = True
-
if isinstance(d, build.StaticLibrary):
# Rustc doesn't follow Meson's convention that static libraries
# are called .a, and import libraries are .lib, so we have to
@@ -2045,10 +2017,6 @@ class NinjaBackend(backends.Backend):
args += ['--extern', '{}={}'.format(d_name, os.path.join(d.subdir, d.filename))]
project_deps.append(RustDep(d_name, self.rust_crates[d.name].order))
else:
- if not crt_args_injected and not {'c', 'cpp', 'fortran'}.isdisjoint(d.compilers):
- crt_args_injected = True
- crt_args_injected = True
-
if rustc.linker.id in {'link', 'lld-link'}:
if verbatim:
# If we can use the verbatim modifier, then everything is great
diff --git a/mesonbuild/compilers/rust.py b/mesonbuild/compilers/rust.py
index b5e6a6a0c..1fb94aa44 100644
--- a/mesonbuild/compilers/rust.py
+++ b/mesonbuild/compilers/rust.py
@@ -55,6 +55,17 @@ class RustCompiler(Compiler):
'3': ['-W', 'warnings'],
}
+ # Those are static libraries, but we use dylib= here as workaround to avoid
+ # rust --tests to use /WHOLEARCHIVE.
+ # https://github.com/rust-lang/rust/issues/116910
+ MSVCRT_ARGS: T.Mapping[str, T.List[str]] = {
+ 'none': [],
+ 'md': [], # this is the default, no need to inject anything
+ 'mdd': ['-l', 'dylib=msvcrtd'],
+ 'mt': ['-l', 'dylib=libcmt'],
+ 'mtd': ['-l', 'dylib=libcmtd'],
+ }
+
def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice,
is_cross: bool, info: 'MachineInfo',
exe_wrapper: T.Optional['ExternalProgram'] = None,
@@ -177,6 +188,11 @@ class RustCompiler(Compiler):
# Rust handles this for us, we don't need to do anything
return []
+ def get_crt_link_args(self, crt_val: str, buildtype: str) -> T.List[str]:
+ if self.linker.id not in {'link', 'lld-link'}:
+ return []
+ return self.MSVCRT_ARGS[self.get_crt_val(crt_val, buildtype)]
+
def get_colorout_args(self, colortype: str) -> T.List[str]:
if colortype in {'always', 'never', 'auto'}:
return [f'--color={colortype}']