Makefile | 7 +++++ rust/Makefile | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+)
Adds a new `rustcheck` make target to run a check-only build
similar to `cargo check`. This allows us to verify that the Rust
sources can build without building/linking final artifacts,
which speeds up the iteration (a lot) during development.
The target supports the same flags as other Rust build rules, so
it can also be used with `CLIPPY=1` (e.g., `make LLVM=1 rustcheck
CLIPPY=1) to run Clippy in a faster way.
Also, unlike `make LLVM=1`, it doesn't compile large amounts of C
code (on a fresh checkout) when the goal is only to check that
Rust builds are not broken after some changes.
Suggested-by: Benno Losin <lossin@kernel.org>
Link: https://rust-for-linux.zulipchat.com/#narrow/channel/288089/topic/x/near/539103602
Signed-off-by: Onur Özkan <work@onurozkan.dev>
---
Makefile | 7 +++++
rust/Makefile | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 80 insertions(+)
diff --git a/Makefile b/Makefile
index cf37b9407821..7812cdc72938 100644
--- a/Makefile
+++ b/Makefile
@@ -1716,6 +1716,8 @@ help:
@echo ' is formatted, printing a diff otherwise.'
@echo ' rustdoc - Generate Rust documentation'
@echo ' (requires kernel .config)'
+ @echo ' rustcheck - Check that the Rust code builds'
+ @echo ' (requires kernel .config)'
@echo ' rusttest - Runs the Rust tests'
@echo ' (requires kernel .config; downloads external repos)'
@echo ' rust-analyzer - Generate rust-project.json rust-analyzer support file'
@@ -1821,6 +1823,11 @@ PHONY += rustdoc
rustdoc: prepare
$(Q)$(MAKE) $(build)=rust $@
+# Checking Rust sources.
+PHONY += rustcheck
+rustcheck: prepare0
+ $(Q)$(MAKE) $(build)=rust $@
+
# Testing target
PHONY += rusttest
rusttest: prepare
diff --git a/rust/Makefile b/rust/Makefile
index bfa915b0e588..c148ef4a8c08 100644
--- a/rust/Makefile
+++ b/rust/Makefile
@@ -265,6 +265,79 @@ rusttest-kernel: $(src)/kernel/lib.rs rusttestlib-ffi rusttestlib-kernel \
rusttestlib-uapi rusttestlib-pin_init FORCE
+$(call if_changed,rustc_test)
+## Check-only compilation (similar to `cargo check`)
+quiet_cmd_rustc_check_library = $(RUSTC_OR_CLIPPY_QUIET) CHECK $<
+ cmd_rustc_check_library = \
+ OBJTREE=$(abspath $(objtree)) \
+ $(RUSTC_OR_CLIPPY) $(rust_common_flags) \
+ @$(objtree)/include/generated/rustc_cfg $(rustc_target_flags) \
+ --crate-type $(if $(rustc_check_library_proc),proc-macro,rlib) \
+ $(if $(rustc_check_library_proc),,--emit=metadata) \
+ --out-dir $(objtree)/$(obj)/check -L$(objtree)/$(obj)/check \
+ --crate-name $(if $(rustc_check_crate_name),$(rustc_check_crate_name), \
+ $(subst rustcheck-,,$(subst rustchecklib-,,$@))) $<
+
+rustcheck: rustchecklib-build_error rustchecklib-ffi rustchecklib-macros \
+ rustchecklib-compiler_builtins rustchecklib-pin_init_internal \
+ rustchecklib-pin_init rustchecklib-bindings rustchecklib-uapi \
+ rustchecklib-kernel
+
+rustchecklib-build_error: $(src)/build_error.rs FORCE
+ +$(call if_changed,rustc_check_library)
+
+rustchecklib-ffi: $(src)/ffi.rs FORCE
+ +$(call if_changed,rustc_check_library)
+
+rustchecklib-macros: private rustc_target_flags = --extern proc_macro
+rustchecklib-macros: private rustc_check_library_proc = yes
+rustchecklib-macros: $(src)/macros/lib.rs FORCE
+ +$(call if_changed,rustc_check_library)
+
+rustchecklib-compiler_builtins: private rustc_check_crate_name = compiler_builtins_kernel
+rustchecklib-compiler_builtins: $(src)/compiler_builtins.rs FORCE
+ +$(call if_changed,rustc_check_library)
+
+rustchecklib-pin_init_internal: private rustc_target_flags = --cfg kernel \
+ --extern proc_macro
+rustchecklib-pin_init_internal: private rustc_check_library_proc = yes
+rustchecklib-pin_init_internal: $(src)/pin-init/internal/src/lib.rs FORCE
+ +$(call if_changed,rustc_check_library)
+
+rustchecklib-pin_init: private rustc_target_flags = --extern pin_init_internal \
+ --extern macros --cfg kernel
+rustchecklib-pin_init: $(src)/pin-init/src/lib.rs rustchecklib-macros \
+ rustchecklib-pin_init_internal FORCE
+ +$(call if_changed,rustc_check_library)
+
+rustchecklib-bindings: private rustc_target_flags = --extern ffi
+rustchecklib-bindings: $(src)/bindings/lib.rs \
+ $(obj)/bindings/bindings_generated.rs \
+ $(obj)/bindings/bindings_helpers_generated.rs \
+ rustchecklib-ffi FORCE
+ +$(call if_changed,rustc_check_library)
+
+rustchecklib-uapi: private rustc_target_flags = --extern ffi
+rustchecklib-uapi: $(src)/uapi/lib.rs $(obj)/uapi/uapi_generated.rs \
+ rustchecklib-ffi FORCE
+ +$(call if_changed,rustc_check_library)
+
+ifdef CONFIG_JUMP_LABEL
+rustchecklib-kernel: $(obj)/kernel/generated_arch_static_branch_asm.rs FORCE
+endif
+ifndef CONFIG_UML
+ifdef CONFIG_BUG
+rustchecklib-kernel: $(obj)/kernel/generated_arch_warn_asm.rs \
+ $(obj)/kernel/generated_arch_reachable_asm.rs FORCE
+endif
+endif
+
+rustchecklib-kernel: private rustc_target_flags = --extern ffi --extern pin_init \
+ --extern build_error --extern macros --extern bindings --extern uapi
+rustchecklib-kernel: $(src)/kernel/lib.rs rustchecklib-ffi rustchecklib-pin_init \
+ rustchecklib-build_error rustchecklib-macros rustchecklib-bindings \
+ rustchecklib-uapi FORCE
+ +$(call if_changed,rustc_check_library)
+
ifdef CONFIG_CC_IS_CLANG
bindgen_c_flags = $(c_flags)
else
--
2.51.0
Onur Özkan <work@onurozkan.dev> writes: > Adds a new `rustcheck` make target to run a check-only build > similar to `cargo check`. This allows us to verify that the Rust > sources can build without building/linking final artifacts, > which speeds up the iteration (a lot) during development. > > The target supports the same flags as other Rust build rules, so > it can also be used with `CLIPPY=1` (e.g., `make LLVM=1 rustcheck > CLIPPY=1) to run Clippy in a faster way. > > Also, unlike `make LLVM=1`, it doesn't compile large amounts of C > code (on a fresh checkout) when the goal is only to check that > Rust builds are not broken after some changes. > I think this is a good idea! However, it looks like this target only checks rust code that live in rust/. Can we also check code that lives elsewhere, like drivers? Best regards, Andreas Hindborg
On Sat, 13 Sep 2025 19:46:28 +0200 Andreas Hindborg <a.hindborg@kernel.org> wrote: > Onur Özkan <work@onurozkan.dev> writes: > > > Adds a new `rustcheck` make target to run a check-only build > > similar to `cargo check`. This allows us to verify that the Rust > > sources can build without building/linking final artifacts, > > which speeds up the iteration (a lot) during development. > > > > The target supports the same flags as other Rust build rules, so > > it can also be used with `CLIPPY=1` (e.g., `make LLVM=1 rustcheck > > CLIPPY=1) to run Clippy in a faster way. > > > > Also, unlike `make LLVM=1`, it doesn't compile large amounts of C > > code (on a fresh checkout) when the goal is only to check that > > Rust builds are not broken after some changes. > > > > I think this is a good idea! However, it looks like this target only > checks rust code that live in rust/. Can we also check code that lives > elsewhere, like drivers? > My work depends on the existing build system and that system doesn't allow me to do that (yet). Regards, Onur > > Best regards, > Andreas Hindborg > >
On Sat, Sep 13, 2025 at 7:46 PM Andreas Hindborg <a.hindborg@kernel.org> wrote: > > I think this is a good idea! However, it looks like this target only > checks rust code that live in rust/. Can we also check code that lives > elsewhere, like drivers? That is more involved, and I don't plan to add features to the current system, sorry. Cheers, Miguel
"Miguel Ojeda" <miguel.ojeda.sandonis@gmail.com> writes: > On Sat, Sep 13, 2025 at 7:46 PM Andreas Hindborg <a.hindborg@kernel.org> wrote: >> >> I think this is a good idea! However, it looks like this target only >> checks rust code that live in rust/. Can we also check code that lives >> elsewhere, like drivers? > > That is more involved, and I don't plan to add features to the current > system, sorry. I assume you are referring to the upcoming rust build system changes. Any idea when these will land? Will it be possible to implement a check feature when the changes land? Best regards, Andreas Hindborg
On Sat, 13 Sep 2025 13:08:47 +0300 Onur Özkan <work@onurozkan.dev> wrote: > Adds a new `rustcheck` make target to run a check-only build > similar to `cargo check`. This allows us to verify that the Rust > sources can build without building/linking final artifacts, > which speeds up the iteration (a lot) during development. > > The target supports the same flags as other Rust build rules, so > it can also be used with `CLIPPY=1` (e.g., `make LLVM=1 rustcheck > CLIPPY=1) to run Clippy in a faster way. > > Also, unlike `make LLVM=1`, it doesn't compile large amounts of C > code (on a fresh checkout) when the goal is only to check that > Rust builds are not broken after some changes. > > Suggested-by: Benno Losin <lossin@kernel.org> > Link: > https://rust-for-linux.zulipchat.com/#narrow/channel/288089/topic/x/near/539103602 > Signed-off-by: Onur Özkan <work@onurozkan.dev> --- > Makefile | 7 +++++ > rust/Makefile | 73 > +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, > 80 insertions(+) > > diff --git a/Makefile b/Makefile > index cf37b9407821..7812cdc72938 100644 > --- a/Makefile > +++ b/Makefile > @@ -1716,6 +1716,8 @@ help: > @echo ' is formatted, printing a diff > otherwise.' @echo ' rustdoc - Generate Rust documentation' > @echo ' (requires kernel .config)' > + @echo ' rustcheck - Check that the Rust code builds' > + @echo ' (requires kernel .config)' > @echo ' rusttest - Runs the Rust tests' > @echo ' (requires kernel .config; > downloads external repos)' @echo ' rust-analyzer - > Generate rust-project.json rust-analyzer support file' @@ -1821,6 > +1823,11 @@ PHONY += rustdoc rustdoc: prepare > $(Q)$(MAKE) $(build)=rust $@ > > +# Checking Rust sources. > +PHONY += rustcheck > +rustcheck: prepare0 > + $(Q)$(MAKE) $(build)=rust $@ > + > # Testing target > PHONY += rusttest > rusttest: prepare > diff --git a/rust/Makefile b/rust/Makefile > index bfa915b0e588..c148ef4a8c08 100644 > --- a/rust/Makefile > +++ b/rust/Makefile > @@ -265,6 +265,79 @@ rusttest-kernel: $(src)/kernel/lib.rs > rusttestlib-ffi rusttestlib-kernel \ rusttestlib-uapi > rusttestlib-pin_init FORCE +$(call if_changed,rustc_test) > > +## Check-only compilation (similar to `cargo check`) > +quiet_cmd_rustc_check_library = $(RUSTC_OR_CLIPPY_QUIET) CHECK $< > + cmd_rustc_check_library = \ > + OBJTREE=$(abspath $(objtree)) \ > + $(RUSTC_OR_CLIPPY) $(rust_common_flags) \ > + @$(objtree)/include/generated/rustc_cfg > $(rustc_target_flags) \ > + --crate-type $(if > $(rustc_check_library_proc),proc-macro,rlib) \ > + $(if $(rustc_check_library_proc),,--emit=metadata) \ > + --out-dir $(objtree)/$(obj)/check > -L$(objtree)/$(obj)/check \ > + --crate-name $(if > $(rustc_check_crate_name),$(rustc_check_crate_name), \ > + $(subst rustcheck-,,$(subst > rustchecklib-,,$@))) $< + > +rustcheck: rustchecklib-build_error rustchecklib-ffi > rustchecklib-macros \ > + rustchecklib-compiler_builtins > rustchecklib-pin_init_internal \ > + rustchecklib-pin_init rustchecklib-bindings > rustchecklib-uapi \ > + rustchecklib-kernel > + > +rustchecklib-build_error: $(src)/build_error.rs FORCE > + +$(call if_changed,rustc_check_library) > + > +rustchecklib-ffi: $(src)/ffi.rs FORCE > + +$(call if_changed,rustc_check_library) > + > +rustchecklib-macros: private rustc_target_flags = --extern proc_macro > +rustchecklib-macros: private rustc_check_library_proc = yes > +rustchecklib-macros: $(src)/macros/lib.rs FORCE > + +$(call if_changed,rustc_check_library) > + > +rustchecklib-compiler_builtins: private rustc_check_crate_name = > compiler_builtins_kernel +rustchecklib-compiler_builtins: > $(src)/compiler_builtins.rs FORCE > + +$(call if_changed,rustc_check_library) > + > +rustchecklib-pin_init_internal: private rustc_target_flags = --cfg > kernel \ > + --extern proc_macro > +rustchecklib-pin_init_internal: private rustc_check_library_proc = > yes +rustchecklib-pin_init_internal: > $(src)/pin-init/internal/src/lib.rs FORCE > + +$(call if_changed,rustc_check_library) > + > +rustchecklib-pin_init: private rustc_target_flags = --extern > pin_init_internal \ > + --extern macros --cfg kernel > +rustchecklib-pin_init: $(src)/pin-init/src/lib.rs > rustchecklib-macros \ > + rustchecklib-pin_init_internal FORCE > + +$(call if_changed,rustc_check_library) > + > +rustchecklib-bindings: private rustc_target_flags = --extern ffi > +rustchecklib-bindings: $(src)/bindings/lib.rs \ > + $(obj)/bindings/bindings_generated.rs \ > + $(obj)/bindings/bindings_helpers_generated.rs \ > + rustchecklib-ffi FORCE > + +$(call if_changed,rustc_check_library) > + > +rustchecklib-uapi: private rustc_target_flags = --extern ffi > +rustchecklib-uapi: $(src)/uapi/lib.rs $(obj)/uapi/uapi_generated.rs \ > + rustchecklib-ffi FORCE > + +$(call if_changed,rustc_check_library) > + > +ifdef CONFIG_JUMP_LABEL > +rustchecklib-kernel: > $(obj)/kernel/generated_arch_static_branch_asm.rs FORCE +endif > +ifndef CONFIG_UML > +ifdef CONFIG_BUG > +rustchecklib-kernel: $(obj)/kernel/generated_arch_warn_asm.rs \ > + $(obj)/kernel/generated_arch_reachable_asm.rs FORCE > +endif > +endif > + > +rustchecklib-kernel: private rustc_target_flags = --extern ffi > --extern pin_init \ > + --extern build_error --extern macros --extern bindings > --extern uapi +rustchecklib-kernel: $(src)/kernel/lib.rs > rustchecklib-ffi rustchecklib-pin_init \ > + rustchecklib-build_error rustchecklib-macros > rustchecklib-bindings \ > + rustchecklib-uapi FORCE > + +$(call if_changed,rustc_check_library) > + > ifdef CONFIG_CC_IS_CLANG > bindgen_c_flags = $(c_flags) > else Seems like I got some indentation issues, will handle in in the next version after some feedbacks. -Onur
© 2016 - 2025 Red Hat, Inc.