Skip to content

Commit afba78e

Browse files
committed
rust: generate target specification files on the fly
Now that we have host programs support, add a "Rust script" to generate the `rustc` target spec file. The script has been written so that its output matches exactly the current `arch/*/rust/*.json` static target files we have at the moment, to have a baseline and reduce the changes done by this commit. Thus the static files are now gone. The build system is set up in a way that we do not need to rebuild any Rust code as long as the `target.json` contents do not change, even if the kernel configuration changes for something else. Furthermore, the script does not need to be rebuilt even if the kernel configuration changes. With this, `KBUILD_RUST_TARGET` is also gone -- one should modify the script instead of trying to override the target file. After this, the script should be cleaned (e.g. remove unneeded keys) and fixed to configure the architectures properly (e.g. enable CPU features as needed, etc.). There were several design choices: - The language: this could have been done in a shell script, C or Perl. But as soon as Rust is an option, it is more convenient than any of those. And it is an ideal showcase for the Rust host programs support. Python could have also been a natural option for the script, though it cannot be used as part as the kernel compilation because it is not required (as far as I can see in the docs). Even if it were, Rust offers some advantages anyway (though the `json` module would have been fairly useful here). Compiling the Rust host program takes a lot of time compared to other languages, at least currently (e.g. 300ms), but there is no need to recompile it on config changes, so it is fine. And, of course, running it is very fast. - Whether or not to use conditional compilation. Initially I took advantage of the `rustc_cfg` flags, to make the script look closer to the actual Rust kernel code. However, that means the script depends on the config, which means it is not an independent tool anymore (though there is at least one other host program that gets passed the flags, but it is not common), plus requires recompiling it every time the configuration changes just to generate the actual file. It also made things more tricky on the build system. - Splitting the logic into `arch/*` or not. In order to have arch maintainers work independently, we could move part of the logic into their trees. However, given how small the script is and that some logic is shared anyway, it looks a little bit odd. So I decided to avoid it. We can revisit this if needed. - Whether to use a proper JSON generator or not, whether to use a `HashMap`, whether to set up a type that knows about all the keys that can be generated (or maybe even import part of the `rustc` code to be in sync), etc. The script has been written to be as simple as possible while making it easy to change the actual business logic. We should reevaluate as it gets developed. Signed-off-by: Miguel Ojeda <[email protected]>
1 parent 046d82f commit afba78e

File tree

17 files changed

+338
-276
lines changed

17 files changed

+338
-276
lines changed

Documentation/kbuild/makefiles.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1205,6 +1205,9 @@ When kbuild executes, the following steps are followed (roughly):
12051205

12061206
Often, the KBUILD_RUSTFLAGS variable depends on the configuration.
12071207

1208+
Note that target specification file generation (for ``--target``)
1209+
is handled in ``scripts/generate_rust_target.rs``.
1210+
12081211
KBUILD_AFLAGS_KERNEL
12091212
Assembler options specific for built-in
12101213

Makefile

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,6 @@ KBUILD_CFLAGS := -Wall -Wundef -Werror=strict-prototypes -Wno-trigraphs \
551551
-Werror=return-type -Wno-format-security \
552552
-std=gnu89
553553
KBUILD_CPPFLAGS := -D__KERNEL__
554-
KBUILD_RUST_TARGET := $(srctree)/arch/$(SRCARCH)/rust/target.json
555554
KBUILD_RUSTFLAGS := $(rust_common_flags) \
556555
-Cpanic=abort -Cembed-bitcode=n -Clto=n -Crpath=n \
557556
-Cforce-unwind-tables=n -Ccodegen-units=1 \
@@ -592,7 +591,7 @@ export KBUILD_HOSTCXXFLAGS KBUILD_HOSTLDFLAGS KBUILD_HOSTLDLIBS LDFLAGS_MODULE
592591

593592
export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS KBUILD_LDFLAGS
594593
export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE
595-
export KBUILD_RUST_TARGET KBUILD_RUSTFLAGS RUSTFLAGS_KERNEL RUSTFLAGS_MODULE
594+
export KBUILD_RUSTFLAGS RUSTFLAGS_KERNEL RUSTFLAGS_MODULE
596595
export KBUILD_AFLAGS AFLAGS_KERNEL AFLAGS_MODULE
597596
export KBUILD_AFLAGS_MODULE KBUILD_CFLAGS_MODULE KBUILD_RUSTFLAGS_MODULE KBUILD_LDFLAGS_MODULE
598597
export KBUILD_AFLAGS_KERNEL KBUILD_CFLAGS_KERNEL KBUILD_RUSTFLAGS_KERNEL
@@ -1578,7 +1577,7 @@ MRPROPER_FILES += include/config include/generated \
15781577
certs/x509.genkey \
15791578
vmlinux-gdb.py \
15801579
*.spec \
1581-
rust/libmacros.so
1580+
rust/target.json rust/libmacros.so
15821581

