From 0bcffa60b550b563818c8178e8fad127c2fe4b56 Mon Sep 17 00:00:00 2001 From: Xavier Claessens Date: Wed, 22 Nov 2023 07:41:59 -0500 Subject: [PATCH 1/3] rust: Cache sysroot value as it's called multiple times --- mesonbuild/compilers/rust.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mesonbuild/compilers/rust.py b/mesonbuild/compilers/rust.py index 1fb94aa4447a..f8d5e2939bba 100644 --- a/mesonbuild/compilers/rust.py +++ b/mesonbuild/compilers/rust.py @@ -18,6 +18,8 @@ import re import typing as T +from functools import lru_cache + from .. import coredata from ..mesonlib import EnvironmentException, MesonException, Popen_safe_logged, OptionKey from .compilers import Compiler, rust_buildtype_args, clike_debug_args @@ -126,6 +128,7 @@ def get_dependency_gen_args(self, outtarget: str, outfile: str) -> T.List[str]: def get_buildtype_args(self, buildtype: str) -> T.List[str]: return rust_buildtype_args[buildtype] + @lru_cache(maxsize=None) def get_sysroot(self) -> str: cmd = self.get_exelist(ccache=False) + ['--print', 'sysroot'] p, stdo, stde = Popen_safe_logged(cmd) From b2943dee5e88421a74c46cfe67f78fad3552cb10 Mon Sep 17 00:00:00 2001 From: Xavier Claessens Date: Wed, 22 Nov 2023 08:05:04 -0500 Subject: [PATCH 2/3] compilers: Trigger reconfigure when compiler exe changes When the compiler has been updated we need to trigger a reconfigure because any compiler checks result could have changed. In the case the compiler is a wrapper script we cannot detect when the real compiler changed, but this is better than nothing and we should reconfigure when the wrapper itself changed as well anyway. --- mesonbuild/compilers/compilers.py | 3 +++ mesonbuild/interpreter/interpreter.py | 1 + 2 files changed, 4 insertions(+) diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index a7bb6c417932..afc223b1f4ae 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -631,6 +631,9 @@ def get_exelist(self, ccache: bool = True) -> T.List[str]: def get_linker_exelist(self) -> T.List[str]: return self.linker.get_exelist() if self.linker else self.get_exelist() + def get_exe_file(self) -> str: + return os.path.realpath(self.exelist_no_ccache[0]) + @abc.abstractmethod def get_output_args(self, outputname: str) -> T.List[str]: pass diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py index e885010b23a1..b339c5157711 100644 --- a/mesonbuild/interpreter/interpreter.py +++ b/mesonbuild/interpreter/interpreter.py @@ -1519,6 +1519,7 @@ def add_languages_for(self, args: T.List[str], required: bool, for_machine: Mach comp = compilers.detect_compiler_for(self.environment, lang, for_machine, skip_sanity_check) if comp is None: raise InvalidArguments(f'Tried to use unknown language "{lang}".') + self.add_build_def_file(comp.get_exe_file()) except mesonlib.MesonException: if not required: mlog.log('Compiler for language', From 73257b0778de67890d9c619be138ab2f8e6c3ec5 Mon Sep 17 00:00:00 2001 From: Xavier Claessens Date: Wed, 22 Nov 2023 08:12:05 -0500 Subject: [PATCH 3/3] rust: Rebuild targets when compiler got updated rustc updates are usually incompatible and requires recompiling of all targets. This adds the compiler exe as dependency of every rust ninja targets. Also try to resolve the real rustc exe being used when the toolchain is wrapped by rustup. Fixes: #10706 --- mesonbuild/backend/ninjabackend.py | 2 +- mesonbuild/compilers/rust.py | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index 049ae253fe34..92b88f121bf9 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -1877,7 +1877,7 @@ def generate_rust_target(self, target: build.BuildTarget) -> None: self.generate_generator_list_rules(target) # dependencies need to cause a relink, they're not just for ordering - deps: T.List[str] = [] + deps: T.List[str] = [rustc.get_exe_file()] # Dependencies for rust-project.json project_deps: T.List[RustDep] = [] diff --git a/mesonbuild/compilers/rust.py b/mesonbuild/compilers/rust.py index f8d5e2939bba..faa340814fb1 100644 --- a/mesonbuild/compilers/rust.py +++ b/mesonbuild/compilers/rust.py @@ -81,6 +81,19 @@ def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoic if 'link' in self.linker.id: self.base_options.add(OptionKey('b_vscrt')) self.native_static_libs: T.List[str] = [] + # Resolve the real rustc executable. When using rustup, "rustc" in PATH + # is a wrapper that won't change when updating the toolchain, which + # means ninja would not rebuild rust targets after "rustup update". That + # can cause build issues because different rustc versions are generally + # uncompatible. This also means that once a Meson project has been + # configured, changing the default toolchain with e.g. + # "rustup default nightly" won't have any effect. + sysroot = self.get_sysroot() + real_rustc = os.path.join(sysroot, 'bin', 'rustc') + if os.path.exists(real_rustc): + exelist = [real_rustc] + exelist[1:] + self.exelist = exelist + self.exelist_no_ccache = exelist def needs_static_linker(self) -> bool: return False