Skip to content

Commit 6b73399

Browse files
committed
rust: support host userspace tests
Includes support for both unit tests and doctests. This is also in preparation of `alloc`. It may also help vendoring other crates in the future. Currently, like for `rustdoc`, only for `rust/` code. Later on we can expand the support to all modules. Signed-off-by: Miguel Ojeda <[email protected]>
1 parent ca3bf88 commit 6b73399

File tree

5 files changed

+73
-16
lines changed

5 files changed

+73
-16
lines changed

Makefile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1739,6 +1739,8 @@ help:
17391739
@echo ' is formatted, printing a diff otherwise.'
17401740
@echo ' rustdoc - Generate Rust documentation'
17411741
@echo ' (requires kernel .config)'
1742+
@echo ' rusttest - Runs the Rust tests'
1743+
@echo ' (requires kernel .config)'
17421744
@echo ' rust-analyzer - Generate rust-project.json rust-analyzer support file'
17431745
@echo ' (requires kernel .config)'
17441746
@echo ''
@@ -1824,6 +1826,11 @@ PHONY += rustdoc
18241826
rustdoc: prepare0
18251827
$(Q)$(MAKE) $(build)=rust $@
18261828

1829+
# Testing target
1830+
PHONY += rusttest
1831+
rusttest: prepare0
1832+
$(Q)$(MAKE) $(build)=rust $@
1833+
18271834
# Formatting targets
18281835
PHONY += rustfmt rustfmtcheck
18291836

rust/.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22

33
bindings_generated.rs
44
exports_*_generated.h
5-
doc/
5+
doc/
6+
test/

rust/Makefile

Lines changed: 57 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,39 +19,81 @@ obj-$(CONFIG_RUST) += exports.o
1919

2020
RUSTDOC = rustdoc
2121

22-
quiet_cmd_rustdoc_host = RUSTDOC $<
23-
cmd_rustdoc_host = \
24-
RUST_BINDINGS_FILE=$(abspath $(objtree)/rust/bindings_generated.rs) \
25-
$(RUSTDOC) $(filter-out --emit=%, $(rustc_flags)) \
26-
$(rustdoc_target_flags) -L $(objtree)/rust/ \
27-
--output $(objtree)/rust/doc --crate-name $(subst rustdoc-,,$@) \
28-
-Fmissing-docs @$(objtree)/include/generated/rustc_cfg $<
29-
30-
quiet_cmd_rustdoc = RUSTDOC $<
22+
quiet_cmd_rustdoc = RUSTDOC $(if $(filter --test,$(rustdoc_target_flags)),T, ) $(if $(rustdoc_host),H, ) $<
3123
cmd_rustdoc = \
3224
RUST_BINDINGS_FILE=$(abspath $(objtree)/rust/bindings_generated.rs) \
33-
$(RUSTDOC) $(rustc_cross_flags) $(filter-out --emit=%, $(rustc_flags)) \
34-
$(rustdoc_target_flags) -L $(objtree)/rust/ \
35-
--output $(objtree)/rust/doc --crate-name $(subst rustdoc-,,$@) \
25+
$(RUSTDOC) $(if $(rustdoc_host),,$(rustc_cross_flags)) \
26+
$(filter-out --emit=%, $(rustc_flags)) $(rustc_target_flags) $(rustdoc_target_flags) \
27+
-L $(objtree)/rust/$(if $(filter --test,$(rustdoc_target_flags)),test/) \
28+
--output $(objtree)/rust/doc --crate-name $(subst rusttest-,,$(subst rustdoc-,,$@)) \
3629
-Fmissing-docs @$(objtree)/include/generated/rustc_cfg $<
3730

3831
rustdoc: rustdoc-macros rustdoc-compiler_builtins rustdoc-kernel
3932

40-
rustdoc-macros: private rustdoc_target_flags = --crate-type proc-macro \
33+
rustdoc-macros: private rustdoc_host = yes
34+
rustdoc-macros: private rustc_target_flags = --crate-type proc-macro \
4135
--extern proc_macro
4236
rustdoc-macros: $(srctree)/rust/macros/lib.rs FORCE
43-
$(call if_changed,rustdoc_host)
37+
$(call if_changed,rustdoc)
4438

4539
rustdoc-compiler_builtins: $(srctree)/rust/compiler_builtins.rs FORCE
4640
$(call if_changed,rustdoc)
4741

