Skip to content

Commit

Permalink
rust: depend on syn
Browse files Browse the repository at this point in the history
add `syn` and others as dependencies of `macros` crate, and use cargo
to build `macros` crate. Only host-facing `libmacros.so` is built this
way, not any of the other crates that are compiled for the target. This
cargo invocation has all crate versions locked and has `--offline`
option specified, so it won't access Internet during the build.

The current `module!` crate already shows it tedious and limited for
writing proc macros without `syn`. Pinning and vtable handling could
likely be drastically improved with the help of proc macros, and they
will require parsing Rust struct/trait/impl blocks. A dependency on
`syn` is highly desirable to avoid us essentially reinventing the wheel
when building our procedural macros.

A `make rust-fetch-deps` command is added and listed in the
documentation as a build requirement.

Signed-off-by: Gary Guo <[email protected]>
  • Loading branch information
nbdd0121 committed May 26, 2021
1 parent 03ecf73 commit 293ae4c
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 16 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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: |
Expand Down
12 changes: 12 additions & 0 deletions Documentation/rust/quick-start.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
------------------------

Expand Down
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion rust/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@

bindings_generated.rs
exports_*_generated.h
doc/
doc/
target/
30 changes: 15 additions & 15 deletions rust/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -35,20 +35,15 @@ 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)

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)

Expand Down Expand Up @@ -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)

Expand Down
47 changes: 47 additions & 0 deletions rust/macros/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions rust/macros/Cargo.toml
Original file line number Diff line number Diff line change
@@ -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"

0 comments on commit 293ae4c

Please sign in to comment.