15831582
# clean - Delete most, but leave enough to build external modules
15841583
#

arch/arm/rust/target.json

Lines changed: 0 additions & 27 deletions
This file was deleted.

arch/arm64/rust/target.json

Lines changed: 0 additions & 34 deletions
This file was deleted.

arch/powerpc/rust/target.json

Lines changed: 0 additions & 29 deletions
This file was deleted.

arch/riscv/Makefile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ riscv-march-$(toolchain-need-zicsr-zifencei) := $(riscv-march-y)_zicsr_zifencei
5858

5959
KBUILD_CFLAGS += -march=$(subst fd,,$(riscv-march-y))
6060
KBUILD_AFLAGS += -march=$(riscv-march-y)
61-
KBUILD_RUST_TARGET := $(srctree)/arch/riscv/rust/$(subst fd,,$(riscv-march-y)).json
6261

6362
KBUILD_CFLAGS += -mno-save-restore
6463
KBUILD_CFLAGS += -DCONFIG_PAGE_OFFSET=$(CONFIG_PAGE_OFFSET)

arch/riscv/rust/rv32ima.json

Lines changed: 0 additions & 36 deletions
This file was deleted.

arch/riscv/rust/rv32imac.json

Lines changed: 0 additions & 36 deletions
This file was deleted.

arch/riscv/rust/rv64ima.json

Lines changed: 0 additions & 36 deletions
This file was deleted.

arch/riscv/rust/rv64imac.json

Lines changed: 0 additions & 36 deletions
This file was deleted.

arch/x86/rust/target.json

Lines changed: 0 additions & 36 deletions
This file was deleted.

rust/.gitignore

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

3+
target.json
34
bindings_generated.rs
45
bindings_helpers_generated.rs
56
exports_*_generated.h

rust/Makefile

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# SPDX-License-Identifier: GPL-2.0
22

3+
always-$(CONFIG_RUST) += target.json
4+
no-clean-files += target.json
5+
36
obj-$(CONFIG_RUST) += core.o compiler_builtins.o
47
always-$(CONFIG_RUST) += exports_core_generated.h
58

@@ -206,6 +209,11 @@ rusttest-kernel: $(srctree)/rust/kernel/lib.rs rusttest-prepare \
206209
$(call if_changed,rustc_test_library)
207210
$(call if_changed,rustdoc_test)
208211

212+
filechk_rust_target = $(objtree)/scripts/generate_rust_target < $<
213+
214+
$(objtree)/rust/target.json: $(objtree)/include/config/auto.conf FORCE
215+
$(call filechk,rust_target)
216+
209217
ifdef CONFIG_CC_IS_CLANG
210218
bindgen_c_flags = $(c_flags)
211219
else
@@ -364,7 +372,8 @@ $(objtree)/rust/kernel.o: $(srctree)/rust/kernel/lib.rs $(objtree)/rust/alloc.o
364372
$(objtree)/rust/core.o: private skip_clippy = 1
365373
$(objtree)/rust/core.o: private skip_flags = -Dunreachable_pub --edition=2021
366374
$(objtree)/rust/core.o: private rustc_target_flags = $(core-cfgs) --edition=2018
367-
$(objtree)/rust/core.o: $(RUST_LIB_SRC)/core/src/lib.rs FORCE
375+
$(objtree)/rust/core.o: $(RUST_LIB_SRC)/core/src/lib.rs \
376+
$(objtree)/rust/target.json FORCE
368377
$(call if_changed_dep,rustc_library)
369378

370379
rustdoc-core: private rustc_target_flags = $(core-cfgs)

scripts/.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-only
22
/asn1_compiler
33
/bin2c
4+
/generate_rust_target
45
/insert-sys-cert
56
/kallsyms
67
/module.lds

scripts/Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ hostprogs-always-$(CONFIG_BUILDTIME_TABLE_SORT) += sorttable
1010
hostprogs-always-$(CONFIG_ASN1) += asn1_compiler
1111
hostprogs-always-$(CONFIG_MODULE_SIG_FORMAT) += sign-file
1212
hostprogs-always-$(CONFIG_SYSTEM_EXTRA_CERTIFICATE) += insert-sys-cert
13+
hostprogs-always-$(CONFIG_RUST) += generate_rust_target
14+
15+
generate_rust_target-rust := y
1316

1417
HOSTCFLAGS_sorttable.o = -I$(srctree)/tools/include
1518
HOSTLDLIBS_sorttable = -lpthread

scripts/Makefile.build

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ $(obj)/%.lst: $(src)/%.c FORCE
328328
# Compile Rust sources (.rs)
329329
# ---------------------------------------------------------------------------
330330

331-
rust_cross_flags := --target=$(KBUILD_RUST_TARGET)
331+
rust_cross_flags := --target=$(objtree)/rust/target.json
332332
rust_allowed_features := allocator_api,bench_black_box,concat_idents,generic_associated_types
333333

334334
rust_common_cmd = \

0 commit comments

Comments
 (0)