summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Turner <jturner.usa@gmail.com>2025-12-22 19:52:56 -0500
committerJohn Turner <jturner.usa@gmail.com>2025-12-22 19:52:56 -0500
commit124f237c9e8c0a09737571aac92095461a2c689d (patch)
tree109d12f4d49643d51d585dd7855fdc0c58b20398
parent8e53ca4b796242a4fc366a263fab3adecf5e7151 (diff)
parent651fe54d12f07dd98ff94f8a8cea2469e746a590 (diff)
downloadmeson-124f237c9e8c0a09737571aac92095461a2c689d.tar.gz
Merge branch 'clippy-json'
-rw-r--r--docs/markdown/Rust.md7
-rw-r--r--docs/markdown/snippets/clippy-json.md9
-rw-r--r--mesonbuild/backend/ninjabackend.py24
-rw-r--r--mesonbuild/scripts/clippy.py14
4 files changed, 52 insertions, 2 deletions
diff --git a/docs/markdown/Rust.md b/docs/markdown/Rust.md
index 1ca3d3a85..7b64944ef 100644
--- a/docs/markdown/Rust.md
+++ b/docs/markdown/Rust.md
@@ -91,6 +91,13 @@ write files into the source directory). [See the upstream
docs](https://rust-analyzer.github.io/book/non_cargo_based_projects.html) for
more information on how to configure that.
+### Clippy
+You can use the "clippy-json" build target as rust-analyer's "check command" to recieve clippy diagnostics in your editor.
+
+Without overriding the check command, the LSP will function in a limited state, only showing certain errors (for example, no borrow checking errors are shown).
+
+[Non cargo based projects](https://rust-analyzer.github.io/book/non_cargo_based_projects.html) shows how to override the check command, you probably want to set it to `ninja clippy-json -C build`.
+
## Linking with standard libraries
Meson will link the Rust standard libraries (e.g. libstd) statically, unless the
diff --git a/docs/markdown/snippets/clippy-json.md b/docs/markdown/snippets/clippy-json.md
new file mode 100644
index 000000000..3b8ae370c
--- /dev/null
+++ b/docs/markdown/snippets/clippy-json.md
@@ -0,0 +1,9 @@
+# New "clippy-json" Ninja Target For rust-analyzer
+
+A new `clippy-json` ninja target will now be generated for rust projects.
+
+rust-analyzer supports non-cargo based projects so long as you provide it with a `rust-project.json` file and a custom "check command" to provide compiler errors.
+
+Meson already for some time has generated a `rust-project.json` file for rust-analyzer, but had no way to hook up its rustc/clippy output to rust-analyzer.
+
+To use the new feature, you want to override the rust-analyzer check command as shown [here](https://rust-analyzer.github.io/book/non_cargo_based_projects.html), and set it to `ninja clippy-json -C build` or something to the same effect.
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index 24d917343..f6139127d 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -3947,6 +3947,28 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
elem.add_dep(list(self.all_structured_sources))
self.add_build(elem)
+ def generate_clippy_json_prereq(self) -> None:
+ if 'clippy-json-prereq' in self.all_outputs or not self.have_language('rust'):
+ return
+
+ elem = self.create_phony_target('clippy-json-prereq', 'CUSTOM_COMMAND', 'PHONY')
+ for crate in self.rust_crates.values():
+ if crate.crate_type in {'rlib', 'dylib', 'proc-macro'}:
+ elem.add_dep(crate.target_name)
+ elem.add_dep(list(self.all_structured_sources))
+ self.add_build(elem)
+
+ def generate_clippy_json(self) -> None:
+ if 'clippy-json' in self.all_outputs or not self.have_language('rust'):
+ return
+
+ cmd = self.environment.get_build_command() + \
+ ['--internal', 'clippy', self.environment.build_dir, '--error-format=json']
+ elem = self.create_phony_target('clippy-json', 'CUSTOM_COMMAND', 'PHONY')
+ elem.add_item('COMMAND', cmd)
+ elem.add_item('pool', 'console')
+ self.add_build(elem)
+
def generate_rustdoc(self) -> None:
if 'rustdoc' in self.all_outputs or not self.have_language('rust'):
return
@@ -4036,6 +4058,8 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
self.generate_clangformat()
self.generate_clangtidy()
self.generate_clippy()
+ self.generate_clippy_json_prereq()
+ self.generate_clippy_json()
self.generate_rustdoc()
self.generate_tags('etags', 'TAGS')
self.generate_tags('ctags', 'ctags')
diff --git a/mesonbuild/scripts/clippy.py b/mesonbuild/scripts/clippy.py
index 0ea7a3429..519d3ab22 100644
--- a/mesonbuild/scripts/clippy.py
+++ b/mesonbuild/scripts/clippy.py
@@ -6,16 +6,18 @@ from collections import defaultdict
import os
import tempfile
import typing as T
+import subprocess
from .run_tool import run_tool_on_targets, run_with_buffered_output
from .. import build, mlog
from ..mesonlib import MachineChoice, PerMachine
+from ..tooldetect import detect_ninja
if T.TYPE_CHECKING:
from ..compilers.rust import RustCompiler
class ClippyDriver:
- def __init__(self, build: build.Build, tempdir: str):
+ def __init__(self, build: build.Build, tempdir: str, args: list[str]):
self.tools: PerMachine[T.List[str]] = PerMachine([], [])
self.warned: T.DefaultDict[str, bool] = defaultdict(lambda: False)
self.tempdir = tempdir
@@ -24,6 +26,7 @@ class ClippyDriver:
if 'rust' in compilers:
compiler = T.cast('RustCompiler', compilers['rust'])
self.tools[machine] = compiler.get_rust_tool('clippy-driver')
+ self.args = args
def warn_missing_clippy(self, machine: str) -> None:
if self.warned[machine]:
@@ -67,10 +70,17 @@ class ClippyDriver:
cmdlist.append('metadata')
cmdlist.append('--out-dir')
cmdlist.append(self.tempdir)
+ cmdlist += self.args
yield run_with_buffered_output(cmdlist)
def run(args: T.List[str]) -> int:
os.chdir(args[0])
build_data = build.load(os.getcwd())
+
+ # Build as much of the project as possible, or else
+ # we get errors about missing libraries in the build directory and
+ # other related errors.
+ subprocess.run(detect_ninja() + ['clippy-json-prereq', '-k0'])
+
with tempfile.TemporaryDirectory() as d:
- return run_tool_on_targets(ClippyDriver(build_data, d))
+ return run_tool_on_targets(ClippyDriver(build_data, d, args[1:]))