Skip to content

Commit 73243a8

Browse files
committed
rust: generate bindings for helpers
Automatically generate rust bindings for helper functions via bindgen. The corresponding Rust bindings will have their `rust_helper_` prefix removed, so Rust code can call `bindings::foo` regardless whether `foo` is directly exposed or exposed via a helper. When both a directly exposed symbol and a helper exists, the directly exposed symbol will take precedence. Signed-off-by: Gary Guo <[email protected]>
1 parent c4d17fc commit 73243a8

File tree

4 files changed

+46
-11
lines changed

4 files changed

+46
-11
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1834,6 +1834,7 @@ rustfmt:
18341834
-o -path $(abs_objtree)/rust/test -prune \
18351835
| grep -Fv $(abs_srctree)/rust/alloc \
18361836
| grep -Fv $(abs_objtree)/rust/test \
1837+
| grep -Fv generated \
18371838
| xargs $(RUSTFMT) $(rustfmt_flags)
18381839

18391840
rustfmtcheck: rustfmt_flags = --check

rust/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# SPDX-License-Identifier: GPL-2.0
22

33
bindings_generated.rs
4+
bindings_helpers_generated.rs
45
exports_*_generated.h
56
doc/
67
test/

rust/Makefile

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ extra-$(CONFIG_RUST) += exports_core_generated.h
55

66
extra-$(CONFIG_RUST) += libmacros.so
77

8-
extra-$(CONFIG_RUST) += bindings_generated.rs
8+
extra-$(CONFIG_RUST) += bindings_generated.rs bindings_helpers_generated.rs
99
obj-$(CONFIG_RUST) += alloc.o kernel.o
1010
extra-$(CONFIG_RUST) += exports_alloc_generated.h exports_kernel_generated.h
1111

@@ -30,7 +30,7 @@ endif
3030

3131
quiet_cmd_rustdoc = RUSTDOC $(if $(rustdoc_host),H, ) $<
3232
cmd_rustdoc = \
33-
RUST_BINDINGS_FILE=$(abspath $(objtree)/rust/bindings_generated.rs) \
33+
OBJTREE=$(abspath $(objtree)) \
3434
$(RUSTDOC) $(if $(rustdoc_host),,$(rust_cross_flags)) \
3535
$(filter-out -Cpanic=abort, $(filter-out --emit=%, $(rust_flags))) \
3636
$(rustc_target_flags) -L $(objtree)/rust \
@@ -73,12 +73,13 @@ rustdoc-kernel: private rustc_target_flags = --extern alloc \
7373
--extern macros=$(objtree)/rust/libmacros.so
7474
rustdoc-kernel: $(srctree)/rust/kernel/lib.rs rustdoc-core \
7575
rustdoc-macros rustdoc-compiler_builtins rustdoc-alloc \
76-
$(objtree)/rust/libmacros.so $(objtree)/rust/bindings_generated.rs FORCE
76+
$(objtree)/rust/libmacros.so $(objtree)/rust/bindings_generated.rs \
77+
$(objtree)/rust/bindings_helpers_generated.rs FORCE
7778
$(call if_changed,rustdoc)
7879

7980
quiet_cmd_rustc_test_library = RUSTC TL $<
8081
cmd_rustc_test_library = \
81-
RUST_BINDINGS_FILE=$(abspath $(objtree)/rust/bindings_generated.rs) \
82+
OBJTREE=$(abspath $(objtree)) \
8283
$(RUSTC) $(filter-out --sysroot=%, $(filter-out -Cpanic=abort, $(filter-out --emit=%, $(rust_flags)))) \
8384
$(rustc_target_flags) --crate-type $(if $(rustc_test_library_proc),proc-macro,rlib) \
8485
--out-dir $(objtree)/rust/test/ --cfg testlib \
@@ -95,7 +96,7 @@ rusttestlib-macros: $(srctree)/rust/macros/lib.rs rusttest-prepare FORCE
9596

9697
quiet_cmd_rustdoc_test = RUSTDOC T $<
9798
cmd_rustdoc_test = \
98-
RUST_BINDINGS_FILE=$(abspath $(objtree)/rust/bindings_generated.rs) \
99+
OBJTREE=$(abspath $(objtree)) \
99100
$(RUSTDOC) --test $(filter-out --sysroot=%, $(filter-out -Cpanic=abort, $(filter-out --emit=%, $(rust_flags)))) \
100101
$(rustc_target_flags) $(rustdoc_test_target_flags) \
101102
--sysroot $(objtree)/rust/test/sysroot $(rustdoc_test_quiet) \
@@ -107,7 +108,7 @@ quiet_cmd_rustdoc_test = RUSTDOC T $<
107108
# so for the moment we skip `-Cpanic=abort`.
108109
quiet_cmd_rustc_test = RUSTC T $<
109110
cmd_rustc_test = \
110-
RUST_BINDINGS_FILE=$(abspath $(objtree)/rust/bindings_generated.rs) \
111+
OBJTREE=$(abspath $(objtree)) \
111112
$(RUSTC) --test $(filter-out --sysroot=%, $(filter-out -Cpanic=abort, $(filter-out --emit=%, $(rust_flags)))) \
112113
$(rustc_target_flags) --out-dir $(objtree)/rust/test \
113114
--sysroot $(objtree)/rust/test/sysroot \
@@ -230,6 +231,19 @@ $(objtree)/rust/bindings_generated.rs: $(srctree)/rust/kernel/bindings_helper.h
230231
$(srctree)/rust/bindgen_parameters FORCE
231232
$(call if_changed_dep,bindgen)
232233

