summaryrefslogtreecommitdiff
path: root/mesonbuild/compilers
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2024-11-18 11:20:56 +0100
committerDylan Baker <dylan@pnwbakers.com>2024-12-19 09:25:20 -0800
commit27c567de5d1807ac72708ea48018a21f0c6b8dd2 (patch)
tree180bc008df788970020b66ae677ea0f4e4a2d0e5 /mesonbuild/compilers
parent5dc537afd051e60ff00731f73e02d98138d9198b (diff)
downloadmeson-27c567de5d1807ac72708ea48018a21f0c6b8dd2.tar.gz
scripts: add "clippy" internal tool
Similar to the "ninja scan-build" target for C, add a clippy internal tool that runs clippy-driver on all crates in the project. The approach used is more efficient than with "ninja scan-build", and does not require rerunning Meson in a separate build directory; it uses the introspection data to find the compiler arguments for the target and invokes clippy-driver with a slightly modified command line. This could actually be applied to scan-build as well, reusing the run_tool_on_targets() function. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'mesonbuild/compilers')
-rw-r--r--mesonbuild/compilers/rust.py49
1 files changed, 49 insertions, 0 deletions
diff --git a/mesonbuild/compilers/rust.py b/mesonbuild/compilers/rust.py
index 02ac59384..717d5635f 100644
--- a/mesonbuild/compilers/rust.py
+++ b/mesonbuild/compilers/rust.py
@@ -33,6 +33,35 @@ rust_optimization_args: T.Dict[str, T.List[str]] = {
's': ['-C', 'opt-level=s'],
}
+def get_rustup_run_and_args(exelist: T.List[str]) -> T.Optional[T.Tuple[T.List[str], T.List[str]]]:
+ """Given the command for a rustc executable, check if it is invoked via
+ "rustup run" and if so separate the "rustup [OPTIONS] run TOOLCHAIN"
+ part from the arguments to rustc. If the returned value is not None,
+ other tools (for example clippy-driver or rustdoc) can be run by placing
+ the name of the tool between the two elements of the tuple."""
+ e = iter(exelist)
+ try:
+ if os.path.basename(next(e)) != 'rustup':
+ return None
+ # minimum three strings: "rustup run TOOLCHAIN"
+ n = 3
+ opt = next(e)
+
+ # options come first
+ while opt.startswith('-'):
+ n += 1
+ opt = next(e)
+
+ # then "run TOOLCHAIN"
+ if opt != 'run':
+ return None
+
+ next(e)
+ next(e)
+ return exelist[:n], list(e)
+ except StopIteration:
+ return None
+
class RustCompiler(Compiler):
# rustc doesn't invoke the compiler itself, it doesn't need a LINKER_PREFIX
@@ -65,6 +94,7 @@ class RustCompiler(Compiler):
super().__init__([], exelist, version, for_machine, info,
is_cross=is_cross, full_version=full_version,
linker=linker)
+ self.rustup_run_and_args: T.Optional[T.Tuple[T.List[str], T.List[str]]] = get_rustup_run_and_args(exelist)
self.base_options.update({OptionKey(o) for o in ['b_colorout', 'b_ndebug']})
if 'link' in self.linker.id:
self.base_options.add(OptionKey('b_vscrt'))
@@ -252,6 +282,25 @@ class RustCompiler(Compiler):
action = "no" if disable else "yes"
return ['-C', f'debug-assertions={action}', '-C', 'overflow-checks=no']
+ def get_rust_tool(self, name: str, env: Environment) -> T.List[str]:
+ if self.rustup_run_and_args:
+ rustup_exelist, args = self.rustup_run_and_args
+ # do not use extend so that exelist is copied
+ exelist = rustup_exelist + [name]
+ else:
+ exelist = [name]
+ args = self.exelist[1:]
+
+ from ..programs import find_external_program
+ for prog in find_external_program(env, self.for_machine, exelist[0], exelist[0],
+ [exelist[0]], allow_default_for_cross=False):
+ exelist[0] = prog.path
+ break
+ else:
+ return []
+
+ return exelist + args
+
class ClippyRustCompiler(RustCompiler):