48-
rustdoc-kernel: private rustdoc_target_flags = --extern alloc \
42+
rustdoc-kernel: private rustc_target_flags = --extern alloc \
4943
--extern build_error \
5044
--extern macros=$(objtree)/rust/libmacros.so
5145
rustdoc-kernel: $(srctree)/rust/kernel/lib.rs rustdoc-macros \
5246
$(objtree)/rust/libmacros.so $(objtree)/rust/bindings_generated.rs FORCE
5347
$(call if_changed,rustdoc)
5448

49+
quiet_cmd_rustc_test_library = RUSTC TL $<
50+
cmd_rustc_test_library = \
51+
RUST_BINDINGS_FILE=$(abspath $(objtree)/rust/bindings_generated.rs) \
52+
$(RUSTC) $(filter-out -Cpanic=abort, $(filter-out --emit=%, $(rustc_flags))) \
53+
$(rustc_target_flags) --crate-type $(if $(rustc_test_library_proc),proc-macro,rlib) \
54+
--out-dir $(objtree)/rust/test/ --cfg testlib \
55+
-L $(objtree)/rust/test/ --crate-name $(subst rusttest-,,$(subst rusttestlib-,,$@)) $<
56+
57+
rusttestlib-build_error: $(srctree)/rust/build_error.rs FORCE
58+
$(call if_changed,rustc_test_library)
59+
60+
rusttestlib-macros: private rustc_target_flags = --extern proc_macro
61+
rusttestlib-macros: private rustc_test_library_proc = yes
62+
rusttestlib-macros: $(srctree)/rust/macros/lib.rs FORCE
63+
$(call if_changed,rustc_test_library)
64+
65+
# We cannot use `-Zpanic-abort-tests` because some tests are dynamic,
66+
# so for the moment we skip `-Cpanic=abort`.
67+
quiet_cmd_rustc_test = RUSTC T $<
68+
cmd_rustc_test = \
69+
RUST_BINDINGS_FILE=$(abspath $(objtree)/rust/bindings_generated.rs) \
70+
$(RUSTC) --test $(filter-out -Cpanic=abort, $(filter-out --emit=%, $(rustc_flags))) \
71+
$(rustc_target_flags) --out-dir $(objtree)/rust/test \
72+
-L $(objtree)/rust/test/ --crate-name $(subst rusttest-,,$@) $<; \
73+
$(objtree)/rust/test/$(subst rusttest-,,$@) $(rustc_test_run_flags)
74+
75+
rusttest: rusttest-macros rusttest-kernel
76+
77+
rusttest-macros: private rustc_target_flags = --extern proc_macro
78+
rusttest-macros: private rustdoc_host = yes
79+
rusttest-macros: private rustdoc_target_flags = --test --crate-type proc-macro
80+
rusttest-macros: $(srctree)/rust/macros/lib.rs FORCE
81+
$(call if_changed,rustc_test)
82+
$(call if_changed,rustdoc)
83+
84+
rusttest-kernel: private rustc_target_flags = --extern alloc \
85+
--extern build_error \
86+
--extern macros=$(objtree)/rust/test/libmacros.so
87+
rusttest-kernel: private rustc_test_run_flags = \
88+
--skip bindgen_test_layout_
89+
rusttest-kernel: private rustdoc_host = yes
90+
rusttest-kernel: private rustdoc_target_flags = --test
91+
rusttest-kernel: $(srctree)/rust/kernel/lib.rs rusttestlib-build_error \
92+
rusttestlib-macros FORCE
93+
$(call if_changed,rustc_test)
94+
$(call if_changed,rustc_test_library)
95+
$(call if_changed,rustdoc)
96+
5597
ifdef CONFIG_CC_IS_CLANG
5698
bindgen_c_flags = $(c_flags)
5799
else

rust/kernel/bindings.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44
//!
55
//! Imports the generated bindings by `bindgen`.
66
7+
// See https://github.com/rust-lang/rust-bindgen/issues/1651.
8+
#![cfg_attr(test, allow(deref_nullptr))]
9+
#![cfg_attr(test, allow(unaligned_references))]
10+
#![cfg_attr(test, allow(unsafe_op_in_unsafe_fn))]
11+
712
#[allow(
813
clippy::all,
914
non_camel_case_types,

rust/kernel/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
#[cfg(not(CONFIG_RUST))]
3535
compile_error!("Missing kernel configuration for conditional compilation");
3636

37+
#[cfg(not(test))]
38+
#[cfg(not(testlib))]
3739
mod allocator;
3840

3941
#[doc(hidden)]

0 commit comments

Comments
 (0)