]>
Commit | Line | Data |
---|---|---|
2f7ab126 MO |
1 | # SPDX-License-Identifier: GPL-2.0 |
2 | ||
48fadf44 CB |
3 | # Where to place rustdoc generated documentation |
4 | rustdoc_output := $(objtree)/Documentation/output/rust/rustdoc | |
5 | ||
d072acda | 6 | obj-$(CONFIG_RUST) += core.o compiler_builtins.o ffi.o |
2f7ab126 MO |
7 | always-$(CONFIG_RUST) += exports_core_generated.h |
8 | ||
9 | # Missing prototypes are expected in the helpers since these are exported | |
10 | # for Rust only, thus there is no header nor prototypes. | |
87634653 AH |
11 | obj-$(CONFIG_RUST) += helpers/helpers.o |
12 | CFLAGS_REMOVE_helpers/helpers.o = -Wmissing-prototypes -Wmissing-declarations | |
2f7ab126 | 13 | |
2f7ab126 | 14 | always-$(CONFIG_RUST) += bindings/bindings_generated.rs bindings/bindings_helpers_generated.rs |
392e34b6 DK |
15 | obj-$(CONFIG_RUST) += bindings.o kernel.o |
16 | always-$(CONFIG_RUST) += exports_helpers_generated.h \ | |
e26fa546 | 17 | exports_bindings_generated.h exports_kernel_generated.h |
2f7ab126 | 18 | |
4e174665 AL |
19 | always-$(CONFIG_RUST) += uapi/uapi_generated.rs |
20 | obj-$(CONFIG_RUST) += uapi.o | |
21 | ||
ecaa6ddf GG |
22 | ifdef CONFIG_RUST_BUILD_ASSERT_ALLOW |
23 | obj-$(CONFIG_RUST) += build_error.o | |
24 | else | |
25 | always-$(CONFIG_RUST) += build_error.o | |
26 | endif | |
27 | ||
2f7ab126 MO |
28 | obj-$(CONFIG_RUST) += exports.o |
29 | ||
a66d733d MO |
30 | always-$(CONFIG_RUST_KERNEL_DOCTESTS) += doctests_kernel_generated.rs |
31 | always-$(CONFIG_RUST_KERNEL_DOCTESTS) += doctests_kernel_generated_kunit.c | |
32 | ||
33 | obj-$(CONFIG_RUST_KERNEL_DOCTESTS) += doctests_kernel_generated.o | |
34 | obj-$(CONFIG_RUST_KERNEL_DOCTESTS) += doctests_kernel_generated_kunit.o | |
35 | ||
8af7a501 | 36 | always-$(subst y,$(CONFIG_RUST),$(CONFIG_JUMP_LABEL)) += kernel/generated_arch_static_branch_asm.rs |
169484ab | 37 | |
0730422b | 38 | # Avoids running `$(RUSTC)` when it may not be available. |
2f7ab126 MO |
39 | ifdef CONFIG_RUST |
40 | ||
0730422b TD |
41 | libmacros_name := $(shell MAKEFLAGS= $(RUSTC) --print file-names --crate-name macros --crate-type proc-macro - </dev/null) |
42 | libmacros_extension := $(patsubst libmacros.%,%,$(libmacros_name)) | |
43 | ||
44 | always-$(CONFIG_RUST) += $(libmacros_name) | |
45 | ||
2f7ab126 | 46 | # `$(rust_flags)` is passed in case the user added `--sysroot`. |
ecab4115 | 47 | rustc_sysroot := $(shell MAKEFLAGS= $(RUSTC) $(rust_flags) --print sysroot) |
2f7ab126 MO |
48 | rustc_host_target := $(shell $(RUSTC) --version --verbose | grep -F 'host: ' | cut -d' ' -f2) |
49 | RUST_LIB_SRC ?= $(rustc_sysroot)/lib/rustlib/src/rust/library | |
50 | ||
9ffc80c8 | 51 | ifneq ($(quiet),) |
2f7ab126 MO |
52 | rust_test_quiet=-q |
53 | rustdoc_test_quiet=--test-args -q | |
a66d733d | 54 | rustdoc_test_kernel_quiet=>/dev/null |
2f7ab126 MO |
55 | endif |
56 | ||
57 | core-cfgs = \ | |
58 | --cfg no_fp_fmt_parse | |
59 | ||
2f7ab126 MO |
60 | quiet_cmd_rustdoc = RUSTDOC $(if $(rustdoc_host),H, ) $< |
61 | cmd_rustdoc = \ | |
62 | OBJTREE=$(abspath $(objtree)) \ | |
bef83245 | 63 | $(RUSTDOC) $(filter-out $(skip_flags),$(if $(rustdoc_host),$(rust_common_flags),$(rust_flags))) \ |
2f7ab126 | 64 | $(rustc_target_flags) -L$(objtree)/$(obj) \ |
6e6efc5f | 65 | -Zunstable-options --generate-link-to-definition \ |
48fadf44 | 66 | --output $(rustdoc_output) \ |
2f7ab126 | 67 | --crate-name $(subst rustdoc-,,$@) \ |
71479eee | 68 | $(if $(rustdoc_host),,--sysroot=/dev/null) \ |
2f7ab126 MO |
69 | @$(objtree)/include/generated/rustc_cfg $< |
70 | ||
71 | # The `html_logo_url` and `html_favicon_url` forms of the `doc` attribute | |
72 | # can be used to specify a custom logo. However: | |
73 | # - The given value is used as-is, thus it cannot be relative or a local file | |
74 | # (unlike the non-custom case) since the generated docs have subfolders. | |
75 | # - It requires adding it to every crate. | |
76 | # - It requires changing `core` which comes from the sysroot. | |
77 | # | |
78 | # Using `-Zcrate-attr` would solve the last two points, but not the first. | |
79 | # The https://github.com/rust-lang/rfcs/pull/3226 RFC suggests two new | |
80 | # command-like flags to solve the issue. Meanwhile, we use the non-custom case | |
81 | # and then retouch the generated files. | |
82 | rustdoc: rustdoc-core rustdoc-macros rustdoc-compiler_builtins \ | |
392e34b6 | 83 | rustdoc-kernel |
cfd96726 MO |
84 | $(Q)cp $(srctree)/Documentation/images/logo.svg $(rustdoc_output)/static.files/ |
85 | $(Q)cp $(srctree)/Documentation/images/COPYING-logo $(rustdoc_output)/static.files/ | |
48fadf44 | 86 | $(Q)find $(rustdoc_output) -name '*.html' -type f -print0 | xargs -0 sed -Ei \ |
cfd96726 MO |
87 | -e 's:rust-logo-[0-9a-f]+\.svg:logo.svg:g' \ |
88 | -e 's:favicon-[0-9a-f]+\.svg:logo.svg:g' \ | |
bc2e7d5c | 89 | -e 's:<link rel="alternate icon" type="image/png" href="[/.]+/static\.files/favicon-(16x16|32x32)-[0-9a-f]+\.png">::g' \ |
e2bad142 | 90 | -e 's:<a href="srctree/([^"]+)">:<a href="$(realpath $(srctree))/\1">:g' |
cfd96726 MO |
91 | $(Q)for f in $(rustdoc_output)/static.files/rustdoc-*.css; do \ |
92 | echo ".logo-container > img { object-fit: contain; }" >> $$f; done | |
2f7ab126 MO |
93 | |
94 | rustdoc-macros: private rustdoc_host = yes | |
95 | rustdoc-macros: private rustc_target_flags = --crate-type proc-macro \ | |
96 | --extern proc_macro | |
97 | rustdoc-macros: $(src)/macros/lib.rs FORCE | |
ecab4115 | 98 | +$(call if_changed,rustdoc) |
2f7ab126 | 99 | |
bef83245 MO |
100 | # Starting with Rust 1.82.0, skipping `-Wrustdoc::unescaped_backticks` should |
101 | # not be needed -- see https://github.com/rust-lang/rust/pull/128307. | |
102 | rustdoc-core: private skip_flags = -Wrustdoc::unescaped_backticks | |
2f7ab126 MO |
103 | rustdoc-core: private rustc_target_flags = $(core-cfgs) |
104 | rustdoc-core: $(RUST_LIB_SRC)/core/src/lib.rs FORCE | |
ecab4115 | 105 | +$(call if_changed,rustdoc) |
2f7ab126 MO |
106 | |
107 | rustdoc-compiler_builtins: $(src)/compiler_builtins.rs rustdoc-core FORCE | |
ecab4115 | 108 | +$(call if_changed,rustdoc) |
2f7ab126 | 109 | |
d072acda | 110 | rustdoc-ffi: $(src)/ffi.rs rustdoc-core FORCE |
ecab4115 | 111 | +$(call if_changed,rustdoc) |
2f7ab126 | 112 | |
d072acda | 113 | rustdoc-kernel: private rustc_target_flags = --extern ffi \ |
0730422b | 114 | --extern build_error --extern macros \ |
4e174665 | 115 | --extern bindings --extern uapi |
d072acda | 116 | rustdoc-kernel: $(src)/kernel/lib.rs rustdoc-core rustdoc-ffi rustdoc-macros \ |
0730422b | 117 | rustdoc-compiler_builtins $(obj)/$(libmacros_name) \ |
2f7ab126 | 118 | $(obj)/bindings.o FORCE |
ecab4115 | 119 | +$(call if_changed,rustdoc) |
2f7ab126 | 120 | |
2a87f8b0 | 121 | quiet_cmd_rustc_test_library = $(RUSTC_OR_CLIPPY_QUIET) TL $< |
2f7ab126 MO |
122 | cmd_rustc_test_library = \ |
123 | OBJTREE=$(abspath $(objtree)) \ | |
2a87f8b0 | 124 | $(RUSTC_OR_CLIPPY) $(rust_common_flags) \ |
2f7ab126 MO |
125 | @$(objtree)/include/generated/rustc_cfg $(rustc_target_flags) \ |
126 | --crate-type $(if $(rustc_test_library_proc),proc-macro,rlib) \ | |
127 | --out-dir $(objtree)/$(obj)/test --cfg testlib \ | |
2f7ab126 MO |
128 | -L$(objtree)/$(obj)/test \ |
129 | --crate-name $(subst rusttest-,,$(subst rusttestlib-,,$@)) $< | |
130 | ||
9ffc80c8 | 131 | rusttestlib-build_error: $(src)/build_error.rs FORCE |
ecab4115 | 132 | +$(call if_changed,rustc_test_library) |
ecaa6ddf | 133 | |
d072acda GG |
134 | rusttestlib-ffi: $(src)/ffi.rs FORCE |
135 | +$(call if_changed,rustc_test_library) | |
136 | ||
2f7ab126 MO |
137 | rusttestlib-macros: private rustc_target_flags = --extern proc_macro |
138 | rusttestlib-macros: private rustc_test_library_proc = yes | |
9ffc80c8 | 139 | rusttestlib-macros: $(src)/macros/lib.rs FORCE |
ecab4115 | 140 | +$(call if_changed,rustc_test_library) |
2f7ab126 | 141 | |
d072acda | 142 | rusttestlib-kernel: private rustc_target_flags = --extern ffi \ |
b2c261fa ET |
143 | --extern build_error --extern macros \ |
144 | --extern bindings --extern uapi | |
145 | rusttestlib-kernel: $(src)/kernel/lib.rs \ | |
146 | rusttestlib-bindings rusttestlib-uapi rusttestlib-build_error \ | |
b1749432 | 147 | $(obj)/$(libmacros_name) $(obj)/bindings.o FORCE |
b2c261fa ET |
148 | +$(call if_changed,rustc_test_library) |
149 | ||
d072acda GG |
150 | rusttestlib-bindings: private rustc_target_flags = --extern ffi |
151 | rusttestlib-bindings: $(src)/bindings/lib.rs rusttestlib-ffi FORCE | |
ecab4115 | 152 | +$(call if_changed,rustc_test_library) |
2f7ab126 | 153 | |
d072acda GG |
154 | rusttestlib-uapi: private rustc_target_flags = --extern ffi |
155 | rusttestlib-uapi: $(src)/uapi/lib.rs rusttestlib-ffi FORCE | |
ecab4115 | 156 | +$(call if_changed,rustc_test_library) |
4e174665 | 157 | |
2f7ab126 MO |
158 | quiet_cmd_rustdoc_test = RUSTDOC T $< |
159 | cmd_rustdoc_test = \ | |
8d3f5079 | 160 | RUST_MODFILE=test.rs \ |
2f7ab126 MO |
161 | OBJTREE=$(abspath $(objtree)) \ |
162 | $(RUSTDOC) --test $(rust_common_flags) \ | |
163 | @$(objtree)/include/generated/rustc_cfg \ | |
164 | $(rustc_target_flags) $(rustdoc_test_target_flags) \ | |
9ffc80c8 | 165 | $(rustdoc_test_quiet) \ |
48fadf44 | 166 | -L$(objtree)/$(obj)/test --output $(rustdoc_output) \ |
2f7ab126 MO |
167 | --crate-name $(subst rusttest-,,$@) $< |
168 | ||
a66d733d MO |
169 | quiet_cmd_rustdoc_test_kernel = RUSTDOC TK $< |
170 | cmd_rustdoc_test_kernel = \ | |
171 | rm -rf $(objtree)/$(obj)/test/doctests/kernel; \ | |
172 | mkdir -p $(objtree)/$(obj)/test/doctests/kernel; \ | |
173 | OBJTREE=$(abspath $(objtree)) \ | |
174 | $(RUSTDOC) --test $(rust_flags) \ | |
d072acda | 175 | -L$(objtree)/$(obj) --extern ffi --extern kernel \ |
a66d733d MO |
176 | --extern build_error --extern macros \ |
177 | --extern bindings --extern uapi \ | |
178 | --no-run --crate-name kernel -Zunstable-options \ | |
71479eee | 179 | --sysroot=/dev/null \ |
a66d733d MO |
180 | --test-builder $(objtree)/scripts/rustdoc_test_builder \ |
181 | $< $(rustdoc_test_kernel_quiet); \ | |
182 | $(objtree)/scripts/rustdoc_test_gen | |
183 | ||
184 | %/doctests_kernel_generated.rs %/doctests_kernel_generated_kunit.c: \ | |
185 | $(src)/kernel/lib.rs $(obj)/kernel.o \ | |
186 | $(objtree)/scripts/rustdoc_test_builder \ | |
187 | $(objtree)/scripts/rustdoc_test_gen FORCE | |
ecab4115 | 188 | +$(call if_changed,rustdoc_test_kernel) |
a66d733d | 189 | |
2f7ab126 MO |
190 | # We cannot use `-Zpanic-abort-tests` because some tests are dynamic, |
191 | # so for the moment we skip `-Cpanic=abort`. | |
2a87f8b0 | 192 | quiet_cmd_rustc_test = $(RUSTC_OR_CLIPPY_QUIET) T $< |
2f7ab126 MO |
193 | cmd_rustc_test = \ |
194 | OBJTREE=$(abspath $(objtree)) \ | |
2a87f8b0 | 195 | $(RUSTC_OR_CLIPPY) --test $(rust_common_flags) \ |
2f7ab126 MO |
196 | @$(objtree)/include/generated/rustc_cfg \ |
197 | $(rustc_target_flags) --out-dir $(objtree)/$(obj)/test \ | |
2f7ab126 MO |
198 | -L$(objtree)/$(obj)/test \ |
199 | --crate-name $(subst rusttest-,,$@) $<; \ | |
200 | $(objtree)/$(obj)/test/$(subst rusttest-,,$@) $(rust_test_quiet) \ | |
201 | $(rustc_test_run_flags) | |
202 | ||
203 | rusttest: rusttest-macros rusttest-kernel | |
204 | ||
b2c261fa ET |
205 | rusttest-macros: private rustc_target_flags = --extern proc_macro \ |
206 | --extern macros --extern kernel | |
2f7ab126 | 207 | rusttest-macros: private rustdoc_test_target_flags = --crate-type proc-macro |
b2c261fa ET |
208 | rusttest-macros: $(src)/macros/lib.rs \ |
209 | rusttestlib-macros rusttestlib-kernel FORCE | |
ecab4115 MO |
210 | +$(call if_changed,rustc_test) |
211 | +$(call if_changed,rustdoc_test) | |
2f7ab126 | 212 | |
d072acda | 213 | rusttest-kernel: private rustc_target_flags = --extern ffi \ |
4e174665 | 214 | --extern build_error --extern macros --extern bindings --extern uapi |
d072acda | 215 | rusttest-kernel: $(src)/kernel/lib.rs rusttestlib-ffi rusttestlib-kernel \ |
4e174665 AL |
216 | rusttestlib-build_error rusttestlib-macros rusttestlib-bindings \ |
217 | rusttestlib-uapi FORCE | |
ecab4115 | 218 | +$(call if_changed,rustc_test) |
2f7ab126 | 219 | |
2f7ab126 MO |
220 | ifdef CONFIG_CC_IS_CLANG |
221 | bindgen_c_flags = $(c_flags) | |
222 | else | |
223 | # bindgen relies on libclang to parse C. Ideally, bindgen would support a GCC | |
224 | # plugin backend and/or the Clang driver would be perfectly compatible with GCC. | |
225 | # | |
226 | # For the moment, here we are tweaking the flags on the fly. This is a hack, | |
227 | # and some kernel configurations may not work (e.g. `GCC_PLUGIN_RANDSTRUCT` | |
228 | # if we end up using one of those structs). | |
229 | bindgen_skip_c_flags := -mno-fp-ret-in-387 -mpreferred-stack-boundary=% \ | |
230 | -mskip-rax-setup -mgeneral-regs-only -msign-return-address=% \ | |
231 | -mindirect-branch=thunk-extern -mindirect-branch-register \ | |
232 | -mfunction-return=thunk-extern -mrecord-mcount -mabi=lp64 \ | |
233 | -mindirect-branch-cs-prefix -mstack-protector-guard% -mtraceback=no \ | |
234 | -mno-pointers-to-nested-functions -mno-string \ | |
235 | -mno-strict-align -mstrict-align \ | |
236 | -fconserve-stack -falign-jumps=% -falign-loops=% \ | |
237 | -femit-struct-debug-baseonly -fno-ipa-cp-clone -fno-ipa-sra \ | |
238 | -fno-partial-inlining -fplugin-arg-arm_ssp_per_task_plugin-% \ | |
239 | -fno-reorder-blocks -fno-allow-store-data-races -fasan-shadow-offset=% \ | |
240 | -fzero-call-used-regs=% -fno-stack-clash-protection \ | |
b0554488 | 241 | -fno-inline-functions-called-once -fsanitize=bounds-strict \ |
869b5016 | 242 | -fstrict-flex-arrays=% -fmin-function-alignment=% \ |
a9c621a2 | 243 | -fzero-init-padding-bits=% \ |
2f7ab126 MO |
244 | --param=% --param asan-% |
245 | ||
246 | # Derived from `scripts/Makefile.clang`. | |
247 | BINDGEN_TARGET_x86 := x86_64-linux-gnu | |
724a75ac | 248 | BINDGEN_TARGET_arm64 := aarch64-linux-gnu |
2f7ab126 MO |
249 | BINDGEN_TARGET := $(BINDGEN_TARGET_$(SRCARCH)) |
250 | ||
251 | # All warnings are inhibited since GCC builds are very experimental, | |
252 | # many GCC warnings are not supported by Clang, they may only appear in | |
253 | # some configurations, with new GCC versions, etc. | |
254 | bindgen_extra_c_flags = -w --target=$(BINDGEN_TARGET) | |
255 | ||
d966c3ca AR |
256 | # Auto variable zero-initialization requires an additional special option with |
257 | # clang that is going to be removed sometime in the future (likely in | |
258 | # clang-18), so make sure to pass this option only if clang supports it | |
259 | # (libclang major version < 16). | |
260 | # | |
261 | # https://github.com/llvm/llvm-project/issues/44842 | |
262 | # https://github.com/llvm/llvm-project/blob/llvmorg-16.0.0-rc2/clang/docs/ReleaseNotes.rst#deprecated-compiler-flags | |
263 | ifdef CONFIG_INIT_STACK_ALL_ZERO | |
264 | libclang_maj_ver=$(shell $(BINDGEN) $(srctree)/scripts/rust_is_available_bindgen_libclang.h 2>&1 | sed -ne 's/.*clang version \([0-9]*\).*/\1/p') | |
265 | ifeq ($(shell expr $(libclang_maj_ver) \< 16), 1) | |
266 | bindgen_extra_c_flags += -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang | |
267 | endif | |
268 | endif | |
269 | ||
2f7ab126 MO |
270 | bindgen_c_flags = $(filter-out $(bindgen_skip_c_flags), $(c_flags)) \ |
271 | $(bindgen_extra_c_flags) | |
272 | endif | |
273 | ||
274 | ifdef CONFIG_LTO | |
275 | bindgen_c_flags_lto = $(filter-out $(CC_FLAGS_LTO), $(bindgen_c_flags)) | |
276 | else | |
277 | bindgen_c_flags_lto = $(bindgen_c_flags) | |
278 | endif | |
279 | ||
75c1fd41 GG |
280 | # `-fno-builtin` is passed to avoid `bindgen` from using `clang` builtin |
281 | # prototypes for functions like `memcpy` -- if this flag is not passed, | |
282 | # `bindgen`-generated prototypes use `c_ulong` or `c_uint` depending on | |
283 | # architecture instead of generating `usize`. | |
284 | bindgen_c_flags_final = $(bindgen_c_flags_lto) -fno-builtin -D__BINDGEN__ | |
2f7ab126 | 285 | |
7a5f93ea MO |
286 | # Each `bindgen` release may upgrade the list of Rust target versions. By |
287 | # default, the highest stable release in their list is used. Thus we need to set | |
288 | # a `--rust-target` to avoid future `bindgen` releases emitting code that | |
289 | # `rustc` may not understand. On top of that, `bindgen` does not support passing | |
290 | # an unknown Rust target version. | |
291 | # | |
292 | # Therefore, the Rust target for `bindgen` can be only as high as the minimum | |
293 | # Rust version the kernel supports and only as high as the greatest stable Rust | |
294 | # target supported by the minimum `bindgen` version the kernel supports (that | |
295 | # is, if we do not test the actual `rustc`/`bindgen` versions running). | |
296 | # | |
297 | # Starting with `bindgen` 0.71.0, we will be able to set any future Rust version | |
298 | # instead, i.e. we will be able to set here our minimum supported Rust version. | |
2f7ab126 MO |
299 | quiet_cmd_bindgen = BINDGEN $@ |
300 | cmd_bindgen = \ | |
7a5f93ea | 301 | $(BINDGEN) $< $(bindgen_target_flags) --rust-target 1.68 \ |
d072acda | 302 | --use-core --with-derive-default --ctypes-prefix ffi --no-layout-tests \ |
76501d19 | 303 | --no-debug '.*' --enable-function-attribute-detection \ |
08ab7865 | 304 | -o $@ -- $(bindgen_c_flags_final) -DMODULE \ |
2f7ab126 MO |
305 | $(bindgen_target_cflags) $(bindgen_target_extra) |
306 | ||
307 | $(obj)/bindings/bindings_generated.rs: private bindgen_target_flags = \ | |
b1992c37 | 308 | $(shell grep -Ev '^#|^$$' $(src)/bindgen_parameters) |
74376656 GG |
309 | $(obj)/bindings/bindings_generated.rs: private bindgen_target_extra = ; \ |
310 | sed -Ei 's/pub const RUST_CONST_HELPER_([a-zA-Z0-9_]*)/pub const \1/g' $@ | |
2f7ab126 MO |
311 | $(obj)/bindings/bindings_generated.rs: $(src)/bindings/bindings_helper.h \ |
312 | $(src)/bindgen_parameters FORCE | |
313 | $(call if_changed_dep,bindgen) | |
314 | ||
4e174665 | 315 | $(obj)/uapi/uapi_generated.rs: private bindgen_target_flags = \ |
b1992c37 | 316 | $(shell grep -Ev '^#|^$$' $(src)/bindgen_parameters) |
4e174665 AL |
317 | $(obj)/uapi/uapi_generated.rs: $(src)/uapi/uapi_helper.h \ |
318 | $(src)/bindgen_parameters FORCE | |
319 | $(call if_changed_dep,bindgen) | |
320 | ||
2f7ab126 MO |
321 | # See `CFLAGS_REMOVE_helpers.o` above. In addition, Clang on C does not warn |
322 | # with `-Wmissing-declarations` (unlike GCC), so it is not strictly needed here | |
323 | # given it is `libclang`; but for consistency, future Clang changes and/or | |
324 | # a potential future GCC backend for `bindgen`, we disable it too. | |
325 | $(obj)/bindings/bindings_helpers_generated.rs: private bindgen_target_flags = \ | |
08ab7865 ASS |
326 | --blocklist-type '.*' --allowlist-var '' \ |
327 | --allowlist-function 'rust_helper_.*' | |
2f7ab126 MO |
328 | $(obj)/bindings/bindings_helpers_generated.rs: private bindgen_target_cflags = \ |
329 | -I$(objtree)/$(obj) -Wno-missing-prototypes -Wno-missing-declarations | |
330 | $(obj)/bindings/bindings_helpers_generated.rs: private bindgen_target_extra = ; \ | |
331 | sed -Ei 's/pub fn rust_helper_([a-zA-Z0-9_]*)/#[link_name="rust_helper_\1"]\n pub fn \1/g' $@ | |
87634653 | 332 | $(obj)/bindings/bindings_helpers_generated.rs: $(src)/helpers/helpers.c FORCE |
2f7ab126 MO |
333 | $(call if_changed_dep,bindgen) |
334 | ||
0e446e31 | 335 | rust_exports = $(NM) -p --defined-only $(1) | awk '$$2~/(T|R|D|B)/ && $$3!~/__cfi/ && $$3!~/__odr_asan/ { printf $(2),$$3 }' |
ac61506b | 336 | |
2f7ab126 MO |
337 | quiet_cmd_exports = EXPORTS $@ |
338 | cmd_exports = \ | |
ac61506b | 339 | $(call rust_exports,$<,"EXPORT_SYMBOL_RUST_GPL(%s);\n") > $@ |
2f7ab126 MO |
340 | |
341 | $(obj)/exports_core_generated.h: $(obj)/core.o FORCE | |
342 | $(call if_changed,exports) | |
343 | ||
e26fa546 GG |
344 | # Even though Rust kernel modules should never use the bindings directly, |
345 | # symbols from the `bindings` crate and the C helpers need to be exported | |
346 | # because Rust generics and inlined functions may not get their code generated | |
347 | # in the crate where they are defined. Other helpers, called from non-inline | |
348 | # functions, may not be exported, in principle. However, in general, the Rust | |
349 | # compiler does not guarantee codegen will be performed for a non-inline | |
350 | # function either. Therefore, we export all symbols from helpers and bindings. | |
351 | # In the future, this may be revisited to reduce the number of exports after | |
352 | # the compiler is informed about the places codegen is required. | |
353 | $(obj)/exports_helpers_generated.h: $(obj)/helpers/helpers.o FORCE | |
354 | $(call if_changed,exports) | |
355 | ||
2f7ab126 MO |
356 | $(obj)/exports_bindings_generated.h: $(obj)/bindings.o FORCE |
357 | $(call if_changed,exports) | |
358 | ||
359 | $(obj)/exports_kernel_generated.h: $(obj)/kernel.o FORCE | |
360 | $(call if_changed,exports) | |
361 | ||
362 | quiet_cmd_rustc_procmacro = $(RUSTC_OR_CLIPPY_QUIET) P $@ | |
363 | cmd_rustc_procmacro = \ | |
364 | $(RUSTC_OR_CLIPPY) $(rust_common_flags) \ | |
80bac83a | 365 | -Clinker-flavor=gcc -Clinker=$(HOSTCC) \ |
ceff0757 | 366 | -Clink-args='$(call escsq,$(KBUILD_PROCMACROLDFLAGS))' \ |
295d8398 MY |
367 | --emit=dep-info=$(depfile) --emit=link=$@ --extern proc_macro \ |
368 | --crate-type proc-macro \ | |
0730422b | 369 | --crate-name $(patsubst lib%.$(libmacros_extension),%,$(notdir $@)) $< |
2f7ab126 MO |
370 | |
371 | # Procedural macros can only be used with the `rustc` that compiled it. | |
0730422b | 372 | $(obj)/$(libmacros_name): $(src)/macros/lib.rs FORCE |
ecab4115 | 373 | +$(call if_changed_dep,rustc_procmacro) |
2f7ab126 MO |
374 | |
375 | quiet_cmd_rustc_library = $(if $(skip_clippy),RUSTC,$(RUSTC_OR_CLIPPY_QUIET)) L $@ | |
376 | cmd_rustc_library = \ | |
377 | OBJTREE=$(abspath $(objtree)) \ | |
378 | $(if $(skip_clippy),$(RUSTC),$(RUSTC_OR_CLIPPY)) \ | |
379 | $(filter-out $(skip_flags),$(rust_flags) $(rustc_target_flags)) \ | |
295d8398 MY |
380 | --emit=dep-info=$(depfile) --emit=obj=$@ \ |
381 | --emit=metadata=$(dir $@)$(patsubst %.o,lib%.rmeta,$(notdir $@)) \ | |
382 | --crate-type rlib -L$(objtree)/$(obj) \ | |
2185242f | 383 | --crate-name $(patsubst %.o,%,$(notdir $@)) $< \ |
71479eee | 384 | --sysroot=/dev/null \ |
c4d7f546 MO |
385 | $(if $(rustc_objcopy),;$(OBJCOPY) $(rustc_objcopy) $@) \ |
386 | $(cmd_objtool) | |
2f7ab126 MO |
387 | |
388 | rust-analyzer: | |
0730422b | 389 | $(Q)MAKEFLAGS= $(srctree)/scripts/generate_rust_analyzer.py \ |
392e34b6 | 390 | --cfgs='core=$(core-cfgs)' \ |
e2bad142 | 391 | $(realpath $(srctree)) $(realpath $(objtree)) \ |
13b25489 MY |
392 | $(rustc_sysroot) $(RUST_LIB_SRC) $(if $(KBUILD_EXTMOD),$(srcroot)) \ |
393 | > rust-project.json | |
2f7ab126 | 394 | |
cb7d9def | 395 | redirect-intrinsics = \ |
02dfd63a MO |
396 | __addsf3 __eqsf2 __extendsfdf2 __gesf2 __lesf2 __ltsf2 __mulsf3 __nesf2 __truncdfsf2 __unordsf2 \ |
397 | __adddf3 __eqdf2 __ledf2 __ltdf2 __muldf3 __unorddf2 \ | |
cb7d9def GG |
398 | __muloti4 __multi3 \ |
399 | __udivmodti4 __udivti3 __umodti3 | |
400 | ||
401 | ifneq ($(or $(CONFIG_ARM64),$(and $(CONFIG_RISCV),$(CONFIG_64BIT))),) | |
402 | # These intrinsics are defined for ARM64 and RISCV64 | |
403 | redirect-intrinsics += \ | |
404 | __ashrti3 \ | |
405 | __ashlti3 __lshrti3 | |
406 | endif | |
407 | ||
ac61506b ST |
408 | ifdef CONFIG_MODVERSIONS |
409 | cmd_gendwarfksyms = $(if $(skip_gendwarfksyms),, \ | |
410 | $(call rust_exports,$@,"%s\n") | \ | |
411 | scripts/gendwarfksyms/gendwarfksyms \ | |
412 | $(if $(KBUILD_GENDWARFKSYMS_STABLE), --stable) \ | |
413 | $(if $(KBUILD_SYMTYPES), --symtypes $(@:.o=.symtypes),) \ | |
414 | $@ >> $(dot-target).cmd) | |
415 | endif | |
416 | ||
c4d7f546 MO |
417 | define rule_rustc_library |
418 | $(call cmd_and_fixdep,rustc_library) | |
419 | $(call cmd,gen_objtooldep) | |
ac61506b | 420 | $(call cmd,gendwarfksyms) |
c4d7f546 MO |
421 | endef |
422 | ||
ac61506b ST |
423 | define rule_rust_cc_library |
424 | $(call if_changed_rule,cc_o_c) | |
425 | $(call cmd,force_checksrc) | |
426 | $(call cmd,gendwarfksyms) | |
427 | endef | |
428 | ||
429 | # helpers.o uses the same export mechanism as Rust libraries, so ensure symbol | |
430 | # versions are calculated for the helpers too. | |
431 | $(obj)/helpers/helpers.o: $(src)/helpers/helpers.c $(recordmcount_source) FORCE | |
432 | +$(call if_changed_rule,rust_cc_library) | |
433 | ||
434 | # Disable symbol versioning for exports.o to avoid conflicts with the actual | |
435 | # symbol versions generated from Rust objects. | |
436 | $(obj)/exports.o: private skip_gendwarfksyms = 1 | |
437 | ||
2f7ab126 | 438 | $(obj)/core.o: private skip_clippy = 1 |
f8f88aa2 | 439 | $(obj)/core.o: private skip_flags = -Wunreachable_pub |
cb7d9def | 440 | $(obj)/core.o: private rustc_objcopy = $(foreach sym,$(redirect-intrinsics),--redefine-sym $(sym)=__rust$(sym)) |
2f7ab126 | 441 | $(obj)/core.o: private rustc_target_flags = $(core-cfgs) |
ac3e9726 MO |
442 | $(obj)/core.o: $(RUST_LIB_SRC)/core/src/lib.rs \ |
443 | $(wildcard $(objtree)/include/config/RUSTC_VERSION_TEXT) FORCE | |
c4d7f546 | 444 | +$(call if_changed_rule,rustc_library) |
ab0f4ced | 445 | ifneq ($(or $(CONFIG_X86_64),$(CONFIG_X86_32)),) |
f82811e2 JC |
446 | $(obj)/core.o: scripts/target.json |
447 | endif | |
2f7ab126 | 448 | |
ac61506b | 449 | $(obj)/compiler_builtins.o: private skip_gendwarfksyms = 1 |
2f7ab126 MO |
450 | $(obj)/compiler_builtins.o: private rustc_objcopy = -w -W '__*' |
451 | $(obj)/compiler_builtins.o: $(src)/compiler_builtins.rs $(obj)/core.o FORCE | |
c4d7f546 | 452 | +$(call if_changed_rule,rustc_library) |
2f7ab126 | 453 | |
ac61506b | 454 | $(obj)/build_error.o: private skip_gendwarfksyms = 1 |
ecaa6ddf | 455 | $(obj)/build_error.o: $(src)/build_error.rs $(obj)/compiler_builtins.o FORCE |
c4d7f546 | 456 | +$(call if_changed_rule,rustc_library) |
2f7ab126 | 457 | |
ac61506b | 458 | $(obj)/ffi.o: private skip_gendwarfksyms = 1 |
d072acda | 459 | $(obj)/ffi.o: $(src)/ffi.rs $(obj)/compiler_builtins.o FORCE |
c4d7f546 | 460 | +$(call if_changed_rule,rustc_library) |
ecaa6ddf | 461 | |
d072acda | 462 | $(obj)/bindings.o: private rustc_target_flags = --extern ffi |
2f7ab126 | 463 | $(obj)/bindings.o: $(src)/bindings/lib.rs \ |
d072acda | 464 | $(obj)/ffi.o \ |
2f7ab126 MO |
465 | $(obj)/bindings/bindings_generated.rs \ |
466 | $(obj)/bindings/bindings_helpers_generated.rs FORCE | |
c4d7f546 | 467 | +$(call if_changed_rule,rustc_library) |
2f7ab126 | 468 | |
d072acda | 469 | $(obj)/uapi.o: private rustc_target_flags = --extern ffi |
ac61506b | 470 | $(obj)/uapi.o: private skip_gendwarfksyms = 1 |
4e174665 | 471 | $(obj)/uapi.o: $(src)/uapi/lib.rs \ |
d072acda | 472 | $(obj)/ffi.o \ |
4e174665 | 473 | $(obj)/uapi/uapi_generated.rs FORCE |
c4d7f546 | 474 | +$(call if_changed_rule,rustc_library) |
4e174665 | 475 | |
d072acda | 476 | $(obj)/kernel.o: private rustc_target_flags = --extern ffi \ |
4e174665 | 477 | --extern build_error --extern macros --extern bindings --extern uapi |
392e34b6 | 478 | $(obj)/kernel.o: $(src)/kernel/lib.rs $(obj)/build_error.o \ |
0730422b | 479 | $(obj)/$(libmacros_name) $(obj)/bindings.o $(obj)/uapi.o FORCE |
c4d7f546 | 480 | +$(call if_changed_rule,rustc_library) |
2f7ab126 | 481 | |
169484ab | 482 | ifdef CONFIG_JUMP_LABEL |
8af7a501 | 483 | $(obj)/kernel.o: $(obj)/kernel/generated_arch_static_branch_asm.rs |
169484ab AR |
484 | endif |
485 | ||
2f7ab126 | 486 | endif # CONFIG_RUST |