Commit 2f7ab126 authored by Miguel Ojeda's avatar Miguel Ojeda

Kbuild: add Rust support

Having most of the new files in place, we now enable Rust support
in the build system, including `Kconfig` entries related to Rust,
the Rust configuration printer and a few other bits.
Reviewed-by: default avatarKees Cook <keescook@chromium.org>
Reviewed-by: default avatarNick Desaulniers <ndesaulniers@google.com>
Tested-by: default avatarNick Desaulniers <ndesaulniers@google.com>
Reviewed-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Co-developed-by: default avatarAlex Gaynor <alex.gaynor@gmail.com>
Signed-off-by: default avatarAlex Gaynor <alex.gaynor@gmail.com>
Co-developed-by: default avatarFinn Behrens <me@kloenk.de>
Signed-off-by: default avatarFinn Behrens <me@kloenk.de>
Co-developed-by: default avatarAdam Bratschi-Kaye <ark.email@gmail.com>
Signed-off-by: default avatarAdam Bratschi-Kaye <ark.email@gmail.com>
Co-developed-by: default avatarWedson Almeida Filho <wedsonaf@google.com>
Signed-off-by: default avatarWedson Almeida Filho <wedsonaf@google.com>
Co-developed-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Co-developed-by: default avatarSven Van Asbroeck <thesven73@gmail.com>
Signed-off-by: default avatarSven Van Asbroeck <thesven73@gmail.com>
Co-developed-by: default avatarGary Guo <gary@garyguo.net>
Signed-off-by: default avatarGary Guo <gary@garyguo.net>
Co-developed-by: default avatarBoris-Chengbiao Zhou <bobo1239@web.de>
Signed-off-by: default avatarBoris-Chengbiao Zhou <bobo1239@web.de>
Co-developed-by: default avatarBoqun Feng <boqun.feng@gmail.com>
Signed-off-by: default avatarBoqun Feng <boqun.feng@gmail.com>
Co-developed-by: default avatarDouglas Su <d0u9.su@outlook.com>
Signed-off-by: default avatarDouglas Su <d0u9.su@outlook.com>
Co-developed-by: default avatarDariusz Sosnowski <dsosnowski@dsosnowski.pl>
Signed-off-by: default avatarDariusz Sosnowski <dsosnowski@dsosnowski.pl>
Co-developed-by: default avatarAntonio Terceiro <antonio.terceiro@linaro.org>
Signed-off-by: default avatarAntonio Terceiro <antonio.terceiro@linaro.org>
Co-developed-by: default avatarDaniel Xu <dxu@dxuuu.xyz>
Signed-off-by: default avatarDaniel Xu <dxu@dxuuu.xyz>
Co-developed-by: default avatarBjörn Roy Baron <bjorn3_gh@protonmail.com>
Signed-off-by: default avatarBjörn Roy Baron <bjorn3_gh@protonmail.com>
Co-developed-by: default avatarMartin Rodriguez Reboredo <yakoyoku@gmail.com>
Signed-off-by: default avatarMartin Rodriguez Reboredo <yakoyoku@gmail.com>
Signed-off-by: default avatarMiguel Ojeda <ojeda@kernel.org>
parent 80db40ba
...@@ -37,6 +37,8 @@ ...@@ -37,6 +37,8 @@
*.o *.o
*.o.* *.o.*
*.patch *.patch
*.rmeta
*.rsi
*.s *.s
*.so *.so
*.so.dbg *.so.dbg
......
This diff is collapsed.
...@@ -355,6 +355,12 @@ config HAVE_RSEQ ...@@ -355,6 +355,12 @@ config HAVE_RSEQ
This symbol should be selected by an architecture if it This symbol should be selected by an architecture if it
supports an implementation of restartable sequences. supports an implementation of restartable sequences.
config HAVE_RUST
bool
help
This symbol should be selected by an architecture if it
supports Rust.
config HAVE_FUNCTION_ARG_ACCESS_API config HAVE_FUNCTION_ARG_ACCESS_API
bool bool
help help
......
...@@ -4,8 +4,12 @@ ...@@ -4,8 +4,12 @@
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
/*
* Skipped when running bindgen due to a libclang issue;
* see https://github.com/rust-lang/rust-bindgen/issues/2244.
*/
#if defined(CONFIG_DEBUG_INFO_BTF) && defined(CONFIG_PAHOLE_HAS_BTF_TAG) && \ #if defined(CONFIG_DEBUG_INFO_BTF) && defined(CONFIG_PAHOLE_HAS_BTF_TAG) && \
__has_attribute(btf_type_tag) __has_attribute(btf_type_tag) && !defined(__BINDGEN__)
# define BTF_TYPE_TAG(value) __attribute__((btf_type_tag(#value))) # define BTF_TYPE_TAG(value) __attribute__((btf_type_tag(#value)))
#else #else
# define BTF_TYPE_TAG(value) /* nothing */ # define BTF_TYPE_TAG(value) /* nothing */
......
...@@ -60,6 +60,17 @@ config LLD_VERSION ...@@ -60,6 +60,17 @@ config LLD_VERSION
default $(ld-version) if LD_IS_LLD default $(ld-version) if LD_IS_LLD
default 0 default 0
config RUST_IS_AVAILABLE
def_bool $(success,$(srctree)/scripts/rust_is_available.sh)
help
This shows whether a suitable Rust toolchain is available (found).
Please see Documentation/rust/quick-start.rst for instructions on how
to satify the build requirements of Rust support.
In particular, the Makefile target 'rustavailable' is useful to check
why the Rust toolchain is not being detected.
config CC_CAN_LINK config CC_CAN_LINK
bool bool
default $(success,$(srctree)/scripts/cc-can-link.sh $(CC) $(CLANG_FLAGS) $(USERCFLAGS) $(USERLDFLAGS) $(m64-flag)) if 64BIT default $(success,$(srctree)/scripts/cc-can-link.sh $(CC) $(CLANG_FLAGS) $(USERCFLAGS) $(USERLDFLAGS) $(m64-flag)) if 64BIT
...@@ -147,7 +158,8 @@ config WERROR ...@@ -147,7 +158,8 @@ config WERROR
default COMPILE_TEST default COMPILE_TEST
help help
A kernel build should not cause any compiler warnings, and this A kernel build should not cause any compiler warnings, and this
enables the '-Werror' flag to enforce that rule by default. enables the '-Werror' (for C) and '-Dwarnings' (for Rust) flags
to enforce that rule by default.
However, if you have a new (or very old) compiler with odd and However, if you have a new (or very old) compiler with odd and
unusual warnings, or you have some architecture with problems, unusual warnings, or you have some architecture with problems,
...@@ -1899,6 +1911,38 @@ config PROFILING ...@@ -1899,6 +1911,38 @@ config PROFILING
Say Y here to enable the extended profiling support mechanisms used Say Y here to enable the extended profiling support mechanisms used
by profilers. by profilers.
config RUST
bool "Rust support"
depends on HAVE_RUST
depends on RUST_IS_AVAILABLE
depends on !MODVERSIONS
depends on !GCC_PLUGINS
depends on !RANDSTRUCT
depends on !DEBUG_INFO_BTF
select CONSTRUCTORS
help
Enables Rust support in the kernel.
This allows other Rust-related options, like drivers written in Rust,
to be selected.
It is also required to be able to load external kernel modules
written in Rust.
See Documentation/rust/ for more information.
If unsure, say N.
config RUSTC_VERSION_TEXT
string
depends on RUST
default $(shell,command -v $(RUSTC) >/dev/null 2>&1 && $(RUSTC) --version || echo n)
config BINDGEN_VERSION_TEXT
string
depends on RUST
default $(shell,command -v $(BINDGEN) >/dev/null 2>&1 && $(BINDGEN) --version || echo n)
# #
# Place an empty function call at each tracepoint site. Can be # Place an empty function call at each tracepoint site. Can be
# dynamically changed for a probe function. # dynamically changed for a probe function.
......
...@@ -2710,6 +2710,40 @@ config HYPERV_TESTING ...@@ -2710,6 +2710,40 @@ config HYPERV_TESTING
endmenu # "Kernel Testing and Coverage" endmenu # "Kernel Testing and Coverage"
menu "Rust hacking"
config RUST_DEBUG_ASSERTIONS
bool "Debug assertions"
depends on RUST
help
Enables rustc's `-Cdebug-assertions` codegen option.
This flag lets you turn `cfg(debug_assertions)` conditional
compilation on or off. This can be used to enable extra debugging
code in development but not in production. For example, it controls
the behavior of the standard library's `debug_assert!` macro.
Note that this will apply to all Rust code, including `core`.
If unsure, say N.
config RUST_OVERFLOW_CHECKS
bool "Overflow checks"
default y
depends on RUST
help
Enables rustc's `-Coverflow-checks` codegen option.
This flag allows you to control the behavior of runtime integer
overflow. When overflow-checks are enabled, a Rust panic will occur
on overflow.
Note that this will apply to all Rust code, including `core`.
If unsure, say Y.
endmenu # "Rust"
source "Documentation/Kconfig" source "Documentation/Kconfig"
endmenu # Kernel hacking endmenu # Kernel hacking
# SPDX-License-Identifier: GPL-2.0
target.json
bindings_generated.rs
bindings_helpers_generated.rs
exports_*_generated.h
doc/
test/
This diff is collapsed.
# SPDX-License-Identifier: GPL-2.0
--opaque-type xregs_state
--opaque-type desc_struct
--opaque-type arch_lbr_state
--opaque-type local_apic
# Packed type cannot transitively contain a `#[repr(align)]` type.
--opaque-type x86_msi_data
--opaque-type x86_msi_addr_lo
# `try` is a reserved keyword since Rust 2018; solved in `bindgen` v0.59.2,
# commit 2aed6b021680 ("context: Escape the try keyword properly").
--opaque-type kunit_try_catch
# If SMP is disabled, `arch_spinlock_t` is defined as a ZST which triggers a Rust
# warning. We don't need to peek into it anyway.
--opaque-type spinlock
# `seccomp`'s comment gets understood as a doctest
--no-doc-comments
...@@ -36,12 +36,12 @@ ld-option = $(success,$(LD) -v $(1)) ...@@ -36,12 +36,12 @@ ld-option = $(success,$(LD) -v $(1))
as-instr = $(success,printf "%b\n" "$(1)" | $(CC) $(CLANG_FLAGS) -c -x assembler -o /dev/null -) as-instr = $(success,printf "%b\n" "$(1)" | $(CC) $(CLANG_FLAGS) -c -x assembler -o /dev/null -)
# check if $(CC) and $(LD) exist # check if $(CC) and $(LD) exist
$(error-if,$(failure,command -v $(CC)),compiler '$(CC)' not found) $(error-if,$(failure,command -v $(CC)),C compiler '$(CC)' not found)
$(error-if,$(failure,command -v $(LD)),linker '$(LD)' not found) $(error-if,$(failure,command -v $(LD)),linker '$(LD)' not found)
# Get the compiler name, version, and error out if it is not supported. # Get the C compiler name, version, and error out if it is not supported.
cc-info := $(shell,$(srctree)/scripts/cc-version.sh $(CC)) cc-info := $(shell,$(srctree)/scripts/cc-version.sh $(CC))
$(error-if,$(success,test -z "$(cc-info)"),Sorry$(comma) this compiler is not supported.) $(error-if,$(success,test -z "$(cc-info)"),Sorry$(comma) this C compiler is not supported.)
cc-name := $(shell,set -- $(cc-info) && echo $1) cc-name := $(shell,set -- $(cc-info) && echo $1)
cc-version := $(shell,set -- $(cc-info) && echo $2) cc-version := $(shell,set -- $(cc-info) && echo $2)
......
...@@ -10,6 +10,9 @@ hostprogs-always-$(CONFIG_BUILDTIME_TABLE_SORT) += sorttable ...@@ -10,6 +10,9 @@ hostprogs-always-$(CONFIG_BUILDTIME_TABLE_SORT) += sorttable
hostprogs-always-$(CONFIG_ASN1) += asn1_compiler hostprogs-always-$(CONFIG_ASN1) += asn1_compiler
hostprogs-always-$(CONFIG_MODULE_SIG_FORMAT) += sign-file hostprogs-always-$(CONFIG_MODULE_SIG_FORMAT) += sign-file
hostprogs-always-$(CONFIG_SYSTEM_EXTRA_CERTIFICATE) += insert-sys-cert hostprogs-always-$(CONFIG_SYSTEM_EXTRA_CERTIFICATE) += insert-sys-cert
hostprogs-always-$(CONFIG_RUST) += generate_rust_target
generate_rust_target-rust := y
HOSTCFLAGS_sorttable.o = -I$(srctree)/tools/include HOSTCFLAGS_sorttable.o = -I$(srctree)/tools/include
HOSTLDLIBS_sorttable = -lpthread HOSTLDLIBS_sorttable = -lpthread
......
...@@ -26,6 +26,7 @@ EXTRA_CPPFLAGS := ...@@ -26,6 +26,7 @@ EXTRA_CPPFLAGS :=
EXTRA_LDFLAGS := EXTRA_LDFLAGS :=
asflags-y := asflags-y :=
ccflags-y := ccflags-y :=
rustflags-y :=
cppflags-y := cppflags-y :=
ldflags-y := ldflags-y :=
...@@ -271,6 +272,65 @@ quiet_cmd_cc_lst_c = MKLST $@ ...@@ -271,6 +272,65 @@ quiet_cmd_cc_lst_c = MKLST $@
$(obj)/%.lst: $(src)/%.c FORCE $(obj)/%.lst: $(src)/%.c FORCE
$(call if_changed_dep,cc_lst_c) $(call if_changed_dep,cc_lst_c)
# Compile Rust sources (.rs)
# ---------------------------------------------------------------------------
rust_allowed_features := core_ffi_c
rust_common_cmd = \
RUST_MODFILE=$(modfile) $(RUSTC_OR_CLIPPY) $(rust_flags) \
-Zallow-features=$(rust_allowed_features) \
-Zcrate-attr=no_std \
-Zcrate-attr='feature($(rust_allowed_features))' \
--extern alloc --extern kernel \
--crate-type rlib --out-dir $(obj) -L $(objtree)/rust/ \
--crate-name $(basename $(notdir $@))
rust_handle_depfile = \
mv $(obj)/$(basename $(notdir $@)).d $(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
# requesting it explicitly and we start using some other `--emit` that does not
# imply it (and for which codegen is performed), then we would be out of sync,
# i.e. the outputs we would get for the different single targets (e.g. `.ll`)
# would not match each other.
quiet_cmd_rustc_o_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@
cmd_rustc_o_rs = \
$(rust_common_cmd) --emit=dep-info,obj $<; \
$(rust_handle_depfile)
$(obj)/%.o: $(src)/%.rs FORCE
$(call if_changed_dep,rustc_o_rs)
quiet_cmd_rustc_rsi_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@
cmd_rustc_rsi_rs = \
$(rust_common_cmd) --emit=dep-info -Zunpretty=expanded $< >$@; \
command -v $(RUSTFMT) >/dev/null && $(RUSTFMT) $@; \
$(rust_handle_depfile)
$(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=dep-info,asm $<; \
$(rust_handle_depfile)
$(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=dep-info,llvm-ir $<; \
$(rust_handle_depfile)
$(obj)/%.ll: $(src)/%.rs FORCE
$(call if_changed_dep,rustc_ll_rs)
# Compile assembler sources (.S) # Compile assembler sources (.S)
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
......
DEBUG_CFLAGS := DEBUG_CFLAGS :=
DEBUG_RUSTFLAGS :=
debug-flags-y := -g debug-flags-y := -g
ifdef CONFIG_DEBUG_INFO_SPLIT ifdef CONFIG_DEBUG_INFO_SPLIT
...@@ -17,9 +19,12 @@ KBUILD_AFLAGS += $(debug-flags-y) ...@@ -17,9 +19,12 @@ KBUILD_AFLAGS += $(debug-flags-y)
ifdef CONFIG_DEBUG_INFO_REDUCED ifdef CONFIG_DEBUG_INFO_REDUCED
DEBUG_CFLAGS += -fno-var-tracking DEBUG_CFLAGS += -fno-var-tracking
DEBUG_RUSTFLAGS += -Cdebuginfo=1
ifdef CONFIG_CC_IS_GCC ifdef CONFIG_CC_IS_GCC
DEBUG_CFLAGS += -femit-struct-debug-baseonly DEBUG_CFLAGS += -femit-struct-debug-baseonly
endif endif
else
DEBUG_RUSTFLAGS += -Cdebuginfo=2
endif endif
ifdef CONFIG_DEBUG_INFO_COMPRESSED ifdef CONFIG_DEBUG_INFO_COMPRESSED
...@@ -30,3 +35,6 @@ endif ...@@ -30,3 +35,6 @@ endif
KBUILD_CFLAGS += $(DEBUG_CFLAGS) KBUILD_CFLAGS += $(DEBUG_CFLAGS)
export DEBUG_CFLAGS export DEBUG_CFLAGS
KBUILD_RUSTFLAGS += $(DEBUG_RUSTFLAGS)
export DEBUG_RUSTFLAGS
...@@ -22,6 +22,8 @@ $(obj)/%.tab.c $(obj)/%.tab.h: $(src)/%.y FORCE ...@@ -22,6 +22,8 @@ $(obj)/%.tab.c $(obj)/%.tab.h: $(src)/%.y FORCE
# to preprocess a data file. # to preprocess a data file.
# #
# Both C and C++ are supported, but preferred language is C for such utilities. # Both C and C++ are supported, but preferred language is C for such utilities.
# Rust is also supported, but it may only be used in scenarios where a Rust
# toolchain is required to be available (e.g. when `CONFIG_RUST` is enabled).
# #
# Sample syntax (see Documentation/kbuild/makefiles.rst for reference) # Sample syntax (see Documentation/kbuild/makefiles.rst for reference)
# hostprogs := bin2hex # hostprogs := bin2hex
...@@ -37,15 +39,20 @@ $(obj)/%.tab.c $(obj)/%.tab.h: $(src)/%.y FORCE ...@@ -37,15 +39,20 @@ $(obj)/%.tab.c $(obj)/%.tab.h: $(src)/%.y FORCE
# qconf-objs := menu.o # qconf-objs := menu.o
# Will compile qconf as a C++ program, and menu as a C program. # Will compile qconf as a C++ program, and menu as a C program.
# They are linked as C++ code to the executable qconf # They are linked as C++ code to the executable qconf
#
# hostprogs := target
# target-rust := y
# Will compile `target` as a Rust program, using `target.rs` as the crate root.
# The crate may consist of several source files.
# C code # C code
# Executables compiled from a single .c file # Executables compiled from a single .c file
host-csingle := $(foreach m,$(hostprogs), \ host-csingle := $(foreach m,$(hostprogs), \
$(if $($(m)-objs)$($(m)-cxxobjs),,$(m))) $(if $($(m)-objs)$($(m)-cxxobjs)$($(m)-rust),,$(m)))
# C executables linked based on several .o files # C executables linked based on several .o files
host-cmulti := $(foreach m,$(hostprogs),\ host-cmulti := $(foreach m,$(hostprogs),\
$(if $($(m)-cxxobjs),,$(if $($(m)-objs),$(m)))) $(if $($(m)-cxxobjs)$($(m)-rust),,$(if $($(m)-objs),$(m))))
# Object (.o) files compiled from .c files # Object (.o) files compiled from .c files
host-cobjs := $(sort $(foreach m,$(hostprogs),$($(m)-objs))) host-cobjs := $(sort $(foreach m,$(hostprogs),$($(m)-objs)))
...@@ -58,11 +65,17 @@ host-cxxmulti := $(foreach m,$(hostprogs),$(if $($(m)-cxxobjs),$(m))) ...@@ -58,11 +65,17 @@ host-cxxmulti := $(foreach m,$(hostprogs),$(if $($(m)-cxxobjs),$(m)))
# C++ Object (.o) files compiled from .cc files # C++ Object (.o) files compiled from .cc files
host-cxxobjs := $(sort $(foreach m,$(host-cxxmulti),$($(m)-cxxobjs))) host-cxxobjs := $(sort $(foreach m,$(host-cxxmulti),$($(m)-cxxobjs)))
# Rust code
# Executables compiled from a single Rust crate (which may consist of
# one or more .rs files)
host-rust := $(foreach m,$(hostprogs),$(if $($(m)-rust),$(m)))
host-csingle := $(addprefix $(obj)/,$(host-csingle)) host-csingle := $(addprefix $(obj)/,$(host-csingle))
host-cmulti := $(addprefix $(obj)/,$(host-cmulti)) host-cmulti := $(addprefix $(obj)/,$(host-cmulti))
host-cobjs := $(addprefix $(obj)/,$(host-cobjs)) host-cobjs := $(addprefix $(obj)/,$(host-cobjs))
host-cxxmulti := $(addprefix $(obj)/,$(host-cxxmulti)) host-cxxmulti := $(addprefix $(obj)/,$(host-cxxmulti))
host-cxxobjs := $(addprefix $(obj)/,$(host-cxxobjs)) host-cxxobjs := $(addprefix $(obj)/,$(host-cxxobjs))
host-rust := $(addprefix $(obj)/,$(host-rust))
##### #####
# Handle options to gcc. Support building with separate output directory # Handle options to gcc. Support building with separate output directory
...@@ -71,6 +84,8 @@ _hostc_flags = $(KBUILD_HOSTCFLAGS) $(HOST_EXTRACFLAGS) \ ...@@ -71,6 +84,8 @@ _hostc_flags = $(KBUILD_HOSTCFLAGS) $(HOST_EXTRACFLAGS) \
$(HOSTCFLAGS_$(target-stem).o) $(HOSTCFLAGS_$(target-stem).o)
_hostcxx_flags = $(KBUILD_HOSTCXXFLAGS) $(HOST_EXTRACXXFLAGS) \ _hostcxx_flags = $(KBUILD_HOSTCXXFLAGS) $(HOST_EXTRACXXFLAGS) \
$(HOSTCXXFLAGS_$(target-stem).o) $(HOSTCXXFLAGS_$(target-stem).o)
_hostrust_flags = $(KBUILD_HOSTRUSTFLAGS) $(HOST_EXTRARUSTFLAGS) \
$(HOSTRUSTFLAGS_$(target-stem))
# $(objtree)/$(obj) for including generated headers from checkin source files # $(objtree)/$(obj) for including generated headers from checkin source files
ifeq ($(KBUILD_EXTMOD),) ifeq ($(KBUILD_EXTMOD),)
...@@ -82,6 +97,7 @@ endif ...@@ -82,6 +97,7 @@ endif
hostc_flags = -Wp,-MMD,$(depfile) $(_hostc_flags) hostc_flags = -Wp,-MMD,$(depfile) $(_hostc_flags)
hostcxx_flags = -Wp,-MMD,$(depfile) $(_hostcxx_flags) hostcxx_flags = -Wp,-MMD,$(depfile) $(_hostcxx_flags)
hostrust_flags = $(_hostrust_flags)
##### #####
# Compile programs on the host # Compile programs on the host
...@@ -128,5 +144,17 @@ quiet_cmd_host-cxxobjs = HOSTCXX $@ ...@@ -128,5 +144,17 @@ quiet_cmd_host-cxxobjs = HOSTCXX $@
$(host-cxxobjs): $(obj)/%.o: $(src)/%.cc FORCE $(host-cxxobjs): $(obj)/%.o: $(src)/%.cc FORCE
$(call if_changed_dep,host-cxxobjs) $(call if_changed_dep,host-cxxobjs)
# Create executable from a single Rust crate (which may consist of
# one or more `.rs` files)
# host-rust -> Executable
quiet_cmd_host-rust = HOSTRUSTC $@
cmd_host-rust = \
$(HOSTRUSTC) $(hostrust_flags) --emit=dep-info,link \
--out-dir=$(obj)/ $<; \
mv $(obj)/$(target-stem).d $(depfile); \
sed -i '/^\#/d' $(depfile)
$(host-rust): $(obj)/%: $(src)/%.rs FORCE
$(call if_changed_dep,host-rust)
targets += $(host-csingle) $(host-cmulti) $(host-cobjs) \ targets += $(host-csingle) $(host-cmulti) $(host-cobjs) \
$(host-cxxmulti) $(host-cxxobjs) $(host-cxxmulti) $(host-cxxobjs) $(host-rust)
...@@ -8,6 +8,7 @@ ldflags-y += $(EXTRA_LDFLAGS) ...@@ -8,6 +8,7 @@ ldflags-y += $(EXTRA_LDFLAGS)
# flags that take effect in current and sub directories # flags that take effect in current and sub directories
KBUILD_AFLAGS += $(subdir-asflags-y) KBUILD_AFLAGS += $(subdir-asflags-y)
KBUILD_CFLAGS += $(subdir-ccflags-y) KBUILD_CFLAGS += $(subdir-ccflags-y)
KBUILD_RUSTFLAGS += $(subdir-rustflags-y)
# Figure out what we need to build from the various variables # Figure out what we need to build from the various variables
# =========================================================================== # ===========================================================================
...@@ -128,6 +129,10 @@ _c_flags = $(filter-out $(CFLAGS_REMOVE_$(target-stem).o), \ ...@@ -128,6 +129,10 @@ _c_flags = $(filter-out $(CFLAGS_REMOVE_$(target-stem).o), \
$(filter-out $(ccflags-remove-y), \ $(filter-out $(ccflags-remove-y), \
$(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(ccflags-y)) \ $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(ccflags-y)) \
$(CFLAGS_$(target-stem).o)) $(CFLAGS_$(target-stem).o))
_rust_flags = $(filter-out $(RUSTFLAGS_REMOVE_$(target-stem).o), \
$(filter-out $(rustflags-remove-y), \
$(KBUILD_RUSTFLAGS) $(rustflags-y)) \
$(RUSTFLAGS_$(target-stem).o))
_a_flags = $(filter-out $(AFLAGS_REMOVE_$(target-stem).o), \ _a_flags = $(filter-out $(AFLAGS_REMOVE_$(target-stem).o), \
$(filter-out $(asflags-remove-y), \ $(filter-out $(asflags-remove-y), \
$(KBUILD_CPPFLAGS) $(KBUILD_AFLAGS) $(asflags-y)) \ $(KBUILD_CPPFLAGS) $(KBUILD_AFLAGS) $(asflags-y)) \
...@@ -202,6 +207,11 @@ modkern_cflags = \ ...@@ -202,6 +207,11 @@ modkern_cflags = \
$(KBUILD_CFLAGS_MODULE) $(CFLAGS_MODULE), \ $(KBUILD_CFLAGS_MODULE) $(CFLAGS_MODULE), \
$(KBUILD_CFLAGS_KERNEL) $(CFLAGS_KERNEL) $(modfile_flags)) $(KBUILD_CFLAGS_KERNEL) $(CFLAGS_KERNEL) $(modfile_flags))
modkern_rustflags = \
$(if $(part-of-module), \
$(KBUILD_RUSTFLAGS_MODULE) $(RUSTFLAGS_MODULE), \
$(KBUILD_RUSTFLAGS_KERNEL) $(RUSTFLAGS_KERNEL))
modkern_aflags = $(if $(part-of-module), \ modkern_aflags = $(if $(part-of-module), \
$(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE), \ $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE), \
$(KBUILD_AFLAGS_KERNEL) $(AFLAGS_KERNEL)) $(KBUILD_AFLAGS_KERNEL) $(AFLAGS_KERNEL))
...@@ -211,6 +221,8 @@ c_flags = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ ...@@ -211,6 +221,8 @@ c_flags = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
$(_c_flags) $(modkern_cflags) \ $(_c_flags) $(modkern_cflags) \
$(basename_flags) $(modname_flags) $(basename_flags) $(modname_flags)
rust_flags = $(_rust_flags) $(modkern_rustflags) @$(objtree)/include/generated/rustc_cfg
a_flags = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ a_flags = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
$(_a_flags) $(modkern_aflags) $(_a_flags) $(modkern_aflags)
......
...@@ -39,11 +39,13 @@ quiet_cmd_ld_ko_o = LD [M] $@ ...@@ -39,11 +39,13 @@ quiet_cmd_ld_ko_o = LD [M] $@
quiet_cmd_btf_ko = BTF [M] $@ quiet_cmd_btf_ko = BTF [M] $@
cmd_btf_ko = \ cmd_btf_ko = \
if [ -f vmlinux ]; then \ if [ ! -f vmlinux ]; then \
printf "Skipping BTF generation for %s due to unavailability of vmlinux\n" $@ 1>&2; \
elif [ -n "$(CONFIG_RUST)" ] && $(srctree)/scripts/is_rust_module.sh $@; then \
printf "Skipping BTF generation for %s because it's a Rust module\n" $@ 1>&2; \
else \
LLVM_OBJCOPY="$(OBJCOPY)" $(PAHOLE) -J $(PAHOLE_FLAGS) --btf_base vmlinux $@; \ LLVM_OBJCOPY="$(OBJCOPY)" $(PAHOLE) -J $(PAHOLE_FLAGS) --btf_base vmlinux $@; \
$(RESOLVE_BTFIDS) -b vmlinux $@; \ $(RESOLVE_BTFIDS) -b vmlinux $@; \
else \
printf "Skipping BTF generation for %s due to unavailability of vmlinux\n" $@ 1>&2; \
fi; fi;
# Same as newer-prereqs, but allows to exclude specified extra dependencies # Same as newer-prereqs, but allows to exclude specified extra dependencies
......
#!/bin/sh #!/bin/sh
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
# #
# Print the compiler name and its version in a 5 or 6-digit form. # Print the C compiler name and its version in a 5 or 6-digit form.
# Also, perform the minimum version check. # Also, perform the minimum version check.
set -e set -e
# Print the compiler name and some version components. # Print the C compiler name and some version components.
get_compiler_info() get_c_compiler_info()
{ {
cat <<- EOF | "$@" -E -P -x c - 2>/dev/null cat <<- EOF | "$@" -E -P -x c - 2>/dev/null
#if defined(__clang__) #if defined(__clang__)
...@@ -32,7 +32,7 @@ get_canonical_version() ...@@ -32,7 +32,7 @@ get_canonical_version()
# $@ instead of $1 because multiple words might be given, e.g. CC="ccache gcc". # $@ instead of $1 because multiple words might be given, e.g. CC="ccache gcc".
orig_args="$@" orig_args="$@"
set -- $(get_compiler_info "$@") set -- $(get_c_compiler_info "$@")
name=$1 name=$1
...@@ -52,7 +52,7 @@ ICC) ...@@ -52,7 +52,7 @@ ICC)
min_version=$($min_tool_version icc) min_version=$($min_tool_version icc)
;; ;;
*) *)
echo "$orig_args: unknown compiler" >&2 echo "$orig_args: unknown C compiler" >&2
exit 1 exit 1
;; ;;
esac esac
...@@ -62,7 +62,7 @@ min_cversion=$(get_canonical_version $min_version) ...@@ -62,7 +62,7 @@ min_cversion=$(get_canonical_version $min_version)
if [ "$cversion" -lt "$min_cversion" ]; then if [ "$cversion" -lt "$min_cversion" ]; then
echo >&2 "***" echo >&2 "***"
echo >&2 "*** Compiler is too old." echo >&2 "*** C compiler is too old."
echo >&2 "*** Your $name version: $version" echo >&2 "*** Your $name version: $version"
echo >&2 "*** Minimum $name version: $min_version" echo >&2 "*** Minimum $name version: $min_version"
echo >&2 "***" echo >&2 "***"
......
...@@ -216,6 +216,13 @@ static const char *conf_get_autoheader_name(void) ...@@ -216,6 +216,13 @@ static const char *conf_get_autoheader_name(void)
return name ? name : "include/generated/autoconf.h"; return name ? name : "include/generated/autoconf.h";
} }
static const char *conf_get_rustccfg_name(void)
{
char *name = getenv("KCONFIG_RUSTCCFG");
return name ? name : "include/generated/rustc_cfg";
}
static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p) static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p)
{ {
char *p2; char *p2;
...@@ -605,6 +612,9 @@ static const struct comment_style comment_style_c = { ...@@ -605,6 +612,9 @@ static const struct comment_style comment_style_c = {
static void conf_write_heading(FILE *fp, const struct comment_style *cs) static void conf_write_heading(FILE *fp, const struct comment_style *cs)
{ {
if (!cs)
return;
fprintf(fp, "%s\n", cs->prefix); fprintf(fp, "%s\n", cs->prefix);
fprintf(fp, "%s Automatically generated file; DO NOT EDIT.\n", fprintf(fp, "%s Automatically generated file; DO NOT EDIT.\n",
...@@ -745,6 +755,65 @@ static void print_symbol_for_c(FILE *fp, struct symbol *sym) ...@@ -745,6 +755,65 @@ static void print_symbol_for_c(FILE *fp, struct symbol *sym)
free(escaped); free(escaped);
} }
static void print_symbol_for_rustccfg(FILE *fp, struct symbol *sym)
{
const char *val;
const char *val_prefix = "";
char *val_prefixed = NULL;
size_t val_prefixed_len;
char *escaped = NULL;
if (sym->type == S_UNKNOWN)
return;
val = sym_get_string_value(sym);
switch (sym->type) {
case S_BOOLEAN:
case S_TRISTATE:
/*
* We do not care about disabled ones, i.e. no need for
* what otherwise are "comments" in other printers.
*/
if (*val == 'n')
return;
/*
* To have similar functionality to the C macro `IS_ENABLED()`
* we provide an empty `--cfg CONFIG_X` here in both `y`
* and `m` cases.
*
* Then, the common `fprintf()` below will also give us
* a `--cfg CONFIG_X="y"` or `--cfg CONFIG_X="m"`, which can
* be used as the equivalent of `IS_BUILTIN()`/`IS_MODULE()`.
*/
fprintf(fp, "--cfg=%s%s\n", CONFIG_, sym->name);
break;
case S_HEX:
if (val[0] != '0' || (val[1] != 'x' && val[1] != 'X'))
val_prefix = "0x";
break;
default:
break;
}
if (strlen(val_prefix) > 0) {
val_prefixed_len = strlen(val) + strlen(val_prefix) + 1;
val_prefixed = xmalloc(val_prefixed_len);
snprintf(val_prefixed, val_prefixed_len, "%s%s", val_prefix, val);
val = val_prefixed;
}
/* All values get escaped: the `--cfg` option only takes strings */
escaped = escape_string_value(val);
val = escaped;
fprintf(fp, "--cfg=%s%s=%s\n", CONFIG_, sym->name, val);
free(escaped);
free(val_prefixed);
}
/* /*
* Write out a minimal config. * Write out a minimal config.
* All values that has default values are skipped as this is redundant. * All values that has default values are skipped as this is redundant.
...@@ -1132,6 +1201,12 @@ int conf_write_autoconf(int overwrite) ...@@ -1132,6 +1201,12 @@ int conf_write_autoconf(int overwrite)
if (ret) if (ret)
return ret; return ret;
ret = __conf_write_autoconf(conf_get_rustccfg_name(),
print_symbol_for_rustccfg,
NULL);
if (ret)
return ret;
/* /*
* Create include/config/auto.conf. This must be the last step because * Create include/config/auto.conf. This must be the last step because
* Kbuild has a dependency on auto.conf and this marks the successful * Kbuild has a dependency on auto.conf and this marks the successful
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment