From 295d8398c67e314d99bb070f38883f83fe94a97a Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 7 Jan 2023 18:18:15 +0900 Subject: kbuild: specify output names separately for each emission type from rustc In Kbuild, two different rules must not write to the same file, but it happens when compiling rust source files. For example, set CONFIG_SAMPLE_RUST_MINIMAL=m and run the following: $ make -j$(nproc) samples/rust/rust_minimal.o samples/rust/rust_minimal.rsi \ samples/rust/rust_minimal.s samples/rust/rust_minimal.ll [snip] RUSTC [M] samples/rust/rust_minimal.o RUSTC [M] samples/rust/rust_minimal.rsi RUSTC [M] samples/rust/rust_minimal.s RUSTC [M] samples/rust/rust_minimal.ll mv: cannot stat 'samples/rust/rust_minimal.d': No such file or directory make[3]: *** [scripts/Makefile.build:334: samples/rust/rust_minimal.ll] Error 1 make[3]: *** Waiting for unfinished jobs.... mv: cannot stat 'samples/rust/rust_minimal.d': No such file or directory make[3]: *** [scripts/Makefile.build:309: samples/rust/rust_minimal.o] Error 1 mv: cannot stat 'samples/rust/rust_minimal.d': No such file or directory make[3]: *** [scripts/Makefile.build:326: samples/rust/rust_minimal.s] Error 1 make[2]: *** [scripts/Makefile.build:504: samples/rust] Error 2 make[1]: *** [scripts/Makefile.build:504: samples] Error 2 make: *** [Makefile:2008: .] Error 2 The reason for the error is that 4 threads running in parallel renames the same file, samples/rust/rust_minimal.d. This does not happen when compiling C or assembly files because -Wp,-MMD,$(depfile) explicitly specifies the dependency filepath. $(depfile) is a unique path for each target. Currently, rustc is only given --out-dir and --emit= So, all the rust build rules output the dep-info into the default .d, which causes the path conflict. Fortunately, the --emit option is able to specify the output path individually, with the form --emit==. Add --emit=dep-info=$(depfile) to the common part. Also, remove the redundant --out-dir because the output path is specified for each type. The code gets much cleaner because we do not need to rename *.d files. Signed-off-by: Masahiro Yamada Reviewed-by: Miguel Ojeda Tested-by: Miguel Ojeda Reviewed-by: Vincenzo Palazzo --- rust/Makefile | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'rust') diff --git a/rust/Makefile b/rust/Makefile index ff70c4c916f8..865afb87bc9b 100644 --- a/rust/Makefile +++ b/rust/Makefile @@ -331,10 +331,9 @@ $(obj)/exports_kernel_generated.h: $(obj)/kernel.o FORCE quiet_cmd_rustc_procmacro = $(RUSTC_OR_CLIPPY_QUIET) P $@ cmd_rustc_procmacro = \ $(RUSTC_OR_CLIPPY) $(rust_common_flags) \ - --emit=dep-info,link --extern proc_macro \ - --crate-type proc-macro --out-dir $(objtree)/$(obj) \ + --emit=dep-info=$(depfile) --emit=link=$@ --extern proc_macro \ + --crate-type proc-macro \ --crate-name $(patsubst lib%.so,%,$(notdir $@)) $<; \ - mv $(objtree)/$(obj)/$(patsubst lib%.so,%,$(notdir $@)).d $(depfile); \ sed -i '/^\#/d' $(depfile) # Procedural macros can only be used with the `rustc` that compiled it. @@ -348,10 +347,10 @@ quiet_cmd_rustc_library = $(if $(skip_clippy),RUSTC,$(RUSTC_OR_CLIPPY_QUIET)) L OBJTREE=$(abspath $(objtree)) \ $(if $(skip_clippy),$(RUSTC),$(RUSTC_OR_CLIPPY)) \ $(filter-out $(skip_flags),$(rust_flags) $(rustc_target_flags)) \ - --emit=dep-info,obj,metadata --crate-type rlib \ - --out-dir $(objtree)/$(obj) -L$(objtree)/$(obj) \ + --emit=dep-info=$(depfile) --emit=obj=$@ \ + --emit=metadata=$(dir $@)$(patsubst %.o,lib%.rmeta,$(notdir $@)) \ + --crate-type rlib -L$(objtree)/$(obj) \ --crate-name $(patsubst %.o,%,$(notdir $@)) $<; \ - mv $(objtree)/$(obj)/$(patsubst %.o,%,$(notdir $@)).d $(depfile); \ sed -i '/^\#/d' $(depfile) \ $(if $(rustc_objcopy),;$(OBJCOPY) $(rustc_objcopy) $@) -- cgit v1.2.3-59-g8ed1b From 2185242faddd12a1ba1060be5caf584fe5aba93a Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 7 Jan 2023 18:18:17 +0900 Subject: kbuild: remove sed commands after rustc rules rustc may put comments in dep-info, so sed is used to drop them before passing it to fixdep. Now that fixdep can remove comments, Makefiles do not need to run sed. Signed-off-by: Masahiro Yamada Reviewed-by: Miguel Ojeda Tested-by: Miguel Ojeda Reviewed-by: Vincenzo Palazzo --- rust/Makefile | 6 ++---- scripts/Makefile.build | 18 ++++-------------- scripts/Makefile.host | 3 +-- 3 files changed, 7 insertions(+), 20 deletions(-) (limited to 'rust') diff --git a/rust/Makefile b/rust/Makefile index 865afb87bc9b..f403b79cae5a 100644 --- a/rust/Makefile +++ b/rust/Makefile @@ -333,8 +333,7 @@ quiet_cmd_rustc_procmacro = $(RUSTC_OR_CLIPPY_QUIET) P $@ $(RUSTC_OR_CLIPPY) $(rust_common_flags) \ --emit=dep-info=$(depfile) --emit=link=$@ --extern proc_macro \ --crate-type proc-macro \ - --crate-name $(patsubst lib%.so,%,$(notdir $@)) $<; \ - sed -i '/^\#/d' $(depfile) + --crate-name $(patsubst lib%.so,%,$(notdir $@)) $< # Procedural macros can only be used with the `rustc` that compiled it. # Therefore, to get `libmacros.so` automatically recompiled when the compiler @@ -350,8 +349,7 @@ quiet_cmd_rustc_library = $(if $(skip_clippy),RUSTC,$(RUSTC_OR_CLIPPY_QUIET)) L --emit=dep-info=$(depfile) --emit=obj=$@ \ --emit=metadata=$(dir $@)$(patsubst %.o,lib%.rmeta,$(notdir $@)) \ --crate-type rlib -L$(objtree)/$(obj) \ - --crate-name $(patsubst %.o,%,$(notdir $@)) $<; \ - sed -i '/^\#/d' $(depfile) \ + --crate-name $(patsubst %.o,%,$(notdir $@)) $< \ $(if $(rustc_objcopy),;$(OBJCOPY) $(rustc_objcopy) $@) rust-analyzer: diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 40de20246e50..76323201232a 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -289,9 +289,6 @@ rust_common_cmd = \ --crate-name $(basename $(notdir $@)) \ --emit=dep-info=$(depfile) -rust_handle_depfile = \ - sed -i '/^\#/d' $(depfile) - # `--emit=obj`, `--emit=asm` and `--emit=llvm-ir` imply a single codegen unit # will be used. We explicitly request `-Ccodegen-units=1` in any case, and # the compiler shows a warning if it is not 1. However, if we ever stop @@ -301,9 +298,7 @@ rust_handle_depfile = \ # would not match each other. quiet_cmd_rustc_o_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@ - cmd_rustc_o_rs = \ - $(rust_common_cmd) --emit=obj=$@ $<; \ - $(rust_handle_depfile) + cmd_rustc_o_rs = $(rust_common_cmd) --emit=obj=$@ $< $(obj)/%.o: $(src)/%.rs FORCE $(call if_changed_dep,rustc_o_rs) @@ -311,24 +306,19 @@ $(obj)/%.o: $(src)/%.rs FORCE quiet_cmd_rustc_rsi_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@ cmd_rustc_rsi_rs = \ $(rust_common_cmd) -Zunpretty=expanded $< >$@; \ - command -v $(RUSTFMT) >/dev/null && $(RUSTFMT) $@; \ - $(rust_handle_depfile) + command -v $(RUSTFMT) >/dev/null && $(RUSTFMT) $@ $(obj)/%.rsi: $(src)/%.rs FORCE $(call if_changed_dep,rustc_rsi_rs) quiet_cmd_rustc_s_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@ - cmd_rustc_s_rs = \ - $(rust_common_cmd) --emit=asm=$@ $<; \ - $(rust_handle_depfile) + cmd_rustc_s_rs = $(rust_common_cmd) --emit=asm=$@ $< $(obj)/%.s: $(src)/%.rs FORCE $(call if_changed_dep,rustc_s_rs) quiet_cmd_rustc_ll_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@ - cmd_rustc_ll_rs = \ - $(rust_common_cmd) --emit=llvm-ir=$@ $<; \ - $(rust_handle_depfile) + cmd_rustc_ll_rs = $(rust_common_cmd) --emit=llvm-ir=$@ $< $(obj)/%.ll: $(src)/%.rs FORCE $(call if_changed_dep,rustc_ll_rs) diff --git a/scripts/Makefile.host b/scripts/Makefile.host index d812241144d4..7aea9005e497 100644 --- a/scripts/Makefile.host +++ b/scripts/Makefile.host @@ -148,8 +148,7 @@ $(host-cxxobjs): $(obj)/%.o: $(src)/%.cc FORCE # host-rust -> Executable quiet_cmd_host-rust = HOSTRUSTC $@ cmd_host-rust = \ - $(HOSTRUSTC) $(hostrust_flags) --emit=link=$@ $<; \ - sed -i '/^\#/d' $(depfile) + $(HOSTRUSTC) $(hostrust_flags) --emit=link=$@ $< $(host-rust): $(obj)/%: $(src)/%.rs FORCE $(call if_changed_dep,host-rust) -- cgit v1.2.3-59-g8ed1b From c83b16cefd78f55071840e1159ead9fe62747769 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 7 Jan 2023 18:45:45 +0900 Subject: kbuild: rust: move rust/target.json to scripts/ scripts/ is a better place to generate files used treewide. With target.json moved to scripts/, you do not need to add target.json to no-clean-files or MRPROPER_FILES. 'make clean' does not visit scripts/, but 'make mrproper' does. Signed-off-by: Masahiro Yamada Reviewed-by: Miguel Ojeda Tested-by: Miguel Ojeda --- Makefile | 4 ++-- rust/.gitignore | 1 - rust/Makefile | 10 +--------- scripts/.gitignore | 1 + scripts/Makefile | 8 +++++++- scripts/remove-stale-files | 2 ++ 6 files changed, 13 insertions(+), 13 deletions(-) (limited to 'rust') diff --git a/Makefile b/Makefile index b9d1411ef25b..ef6d593634cf 100644 --- a/Makefile +++ b/Makefile @@ -569,7 +569,7 @@ KBUILD_CFLAGS := -Wall -Wundef -Werror=strict-prototypes -Wno-trigraphs \ -std=gnu11 KBUILD_CPPFLAGS := -D__KERNEL__ KBUILD_RUSTFLAGS := $(rust_common_flags) \ - --target=$(objtree)/rust/target.json \ + --target=$(objtree)/scripts/target.json \ -Cpanic=abort -Cembed-bitcode=n -Clto=n \ -Cforce-unwind-tables=n -Ccodegen-units=1 \ -Csymbol-mangling-version=v0 \ @@ -1606,7 +1606,7 @@ MRPROPER_FILES += include/config include/generated \ certs/x509.genkey \ vmlinux-gdb.py \ *.spec \ - rust/target.json rust/libmacros.so + rust/libmacros.so # clean - Delete most, but leave enough to build external modules # diff --git a/rust/.gitignore b/rust/.gitignore index 9bd1af8e05a1..168cb26a31b9 100644 --- a/rust/.gitignore +++ b/rust/.gitignore @@ -1,6 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 -target.json bindings_generated.rs bindings_helpers_generated.rs exports_*_generated.h diff --git a/rust/Makefile b/rust/Makefile index f403b79cae5a..829f4adfd85c 100644 --- a/rust/Makefile +++ b/rust/Makefile @@ -1,8 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 -always-$(CONFIG_RUST) += target.json -no-clean-files += target.json - obj-$(CONFIG_RUST) += core.o compiler_builtins.o always-$(CONFIG_RUST) += exports_core_generated.h @@ -231,11 +228,6 @@ rusttest-kernel: $(src)/kernel/lib.rs rusttest-prepare \ $(call if_changed,rustc_test) $(call if_changed,rustc_test_library) -filechk_rust_target = $(objtree)/scripts/generate_rust_target < $< - -$(obj)/target.json: $(objtree)/include/config/auto.conf FORCE - $(call filechk,rust_target) - ifdef CONFIG_CC_IS_CLANG bindgen_c_flags = $(c_flags) else @@ -359,7 +351,7 @@ rust-analyzer: $(obj)/core.o: private skip_clippy = 1 $(obj)/core.o: private skip_flags = -Dunreachable_pub $(obj)/core.o: private rustc_target_flags = $(core-cfgs) -$(obj)/core.o: $(RUST_LIB_SRC)/core/src/lib.rs $(obj)/target.json FORCE +$(obj)/core.o: $(RUST_LIB_SRC)/core/src/lib.rs scripts/target.json FORCE $(call if_changed_dep,rustc_library) $(obj)/compiler_builtins.o: private rustc_objcopy = -w -W '__*' diff --git a/scripts/.gitignore b/scripts/.gitignore index b7aec8eb1bd4..11bf3c075fb6 100644 --- a/scripts/.gitignore +++ b/scripts/.gitignore @@ -8,4 +8,5 @@ /recordmcount /sign-file /sorttable +/target.json /unifdef diff --git a/scripts/Makefile b/scripts/Makefile index 1575af84d557..0e0ae3c06ed7 100644 --- a/scripts/Makefile +++ b/scripts/Makefile @@ -10,8 +10,14 @@ hostprogs-always-$(CONFIG_BUILDTIME_TABLE_SORT) += sorttable hostprogs-always-$(CONFIG_ASN1) += asn1_compiler hostprogs-always-$(CONFIG_MODULE_SIG_FORMAT) += sign-file hostprogs-always-$(CONFIG_SYSTEM_EXTRA_CERTIFICATE) += insert-sys-cert -hostprogs-always-$(CONFIG_RUST) += generate_rust_target +always-$(CONFIG_RUST) += target.json +filechk_rust_target = $< < include/config/auto.conf + +$(obj)/target.json: scripts/generate_rust_target include/config/auto.conf FORCE + $(call filechk,rust_target) + +hostprogs += generate_rust_target generate_rust_target-rust := y HOSTCFLAGS_sorttable.o = -I$(srctree)/tools/include diff --git a/scripts/remove-stale-files b/scripts/remove-stale-files index cdbdde89a271..c71bf2f68360 100755 --- a/scripts/remove-stale-files +++ b/scripts/remove-stale-files @@ -27,3 +27,5 @@ rm -f arch/x86/purgatory/kexec-purgatory.c rm -f scripts/extract-cert rm -f scripts/kconfig/[gmnq]conf-cfg + +rm -f rust/target.json -- cgit v1.2.3-59-g8ed1b