234+
quiet_cmd_bindgen_helper = BINDGEN $@
235+
cmd_bindgen_helper = \
236+
$(BINDGEN) $< --blacklist-type '.*' --whitelist-var '' \
237+
--whitelist-function 'rust_helper_.*' \
238+
--use-core --with-derive-default --ctypes-prefix c_types \
239+
--no-debug '.*' \
240+
--size_t-is-usize -o $@ -- $(bindgen_c_flags_final) \
241+
-I$(objtree)/rust/ -DMODULE; \
242+
sed -Ei 's/pub fn rust_helper_([a-zA-Z0-9_]*)/\#[link_name="rust_helper_\1"]\n pub fn \1/g' $@
243+
244+
$(objtree)/rust/bindings_helpers_generated.rs: $(srctree)/rust/helpers.c FORCE
245+
$(call if_changed_dep,bindgen_helper)
246+
233247
quiet_cmd_exports = EXPORTS $@
234248
cmd_exports = \
235249
$(NM) -p --defined-only $< \
@@ -267,7 +281,7 @@ $(objtree)/rust/libmacros.so: $(srctree)/rust/macros/lib.rs \
267281

268282
quiet_cmd_rustc_library = $(if $(skip_clippy),RUSTC,$(RUSTC_OR_CLIPPY_QUIET)) L $@
269283
cmd_rustc_library = \
270-
RUST_BINDINGS_FILE=$(abspath $(objtree)/rust/bindings_generated.rs) \
284+
OBJTREE=$(abspath $(objtree)) \
271285
$(if $(skip_clippy),$(RUSTC),$(RUSTC_OR_CLIPPY)) \
272286
$(rust_flags) $(rust_cross_flags) $(rustc_target_flags) \
273287
--crate-type rlib --out-dir $(objtree)/rust/ -L $(objtree)/rust/ \
@@ -305,7 +319,8 @@ $(objtree)/rust/kernel.o: private rustc_target_flags = --extern alloc \
305319
--extern macros=$(objtree)/rust/libmacros.so
306320
$(objtree)/rust/kernel.o: $(srctree)/rust/kernel/lib.rs $(objtree)/rust/alloc.o \
307321
$(objtree)/rust/build_error.o \
308-
$(objtree)/rust/libmacros.so $(objtree)/rust/bindings_generated.rs FORCE
322+
$(objtree)/rust/libmacros.so $(objtree)/rust/bindings_generated.rs \
323+
$(objtree)/rust/bindings_helpers_generated.rs FORCE
309324
$(call if_changed_dep,rustc_library)
310325

311326
# Targets that need to expand twice

rust/kernel/bindings.rs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,37 @@
88
#![cfg_attr(test, allow(deref_nullptr))]
99
#![cfg_attr(test, allow(unaligned_references))]
1010
#![cfg_attr(test, allow(unsafe_op_in_unsafe_fn))]
11-
12-
#[allow(
11+
#![allow(
1312
clippy::all,
1413
non_camel_case_types,
1514
non_upper_case_globals,
1615
non_snake_case,
1716
improper_ctypes,
1817
unsafe_op_in_unsafe_fn
1918
)]
19+
2020
mod bindings_raw {
21+
// Use glob import here to expose all helpers.
22+
// Symbols defined within the module will take precedence to the glob import.
23+
pub use super::bindings_helper::*;
24+
use crate::c_types;
25+
include!(concat!(env!("OBJTREE"), "/rust/bindings_generated.rs"));
26+
}
27+
28+
// When both a directly exposed symbol and a helper exists for the same function,
29+
// the directly exposed symbol is preferred and the helper becomes dead code, so
30+
// ignore the warning here.
31+
#[allow(dead_code)]
32+
mod bindings_helper {
33+
// Import the generated bindings for types.
34+
use super::bindings_raw::*;
2135
use crate::c_types;
22-
include!(env!("RUST_BINDINGS_FILE"));
36+
include!(concat!(
37+
env!("OBJTREE"),
38+
"/rust/bindings_helpers_generated.rs"
39+
));
2340
}
41+
2442
pub use bindings_raw::*;
2543

2644
pub const GFP_KERNEL: gfp_t = BINDINGS_GFP_KERNEL;

0 commit comments

Comments
 (0)