From b0ec4c8bb189a5bc15eba64057e5ffe404d2f116 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 9 Jul 2022 18:03:07 +0200 Subject: [PATCH 1/2] Split bindings crate out of the main kernel crate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The generated bindings are mostly static when working on new rust abstractions. By splitting them off the main kernel crate, recompilation of the main kernel crate takes ~2s rather than ~12s. While this loses some optimizations without LTO, the fast majority of the binding functions are already marked as `#[inline]`. Pretty much only `Default` impls aren't marked as such. The cost of not inlining those `Default` impls is likely neglectable. Signed-off-by: Björn Roy Baron --- rust/Makefile | 33 +++++++++++++++++++++---------- rust/exports.c | 1 + rust/kernel/bindings.rs | 7 +++++++ rust/kernel/lib.rs | 2 +- scripts/generate_rust_analyzer.py | 11 +++++++++-- 5 files changed, 41 insertions(+), 13 deletions(-) diff --git a/rust/Makefile b/rust/Makefile index 4fc9ebad83732e..5b81c1f17b8162 100644 --- a/rust/Makefile +++ b/rust/Makefile @@ -15,8 +15,9 @@ always-$(CONFIG_RUST) += libmacros.so no-clean-files += libmacros.so always-$(CONFIG_RUST) += bindings_generated.rs bindings_helpers_generated.rs -obj-$(CONFIG_RUST) += alloc.o kernel.o -always-$(CONFIG_RUST) += exports_alloc_generated.h exports_kernel_generated.h +obj-$(CONFIG_RUST) += alloc.o bindings.o kernel.o +always-$(CONFIG_RUST) += exports_alloc_generated.h exports_bindings_generated.h \ + exports_kernel_generated.h ifdef CONFIG_RUST_BUILD_ASSERT_DENY always-$(CONFIG_RUST) += build_error.o @@ -110,10 +111,11 @@ rustdoc-alloc: $(src)/alloc/lib.rs rustdoc-core rustdoc-compiler_builtins FORCE $(call if_changed,rustdoc) rustdoc-kernel: private rustc_target_flags = --extern alloc \ - --extern build_error --extern macros=$(objtree)/$(obj)/libmacros.so + --extern build_error --extern macros=$(objtree)/$(obj)/libmacros.so \ + --extern bindings rustdoc-kernel: $(src)/kernel/lib.rs rustdoc-core rustdoc-macros \ rustdoc-compiler_builtins rustdoc-alloc $(obj)/libmacros.so \ - $(obj)/bindings_generated.rs $(obj)/bindings_helpers_generated.rs FORCE + $(obj)/bindings.o FORCE $(call if_changed,rustdoc) quiet_cmd_rustc_test_library = RUSTC TL $< @@ -135,6 +137,9 @@ rusttestlib-macros: private rustc_test_library_proc = yes rusttestlib-macros: $(src)/macros/lib.rs rusttest-prepare FORCE $(call if_changed,rustc_test_library) +rusttestlib-bindings: $(src)/bindings/lib.rs rusttest-prepare FORCE + $(call if_changed,rustc_test_library) + quiet_cmd_rustdoc_test = RUSTDOC T $< cmd_rustdoc_test = \ OBJTREE=$(abspath $(objtree)) \ @@ -154,6 +159,7 @@ quiet_cmd_rustdoc_test_kernel = RUSTDOC TK $< @$(objtree)/include/generated/rustc_cfg \ -L$(objtree)/$(obj) --extern alloc --extern kernel \ --extern build_error --extern macros \ + --extern bindings \ --no-run --crate-name kernel -Zunstable-options \ --test-builder $(srctree)/scripts/rustdoc_test_builder.py \ $< $(rustdoc_test_kernel_quiet); \ @@ -234,10 +240,9 @@ rusttest-macros: $(src)/macros/lib.rs rusttest-prepare FORCE $(call if_changed,rustdoc_test) rusttest-kernel: private rustc_target_flags = --extern alloc \ - --extern build_error --extern macros -rusttest-kernel: private rustc_test_run_flags = --skip bindgen_test_layout_ + --extern build_error --extern macros --extern bindings rusttest-kernel: $(src)/kernel/lib.rs rusttest-prepare \ - rusttestlib-build_error rusttestlib-macros FORCE + rusttestlib-build_error rusttestlib-macros rusttestlib-bindings FORCE $(call if_changed,rustc_test) $(call if_changed,rustc_test_library) @@ -335,6 +340,9 @@ $(obj)/exports_core_generated.h: $(obj)/core.o FORCE $(obj)/exports_alloc_generated.h: $(obj)/alloc.o FORCE $(call if_changed,exports) +$(obj)/exports_bindings_generated.h: $(obj)/bindings.o FORCE + $(call if_changed,exports) + $(obj)/exports_kernel_generated.h: $(obj)/kernel.o FORCE $(call if_changed,exports) @@ -388,11 +396,16 @@ $(obj)/alloc.o: $(src)/alloc/lib.rs $(obj)/compiler_builtins.o FORCE $(obj)/build_error.o: $(src)/build_error.rs $(obj)/compiler_builtins.o FORCE $(call if_changed_dep,rustc_library) +$(obj)/bindings.o: $(src)/kernel/bindings.rs \ + $(obj)/compiler_builtins.o \ + $(obj)/bindings_generated.rs \ + $(obj)/bindings_helpers_generated.rs FORCE + $(call if_changed_dep,rustc_library) + $(obj)/kernel.o: private rustc_target_flags = --extern alloc \ - --extern build_error --extern macros + --extern build_error --extern macros --extern bindings $(obj)/kernel.o: $(src)/kernel/lib.rs $(obj)/alloc.o $(obj)/build_error.o \ - $(obj)/libmacros.so $(obj)/bindings_generated.rs \ - $(obj)/bindings_helpers_generated.rs FORCE + $(obj)/libmacros.so $(obj)/bindings.o FORCE $(call if_changed_dep,rustc_library) endif # CONFIG_RUST diff --git a/rust/exports.c b/rust/exports.c index fe3dcfdd6fbf6e..43c6ee7d98e5fa 100644 --- a/rust/exports.c +++ b/rust/exports.c @@ -17,4 +17,5 @@ #include "exports_core_generated.h" #include "exports_alloc_generated.h" +#include "exports_bindings_generated.h" #include "exports_kernel_generated.h" diff --git a/rust/kernel/bindings.rs b/rust/kernel/bindings.rs index 9694b5974fec8d..2005bf1db84033 100644 --- a/rust/kernel/bindings.rs +++ b/rust/kernel/bindings.rs @@ -3,13 +3,20 @@ //! Bindings. //! //! Imports the generated bindings by `bindgen`. +//! +//! This crate may not be directly used. If you need a kernel C API that is +//! not ported or wrapped in the `kernel` crate, then do so first instead of +//! using this crate. +#![no_std] +#![feature(core_ffi_c)] // See https://github.com/rust-lang/rust-bindgen/issues/1651. #![cfg_attr(test, allow(deref_nullptr))] #![cfg_attr(test, allow(unaligned_references))] #![cfg_attr(test, allow(unsafe_op_in_unsafe_fn))] #![allow( clippy::all, + missing_docs, non_camel_case_types, non_upper_case_globals, non_snake_case, diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index 8eb203a99c21db..d752b6f6352f2a 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs @@ -39,7 +39,7 @@ compile_error!("Missing kernel configuration for conditional compilation"); mod allocator; #[doc(hidden)] -pub mod bindings; +pub use bindings; #[cfg(CONFIG_ARM_AMBA)] pub mod amba; diff --git a/scripts/generate_rust_analyzer.py b/scripts/generate_rust_analyzer.py index 37c049fb18f257..1d5ff66c11b7e2 100755 --- a/scripts/generate_rust_analyzer.py +++ b/scripts/generate_rust_analyzer.py @@ -73,13 +73,20 @@ def append_crate(display_name, root_module, deps, cfg=[], is_workspace_member=Tr ["core", "compiler_builtins"], ) + append_crate( + "bindings", + srctree / "rust"/ "kernel" / "bindings.rs", + ["core"], + cfg=cfg, + ) + crates[-1]["env"]["OBJTREE"] = str(objtree.resolve(True)) + append_crate( "kernel", srctree / "rust" / "kernel" / "lib.rs", - ["core", "alloc", "macros", "build_error"], + ["core", "alloc", "macros", "build_error", "bindings"], cfg=cfg, ) - crates[-1]["env"]["OBJTREE"] = str(objtree.resolve(True)) crates[-1]["source"] = { "include_dirs": [ str(srctree / "rust" / "kernel"), From 521024c4ef5d44192b67fa599356ec8aacb1ac0e Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 9 Jul 2022 18:09:56 +0200 Subject: [PATCH 2/2] Move bindings related code to rust/bindings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Björn Roy Baron --- rust/Makefile | 22 ++++++++++---------- rust/{kernel => bindings}/bindings_helper.h | 0 rust/{kernel/bindings.rs => bindings/lib.rs} | 7 +++++-- scripts/generate_rust_analyzer.py | 2 +- 4 files changed, 17 insertions(+), 14 deletions(-) rename rust/{kernel => bindings}/bindings_helper.h (100%) rename rust/{kernel/bindings.rs => bindings/lib.rs} (90%) diff --git a/rust/Makefile b/rust/Makefile index 5b81c1f17b8162..a64c63c06a9f5c 100644 --- a/rust/Makefile +++ b/rust/Makefile @@ -14,7 +14,7 @@ CFLAGS_REMOVE_helpers.o = -Wmissing-prototypes -Wmissing-declarations always-$(CONFIG_RUST) += libmacros.so no-clean-files += libmacros.so -always-$(CONFIG_RUST) += bindings_generated.rs bindings_helpers_generated.rs +always-$(CONFIG_RUST) += bindings/bindings_generated.rs bindings/bindings_helpers_generated.rs obj-$(CONFIG_RUST) += alloc.o bindings.o kernel.o always-$(CONFIG_RUST) += exports_alloc_generated.h exports_bindings_generated.h \ exports_kernel_generated.h @@ -307,9 +307,9 @@ quiet_cmd_bindgen = BINDGEN $@ --size_t-is-usize -o $@ -- $(bindgen_c_flags_final) -DMODULE \ $(bindgen_target_cflags) $(bindgen_target_extra) -$(obj)/bindings_generated.rs: private bindgen_target_flags = \ +$(obj)/bindings/bindings_generated.rs: private bindgen_target_flags = \ $(shell grep -v '^\#\|^$$' $(srctree)/$(src)/bindgen_parameters) -$(obj)/bindings_generated.rs: $(src)/kernel/bindings_helper.h \ +$(obj)/bindings/bindings_generated.rs: $(src)/bindings/bindings_helper.h \ $(src)/bindgen_parameters FORCE $(call if_changed_dep,bindgen) @@ -317,14 +317,14 @@ $(obj)/bindings_generated.rs: $(src)/kernel/bindings_helper.h \ # with `-Wmissing-declarations` (unlike GCC), so it is not strictly needed here # given it is `libclang`; but for consistency, future Clang changes and/or # a potential future GCC backend for `bindgen`, we disable it too. -$(obj)/bindings_helpers_generated.rs: private bindgen_target_flags = \ +$(obj)/bindings/bindings_helpers_generated.rs: private bindgen_target_flags = \ --blacklist-type '.*' --whitelist-var '' \ --whitelist-function 'rust_helper_.*' -$(obj)/bindings_helpers_generated.rs: private bindgen_target_cflags = \ +$(obj)/bindings/bindings_helpers_generated.rs: private bindgen_target_cflags = \ -I$(objtree)/$(obj) -Wno-missing-prototypes -Wno-missing-declarations -$(obj)/bindings_helpers_generated.rs: private bindgen_target_extra = ; \ +$(obj)/bindings/bindings_helpers_generated.rs: private bindgen_target_extra = ; \ sed -Ei 's/pub fn rust_helper_([a-zA-Z0-9_]*)/#[link_name="rust_helper_\1"]\n pub fn \1/g' $@ -$(obj)/bindings_helpers_generated.rs: $(src)/helpers.c FORCE +$(obj)/bindings/bindings_helpers_generated.rs: $(src)/helpers.c FORCE $(call if_changed_dep,bindgen) quiet_cmd_exports = EXPORTS $@ @@ -396,10 +396,10 @@ $(obj)/alloc.o: $(src)/alloc/lib.rs $(obj)/compiler_builtins.o FORCE $(obj)/build_error.o: $(src)/build_error.rs $(obj)/compiler_builtins.o FORCE $(call if_changed_dep,rustc_library) -$(obj)/bindings.o: $(src)/kernel/bindings.rs \ - $(obj)/compiler_builtins.o \ - $(obj)/bindings_generated.rs \ - $(obj)/bindings_helpers_generated.rs FORCE +$(obj)/bindings.o: $(src)/bindings/lib.rs \ + $(obj)/compiler_builtins.o \ + $(obj)/bindings/bindings_generated.rs \ + $(obj)/bindings/bindings_helpers_generated.rs FORCE $(call if_changed_dep,rustc_library) $(obj)/kernel.o: private rustc_target_flags = --extern alloc \ diff --git a/rust/kernel/bindings_helper.h b/rust/bindings/bindings_helper.h similarity index 100% rename from rust/kernel/bindings_helper.h rename to rust/bindings/bindings_helper.h diff --git a/rust/kernel/bindings.rs b/rust/bindings/lib.rs similarity index 90% rename from rust/kernel/bindings.rs rename to rust/bindings/lib.rs index 2005bf1db84033..c68de267b643ad 100644 --- a/rust/kernel/bindings.rs +++ b/rust/bindings/lib.rs @@ -29,7 +29,10 @@ mod bindings_raw { // Use glob import here to expose all helpers. // Symbols defined within the module will take precedence to the glob import. pub use super::bindings_helper::*; - include!(concat!(env!("OBJTREE"), "/rust/bindings_generated.rs")); + include!(concat!( + env!("OBJTREE"), + "/rust/bindings/bindings_generated.rs" + )); } // When both a directly exposed symbol and a helper exists for the same function, @@ -41,7 +44,7 @@ mod bindings_helper { use super::bindings_raw::*; include!(concat!( env!("OBJTREE"), - "/rust/bindings_helpers_generated.rs" + "/rust/bindings/bindings_helpers_generated.rs" )); } diff --git a/scripts/generate_rust_analyzer.py b/scripts/generate_rust_analyzer.py index 1d5ff66c11b7e2..ecc7ea9a4dcfc6 100755 --- a/scripts/generate_rust_analyzer.py +++ b/scripts/generate_rust_analyzer.py @@ -75,7 +75,7 @@ def append_crate(display_name, root_module, deps, cfg=[], is_workspace_member=Tr append_crate( "bindings", - srctree / "rust"/ "kernel" / "bindings.rs", + srctree / "rust"/ "bindings" / "lib.rs", ["core"], cfg=cfg, )