diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index ffe91c6beb7417..f285fce0e68014 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -205,6 +205,10 @@ jobs: - run: | curl -o bin/bindgen https://raw.githubusercontent.com/Rust-for-Linux/ci-bin/master/bindgen-0.56.0/bin/bindgen chmod u+x bin/bindgen + + # Setup: Procedural macro dependencies + - run: | + make rust-fetch-deps # Setup: ccache - run: | diff --git a/Documentation/rust/quick-start.rst b/Documentation/rust/quick-start.rst index 43965f8535ee8c..326267e7cd01cb 100644 --- a/Documentation/rust/quick-start.rst +++ b/Documentation/rust/quick-start.rst @@ -89,6 +89,18 @@ Install it via (this will build the tool from source):: cargo install --locked --version 0.56.0 bindgen +Procedural macro dependencies +***************************** + +We use procedural macros that need to parse Rust code. We depends on a few +well-established crate in Rust community (`syn`, `quote` and `proc-macro2`) +for this task. + +Fetch it via:: + + make rust-fetch-deps + + Requirements: Developing ------------------------ diff --git a/Makefile b/Makefile index 2c4bac4898e0a8..1d089f02d38115 100644 --- a/Makefile +++ b/Makefile @@ -1832,6 +1832,11 @@ rustfmt: rustfmtcheck: find $(srctree) -type f -name '*.rs' | xargs $(RUSTFMT) --check +# Procedural macros dependency fetch +PHONY += rust-fetch-deps +rust-fetch-deps: + $(Q)$(MAKE) $(build)=rust $@ + # IDE support targets PHONY += rust-analyzer rust-analyzer: prepare0 diff --git a/rust/.gitignore b/rust/.gitignore index 8875e08ed0b17e..0cc32e0350e7a5 100644 --- a/rust/.gitignore +++ b/rust/.gitignore @@ -2,4 +2,5 @@ bindings_generated.rs exports_*_generated.h -doc/ \ No newline at end of file +doc/ +target/ diff --git a/rust/Makefile b/rust/Makefile index 9e94e687007217..52120641cd0ddd 100644 --- a/rust/Makefile +++ b/rust/Makefile @@ -35,12 +35,7 @@ quiet_cmd_rustdoc = RUSTDOC $< --output $(objtree)/rust/doc --crate-name $(subst rustdoc-,,$@) \ -Fmissing-docs @$(objtree)/include/generated/rustc_cfg $< -rustdoc: rustdoc-macros rustdoc-compiler_builtins rustdoc-kernel - -rustdoc-macros: private rustdoc_target_flags = --crate-type proc-macro \ - --extern proc_macro -rustdoc-macros: $(srctree)/rust/macros/lib.rs FORCE - $(call if_changed,rustdoc_host) +rustdoc: rustdoc-compiler_builtins rustdoc-kernel rustdoc-compiler_builtins: $(srctree)/rust/compiler_builtins.rs FORCE $(call if_changed,rustdoc) @@ -48,7 +43,7 @@ rustdoc-compiler_builtins: $(srctree)/rust/compiler_builtins.rs FORCE rustdoc-kernel: private rustdoc_target_flags = --extern alloc \ --extern build_error \ --extern macros=$(objtree)/rust/libmacros.so -rustdoc-kernel: $(srctree)/rust/kernel/lib.rs rustdoc-macros \ +rustdoc-kernel: $(srctree)/rust/kernel/lib.rs \ $(objtree)/rust/libmacros.so $(objtree)/rust/bindings_generated.rs FORCE $(call if_changed,rustdoc) @@ -113,22 +108,27 @@ $(objtree)/rust/exports_alloc_generated.h: $(objtree)/rust/alloc.o FORCE $(objtree)/rust/exports_kernel_generated.h: $(objtree)/rust/kernel.o FORCE $(call if_changed,exports) +CARGO = cargo + # `-Cpanic=unwind -Cforce-unwind-tables=y` overrides `rustc_flags` in order to # avoid the https://github.com/rust-lang/rust/issues/82320 rustc crash. -quiet_cmd_rustc_procmacro = $(RUSTC_OR_CLIPPY_QUIET) P $@ +quiet_cmd_rustc_procmacro = CARGO P $@ cmd_rustc_procmacro = \ - $(RUSTC_OR_CLIPPY) $(rustc_flags) \ - --emit=dep-info,link --extern proc_macro \ - -Cpanic=unwind -Cforce-unwind-tables=y \ - --crate-type proc-macro --out-dir $(objtree)/rust/ \ - --crate-name $(patsubst lib%.so,%,$(notdir $@)) $<; \ - mv $(objtree)/rust/$(patsubst lib%.so,%,$(notdir $@)).d $(depfile); \ + $(CARGO) build --locked --offline --release \ + --manifest-path $< \ + --target-dir $(objtree)/rust/target; \ + cp $(objtree)/rust/target/release/$(notdir $@) $@; \ + mv $(objtree)/rust/target/release/$(patsubst %.so,%,$(notdir $@)).d $(depfile); \ + sed -i 's/build.rs//' $(depfile); \ sed -i '/^\#/d' $(depfile) +rust-fetch-deps: + $(CARGO) fetch --locked --manifest-path $(srctree)/rust/macros/Cargo.toml + # Procedural macros can only be used with the `rustc` that compiled it. # Therefore, to get `libmacros.so` automatically recompiled when the compiler # version changes, we add `core.o` as a dependency (even if it is not needed). -$(objtree)/rust/libmacros.so: $(srctree)/rust/macros/lib.rs \ +$(objtree)/rust/libmacros.so: $(srctree)/rust/macros/Cargo.toml \ $(objtree)/rust/core.o FORCE $(call if_changed_dep,rustc_procmacro) diff --git a/rust/macros/Cargo.lock b/rust/macros/Cargo.lock new file mode 100644 index 00000000000000..bf7d701398dd21 --- /dev/null +++ b/rust/macros/Cargo.lock @@ -0,0 +1,47 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "macros" +version = "0.0.0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "proc-macro2" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "syn" +version = "1.0.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1e8cdbefb79a9a5a65e0db8b47b723ee907b7c7f8496c76a1770b5c310bab82" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" diff --git a/rust/macros/Cargo.toml b/rust/macros/Cargo.toml new file mode 100644 index 00000000000000..de6efaa04ce1bb --- /dev/null +++ b/rust/macros/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "macros" +version = "0.0.0" +edition = "2018" +license = "GPL-2.0-only" + +[lib] +path = "lib.rs" +proc_macro = true + +[dependencies] +syn = { version = "1.0", features = ["full"] } +quote = "1.0" +proc-macro2 = "1.0"