Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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: Kees Cook <keescook@chromium.org>
Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
Tested-by: Nick Desaulniers <ndesaulniers@google.com>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com>
Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com>
Co-developed-by: Finn Behrens <me@kloenk.de>
Signed-off-by: Finn Behrens <me@kloenk.de>
Co-developed-by: Adam Bratschi-Kaye <ark.email@gmail.com>
Signed-off-by: Adam Bratschi-Kaye <ark.email@gmail.com>
Co-developed-by: Wedson Almeida Filho <wedsonaf@google.com>
Signed-off-by: Wedson Almeida Filho <wedsonaf@google.com>
Co-developed-by: Michael Ellerman <mpe@ellerman.id.au>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Co-developed-by: Sven Van Asbroeck <thesven73@gmail.com>
Signed-off-by: Sven Van Asbroeck <thesven73@gmail.com>
Co-developed-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Gary Guo <gary@garyguo.net>
Co-developed-by: Boris-Chengbiao Zhou <bobo1239@web.de>
Signed-off-by: Boris-Chengbiao Zhou <bobo1239@web.de>
Co-developed-by: Boqun Feng <boqun.feng@gmail.com>
Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
Co-developed-by: Douglas Su <d0u9.su@outlook.com>
Signed-off-by: Douglas Su <d0u9.su@outlook.com>
Co-developed-by: Dariusz Sosnowski <dsosnowski@dsosnowski.pl>
Signed-off-by: Dariusz Sosnowski <dsosnowski@dsosnowski.pl>
Co-developed-by: Antonio Terceiro <antonio.terceiro@linaro.org>
Signed-off-by: Antonio Terceiro <antonio.terceiro@linaro.org>
Co-developed-by: Daniel Xu <dxu@dxuuu.xyz>
Signed-off-by: Daniel Xu <dxu@dxuuu.xyz>
Co-developed-by: Björn Roy Baron <bjorn3_gh@protonmail.com>
Signed-off-by: Björn Roy Baron <bjorn3_gh@protonmail.com>
Co-developed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
Signed-off-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com>
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>

+869 -26
+2
.gitignore
··· 37 37 *.o 38 38 *.o.* 39 39 *.patch 40 + *.rmeta 41 + *.rsi 40 42 *.s 41 43 *.so 42 44 *.so.dbg
+163 -9
Makefile
··· 120 120 121 121 export KBUILD_CHECKSRC 122 122 123 + # Enable "clippy" (a linter) as part of the Rust compilation. 124 + # 125 + # Use 'make CLIPPY=1' to enable it. 126 + ifeq ("$(origin CLIPPY)", "command line") 127 + KBUILD_CLIPPY := $(CLIPPY) 128 + endif 129 + 130 + export KBUILD_CLIPPY 131 + 123 132 # Use make M=dir or set the environment variable KBUILD_EXTMOD to specify the 124 133 # directory of external module to build. Setting M= takes precedence. 125 134 ifeq ("$(origin M)", "command line") ··· 279 270 cscope gtags TAGS tags help% %docs check% coccicheck \ 280 271 $(version_h) headers headers_% archheaders archscripts \ 281 272 %asm-generic kernelversion %src-pkg dt_binding_check \ 282 - outputmakefile 273 + outputmakefile rustavailable rustfmt rustfmtcheck 283 274 # Installation targets should not require compiler. Unfortunately, vdso_install 284 275 # is an exception where build artifacts may be updated. This must be fixed. 285 276 no-compiler-targets := $(no-dot-config-targets) install dtbs_install \ 286 277 headers_install modules_install kernelrelease image_name 287 278 no-sync-config-targets := $(no-dot-config-targets) %install kernelrelease \ 288 279 image_name 289 - single-targets := %.a %.i %.ko %.lds %.ll %.lst %.mod %.o %.s %.symtypes %/ 280 + single-targets := %.a %.i %.rsi %.ko %.lds %.ll %.lst %.mod %.o %.s %.symtypes %/ 290 281 291 282 config-build := 292 283 mixed-build := ··· 448 439 HOSTCC = gcc 449 440 HOSTCXX = g++ 450 441 endif 442 + HOSTRUSTC = rustc 451 443 HOSTPKG_CONFIG = pkg-config 452 444 453 445 KBUILD_USERHOSTCFLAGS := -Wall -Wmissing-prototypes -Wstrict-prototypes \ ··· 457 447 KBUILD_USERCFLAGS := $(KBUILD_USERHOSTCFLAGS) $(USERCFLAGS) 458 448 KBUILD_USERLDFLAGS := $(USERLDFLAGS) 459 449 450 + # These flags apply to all Rust code in the tree, including the kernel and 451 + # host programs. 452 + export rust_common_flags := --edition=2021 \ 453 + -Zbinary_dep_depinfo=y \ 454 + -Dunsafe_op_in_unsafe_fn -Drust_2018_idioms \ 455 + -Dunreachable_pub -Dnon_ascii_idents \ 456 + -Wmissing_docs \ 457 + -Drustdoc::missing_crate_level_docs \ 458 + -Dclippy::correctness -Dclippy::style \ 459 + -Dclippy::suspicious -Dclippy::complexity \ 460 + -Dclippy::perf \ 461 + -Dclippy::let_unit_value -Dclippy::mut_mut \ 462 + -Dclippy::needless_bitwise_bool \ 463 + -Dclippy::needless_continue \ 464 + -Wclippy::dbg_macro 465 + 460 466 KBUILD_HOSTCFLAGS := $(KBUILD_USERHOSTCFLAGS) $(HOST_LFS_CFLAGS) $(HOSTCFLAGS) 461 467 KBUILD_HOSTCXXFLAGS := -Wall -O2 $(HOST_LFS_CFLAGS) $(HOSTCXXFLAGS) 468 + KBUILD_HOSTRUSTFLAGS := $(rust_common_flags) -O -Cstrip=debuginfo \ 469 + -Zallow-features= $(HOSTRUSTFLAGS) 462 470 KBUILD_HOSTLDFLAGS := $(HOST_LFS_LDFLAGS) $(HOSTLDFLAGS) 463 471 KBUILD_HOSTLDLIBS := $(HOST_LFS_LIBS) $(HOSTLDLIBS) 464 472 ··· 501 473 READELF = $(CROSS_COMPILE)readelf 502 474 STRIP = $(CROSS_COMPILE)strip 503 475 endif 476 + RUSTC = rustc 477 + RUSTDOC = rustdoc 478 + RUSTFMT = rustfmt 479 + CLIPPY_DRIVER = clippy-driver 480 + BINDGEN = bindgen 481 + CARGO = cargo 504 482 PAHOLE = pahole 505 483 RESOLVE_BTFIDS = $(objtree)/tools/bpf/resolve_btfids/resolve_btfids 506 484 LEX = flex ··· 532 498 -Wbitwise -Wno-return-void -Wno-unknown-attribute $(CF) 533 499 NOSTDINC_FLAGS := 534 500 CFLAGS_MODULE = 501 + RUSTFLAGS_MODULE = 535 502 AFLAGS_MODULE = 536 503 LDFLAGS_MODULE = 537 504 CFLAGS_KERNEL = 505 + RUSTFLAGS_KERNEL = 538 506 AFLAGS_KERNEL = 539 507 LDFLAGS_vmlinux = 540 508 ··· 565 529 -Werror=return-type -Wno-format-security \ 566 530 -std=gnu11 567 531 KBUILD_CPPFLAGS := -D__KERNEL__ 532 + KBUILD_RUSTFLAGS := $(rust_common_flags) \ 533 + --target=$(objtree)/rust/target.json \ 534 + -Cpanic=abort -Cembed-bitcode=n -Clto=n \ 535 + -Cforce-unwind-tables=n -Ccodegen-units=1 \ 536 + -Csymbol-mangling-version=v0 \ 537 + -Crelocation-model=static \ 538 + -Zfunction-sections=n \ 539 + -Dclippy::float_arithmetic 540 + 568 541 KBUILD_AFLAGS_KERNEL := 569 542 KBUILD_CFLAGS_KERNEL := 543 + KBUILD_RUSTFLAGS_KERNEL := 570 544 KBUILD_AFLAGS_MODULE := -DMODULE 571 545 KBUILD_CFLAGS_MODULE := -DMODULE 546 + KBUILD_RUSTFLAGS_MODULE := --cfg MODULE 572 547 KBUILD_LDFLAGS_MODULE := 573 548 KBUILD_LDFLAGS := 574 549 CLANG_FLAGS := 575 550 551 + ifeq ($(KBUILD_CLIPPY),1) 552 + RUSTC_OR_CLIPPY_QUIET := CLIPPY 553 + RUSTC_OR_CLIPPY = $(CLIPPY_DRIVER) 554 + else 555 + RUSTC_OR_CLIPPY_QUIET := RUSTC 556 + RUSTC_OR_CLIPPY = $(RUSTC) 557 + endif 558 + 559 + ifdef RUST_LIB_SRC 560 + export RUST_LIB_SRC 561 + endif 562 + 563 + # Allows the usage of unstable features in stable compilers. 564 + export RUSTC_BOOTSTRAP := 1 565 + 576 566 export ARCH SRCARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE LD CC HOSTPKG_CONFIG 567 + export RUSTC RUSTDOC RUSTFMT RUSTC_OR_CLIPPY_QUIET RUSTC_OR_CLIPPY BINDGEN CARGO 568 + export HOSTRUSTC KBUILD_HOSTRUSTFLAGS 577 569 export CPP AR NM STRIP OBJCOPY OBJDUMP READELF PAHOLE RESOLVE_BTFIDS LEX YACC AWK INSTALLKERNEL 578 570 export PERL PYTHON3 CHECK CHECKFLAGS MAKE UTS_MACHINE HOSTCXX 579 571 export KGZIP KBZIP2 KLZOP LZMA LZ4 XZ ZSTD ··· 610 546 611 547 export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS KBUILD_LDFLAGS 612 548 export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE 549 + export KBUILD_RUSTFLAGS RUSTFLAGS_KERNEL RUSTFLAGS_MODULE 613 550 export KBUILD_AFLAGS AFLAGS_KERNEL AFLAGS_MODULE 614 - export KBUILD_AFLAGS_MODULE KBUILD_CFLAGS_MODULE KBUILD_LDFLAGS_MODULE 615 - export KBUILD_AFLAGS_KERNEL KBUILD_CFLAGS_KERNEL 551 + export KBUILD_AFLAGS_MODULE KBUILD_CFLAGS_MODULE KBUILD_RUSTFLAGS_MODULE KBUILD_LDFLAGS_MODULE 552 + export KBUILD_AFLAGS_KERNEL KBUILD_CFLAGS_KERNEL KBUILD_RUSTFLAGS_KERNEL 616 553 export PAHOLE_FLAGS 617 554 618 555 # Files to ignore in find ... statements ··· 794 729 # 795 730 # Do not use $(call cmd,...) here. That would suppress prompts from syncconfig, 796 731 # so you cannot notice that Kconfig is waiting for the user input. 797 - %/config/auto.conf %/config/auto.conf.cmd %/generated/autoconf.h: $(KCONFIG_CONFIG) 732 + %/config/auto.conf %/config/auto.conf.cmd %/generated/autoconf.h %/generated/rustc_cfg: $(KCONFIG_CONFIG) 798 733 $(Q)$(kecho) " SYNC $@" 799 734 $(Q)$(MAKE) -f $(srctree)/Makefile syncconfig 800 735 else # !may-sync-config ··· 823 758 824 759 ifdef CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE 825 760 KBUILD_CFLAGS += -O2 761 + KBUILD_RUSTFLAGS += -Copt-level=2 826 762 else ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE 827 763 KBUILD_CFLAGS += -Os 764 + KBUILD_RUSTFLAGS += -Copt-level=s 828 765 endif 766 + 767 + # Always set `debug-assertions` and `overflow-checks` because their default 768 + # depends on `opt-level` and `debug-assertions`, respectively. 769 + KBUILD_RUSTFLAGS += -Cdebug-assertions=$(if $(CONFIG_RUST_DEBUG_ASSERTIONS),y,n) 770 + KBUILD_RUSTFLAGS += -Coverflow-checks=$(if $(CONFIG_RUST_OVERFLOW_CHECKS),y,n) 829 771 830 772 # Tell gcc to never replace conditional load with a non-conditional one 831 773 ifdef CONFIG_CC_IS_GCC ··· 864 792 KBUILD_CFLAGS-$(CONFIG_CC_NO_ARRAY_BOUNDS) += -Wno-array-bounds 865 793 KBUILD_CFLAGS += $(KBUILD_CFLAGS-y) $(CONFIG_CC_IMPLICIT_FALLTHROUGH) 866 794 795 + KBUILD_RUSTFLAGS-$(CONFIG_WERROR) += -Dwarnings 796 + KBUILD_RUSTFLAGS += $(KBUILD_RUSTFLAGS-y) 797 + 867 798 ifdef CONFIG_CC_IS_CLANG 868 799 KBUILD_CPPFLAGS += -Qunused-arguments 869 800 # The kernel builds with '-std=gnu11' so use of GNU extensions is acceptable. ··· 887 812 888 813 ifdef CONFIG_FRAME_POINTER 889 814 KBUILD_CFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-calls 815 + KBUILD_RUSTFLAGS += -Cforce-frame-pointers=y 890 816 else 891 817 # Some targets (ARM with Thumb2, for example), can't be built with frame 892 818 # pointers. For those, we don't have FUNCTION_TRACER automatically 893 819 # select FRAME_POINTER. However, FUNCTION_TRACER adds -pg, and this is 894 820 # incompatible with -fomit-frame-pointer with current GCC, so we don't use 895 821 # -fomit-frame-pointer with FUNCTION_TRACER. 822 + # In the Rust target specification, "frame-pointer" is set explicitly 823 + # to "may-omit". 896 824 ifndef CONFIG_FUNCTION_TRACER 897 825 KBUILD_CFLAGS += -fomit-frame-pointer 898 826 endif ··· 960 882 KBUILD_CFLAGS += -fno-inline-functions-called-once 961 883 endif 962 884 885 + # `rustc`'s `-Zfunction-sections` applies to data too (as of 1.59.0). 963 886 ifdef CONFIG_LD_DEAD_CODE_DATA_ELIMINATION 964 887 KBUILD_CFLAGS_KERNEL += -ffunction-sections -fdata-sections 888 + KBUILD_RUSTFLAGS_KERNEL += -Zfunction-sections=y 965 889 LDFLAGS_vmlinux += --gc-sections 966 890 endif 967 891 ··· 1106 1026 # Do not add $(call cc-option,...) below this line. When you build the kernel 1107 1027 # from the clean source tree, the GCC plugins do not exist at this point. 1108 1028 1109 - # Add user supplied CPPFLAGS, AFLAGS and CFLAGS as the last assignments 1029 + # Add user supplied CPPFLAGS, AFLAGS, CFLAGS and RUSTFLAGS as the last assignments 1110 1030 KBUILD_CPPFLAGS += $(KCPPFLAGS) 1111 1031 KBUILD_AFLAGS += $(KAFLAGS) 1112 1032 KBUILD_CFLAGS += $(KCFLAGS) 1033 + KBUILD_RUSTFLAGS += $(KRUSTFLAGS) 1113 1034 1114 1035 KBUILD_LDFLAGS_MODULE += --build-id=sha1 1115 1036 LDFLAGS_vmlinux += --build-id=sha1 ··· 1185 1104 core-y += kernel/ certs/ mm/ fs/ ipc/ security/ crypto/ 1186 1105 core-$(CONFIG_BLOCK) += block/ 1187 1106 core-$(CONFIG_IO_URING) += io_uring/ 1107 + core-$(CONFIG_RUST) += rust/ 1188 1108 1189 1109 vmlinux-dirs := $(patsubst %/,%,$(filter %/, \ 1190 1110 $(core-y) $(core-m) $(drivers-y) $(drivers-m) \ ··· 1288 1206 1289 1207 # All the preparing.. 1290 1208 prepare: prepare0 1209 + ifdef CONFIG_RUST 1210 + $(Q)$(CONFIG_SHELL) $(srctree)/scripts/rust_is_available.sh -v 1211 + $(Q)$(MAKE) $(build)=rust 1212 + endif 1291 1213 1292 1214 PHONY += remove-stale-files 1293 1215 remove-stale-files: ··· 1585 1499 # Directories & files removed with 'make clean' 1586 1500 CLEAN_FILES += include/ksym vmlinux.symvers modules-only.symvers \ 1587 1501 modules.builtin modules.builtin.modinfo modules.nsdeps \ 1588 - compile_commands.json .thinlto-cache 1502 + compile_commands.json .thinlto-cache rust/test rust/doc 1589 1503 1590 1504 # Directories & files removed with 'make mrproper' 1591 1505 MRPROPER_FILES += include/config include/generated \ ··· 1596 1510 certs/signing_key.pem \ 1597 1511 certs/x509.genkey \ 1598 1512 vmlinux-gdb.py \ 1599 - *.spec 1513 + *.spec \ 1514 + rust/target.json rust/libmacros.so 1600 1515 1601 1516 # clean - Delete most, but leave enough to build external modules 1602 1517 # ··· 1622 1535 1623 1536 mrproper: clean $(mrproper-dirs) 1624 1537 $(call cmd,rmfiles) 1538 + @find . $(RCS_FIND_IGNORE) \ 1539 + \( -name '*.rmeta' \) \ 1540 + -type f -print | xargs rm -f 1625 1541 1626 1542 # distclean 1627 1543 # ··· 1712 1622 @echo ' kselftest-merge - Merge all the config dependencies of' 1713 1623 @echo ' kselftest to existing .config.' 1714 1624 @echo '' 1625 + @echo 'Rust targets:' 1626 + @echo ' rustavailable - Checks whether the Rust toolchain is' 1627 + @echo ' available and, if not, explains why.' 1628 + @echo ' rustfmt - Reformat all the Rust code in the kernel' 1629 + @echo ' rustfmtcheck - Checks if all the Rust code in the kernel' 1630 + @echo ' is formatted, printing a diff otherwise.' 1631 + @echo ' rustdoc - Generate Rust documentation' 1632 + @echo ' (requires kernel .config)' 1633 + @echo ' rusttest - Runs the Rust tests' 1634 + @echo ' (requires kernel .config; downloads external repos)' 1635 + @echo ' rust-analyzer - Generate rust-project.json rust-analyzer support file' 1636 + @echo ' (requires kernel .config)' 1637 + @echo ' dir/file.[os] - Build specified target only' 1638 + @echo ' dir/file.rsi - Build macro expanded source, similar to C preprocessing.' 1639 + @echo ' Run with RUSTFMT=n to skip reformatting if needed.' 1640 + @echo ' The output is not intended to be compilable.' 1641 + @echo ' dir/file.ll - Build the LLVM assembly file' 1642 + @echo '' 1715 1643 @$(if $(dtstree), \ 1716 1644 echo 'Devicetree:'; \ 1717 1645 echo '* dtbs - Build device tree blobs for enabled boards'; \ ··· 1801 1693 PHONY += $(DOC_TARGETS) 1802 1694 $(DOC_TARGETS): 1803 1695 $(Q)$(MAKE) $(build)=Documentation $@ 1696 + 1697 + 1698 + # Rust targets 1699 + # --------------------------------------------------------------------------- 1700 + 1701 + # "Is Rust available?" target 1702 + PHONY += rustavailable 1703 + rustavailable: 1704 + $(Q)$(CONFIG_SHELL) $(srctree)/scripts/rust_is_available.sh -v && echo "Rust is available!" 1705 + 1706 + # Documentation target 1707 + # 1708 + # Using the singular to avoid running afoul of `no-dot-config-targets`. 1709 + PHONY += rustdoc 1710 + rustdoc: prepare 1711 + $(Q)$(MAKE) $(build)=rust $@ 1712 + 1713 + # Testing target 1714 + PHONY += rusttest 1715 + rusttest: prepare 1716 + $(Q)$(MAKE) $(build)=rust $@ 1717 + 1718 + # Formatting targets 1719 + PHONY += rustfmt rustfmtcheck 1720 + 1721 + # We skip `rust/alloc` since we want to minimize the diff w.r.t. upstream. 1722 + # 1723 + # We match using absolute paths since `find` does not resolve them 1724 + # when matching, which is a problem when e.g. `srctree` is `..`. 1725 + # We `grep` afterwards in order to remove the directory entry itself. 1726 + rustfmt: 1727 + $(Q)find $(abs_srctree) -type f -name '*.rs' \ 1728 + -o -path $(abs_srctree)/rust/alloc -prune \ 1729 + -o -path $(abs_objtree)/rust/test -prune \ 1730 + | grep -Fv $(abs_srctree)/rust/alloc \ 1731 + | grep -Fv $(abs_objtree)/rust/test \ 1732 + | grep -Fv generated \ 1733 + | xargs $(RUSTFMT) $(rustfmt_flags) 1734 + 1735 + rustfmtcheck: rustfmt_flags = --check 1736 + rustfmtcheck: rustfmt 1737 + 1738 + # IDE support targets 1739 + PHONY += rust-analyzer 1740 + rust-analyzer: 1741 + $(Q)$(MAKE) $(build)=rust $@ 1804 1742 1805 1743 # Misc 1806 1744 # --------------------------------------------------------------------------- ··· 2015 1861 clean: $(clean-dirs) 2016 1862 $(call cmd,rmfiles) 2017 1863 @find $(or $(KBUILD_EXTMOD), .) $(RCS_FIND_IGNORE) \ 2018 - \( -name '*.[aios]' -o -name '*.ko' -o -name '.*.cmd' \ 1864 + \( -name '*.[aios]' -o -name '*.rsi' -o -name '*.ko' -o -name '.*.cmd' \ 2019 1865 -o -name '*.ko.*' \ 2020 1866 -o -name '*.dtb' -o -name '*.dtbo' -o -name '*.dtb.S' -o -name '*.dt.yaml' \ 2021 1867 -o -name '*.dwo' -o -name '*.lst' \
+6
arch/Kconfig
··· 355 355 This symbol should be selected by an architecture if it 356 356 supports an implementation of restartable sequences. 357 357 358 + config HAVE_RUST 359 + bool 360 + help 361 + This symbol should be selected by an architecture if it 362 + supports Rust. 363 + 358 364 config HAVE_FUNCTION_ARG_ACCESS_API 359 365 bool 360 366 help
+5 -1
include/linux/compiler_types.h
··· 4 4 5 5 #ifndef __ASSEMBLY__ 6 6 7 + /* 8 + * Skipped when running bindgen due to a libclang issue; 9 + * see https://github.com/rust-lang/rust-bindgen/issues/2244. 10 + */ 7 11 #if defined(CONFIG_DEBUG_INFO_BTF) && defined(CONFIG_PAHOLE_HAS_BTF_TAG) && \ 8 - __has_attribute(btf_type_tag) 12 + __has_attribute(btf_type_tag) && !defined(__BINDGEN__) 9 13 # define BTF_TYPE_TAG(value) __attribute__((btf_type_tag(#value))) 10 14 #else 11 15 # define BTF_TYPE_TAG(value) /* nothing */
+45 -1
init/Kconfig
··· 60 60 default $(ld-version) if LD_IS_LLD 61 61 default 0 62 62 63 + config RUST_IS_AVAILABLE 64 + def_bool $(success,$(srctree)/scripts/rust_is_available.sh) 65 + help 66 + This shows whether a suitable Rust toolchain is available (found). 67 + 68 + Please see Documentation/rust/quick-start.rst for instructions on how 69 + to satify the build requirements of Rust support. 70 + 71 + In particular, the Makefile target 'rustavailable' is useful to check 72 + why the Rust toolchain is not being detected. 73 + 63 74 config CC_CAN_LINK 64 75 bool 65 76 default $(success,$(srctree)/scripts/cc-can-link.sh $(CC) $(CLANG_FLAGS) $(USERCFLAGS) $(USERLDFLAGS) $(m64-flag)) if 64BIT ··· 158 147 default COMPILE_TEST 159 148 help 160 149 A kernel build should not cause any compiler warnings, and this 161 - enables the '-Werror' flag to enforce that rule by default. 150 + enables the '-Werror' (for C) and '-Dwarnings' (for Rust) flags 151 + to enforce that rule by default. 162 152 163 153 However, if you have a new (or very old) compiler with odd and 164 154 unusual warnings, or you have some architecture with problems, ··· 1910 1898 help 1911 1899 Say Y here to enable the extended profiling support mechanisms used 1912 1900 by profilers. 1901 + 1902 + config RUST 1903 + bool "Rust support" 1904 + depends on HAVE_RUST 1905 + depends on RUST_IS_AVAILABLE 1906 + depends on !MODVERSIONS 1907 + depends on !GCC_PLUGINS 1908 + depends on !RANDSTRUCT 1909 + depends on !DEBUG_INFO_BTF 1910 + select CONSTRUCTORS 1911 + help 1912 + Enables Rust support in the kernel. 1913 + 1914 + This allows other Rust-related options, like drivers written in Rust, 1915 + to be selected. 1916 + 1917 + It is also required to be able to load external kernel modules 1918 + written in Rust. 1919 + 1920 + See Documentation/rust/ for more information. 1921 + 1922 + If unsure, say N. 1923 + 1924 + config RUSTC_VERSION_TEXT 1925 + string 1926 + depends on RUST 1927 + default $(shell,command -v $(RUSTC) >/dev/null 2>&1 && $(RUSTC) --version || echo n) 1928 + 1929 + config BINDGEN_VERSION_TEXT 1930 + string 1931 + depends on RUST 1932 + default $(shell,command -v $(BINDGEN) >/dev/null 2>&1 && $(BINDGEN) --version || echo n) 1913 1933 1914 1934 # 1915 1935 # Place an empty function call at each tracepoint site. Can be
+1
kernel/configs/rust.config
··· 1 + CONFIG_RUST=y
+34
lib/Kconfig.debug
··· 2710 2710 2711 2711 endmenu # "Kernel Testing and Coverage" 2712 2712 2713 + menu "Rust hacking" 2714 + 2715 + config RUST_DEBUG_ASSERTIONS 2716 + bool "Debug assertions" 2717 + depends on RUST 2718 + help 2719 + Enables rustc's `-Cdebug-assertions` codegen option. 2720 + 2721 + This flag lets you turn `cfg(debug_assertions)` conditional 2722 + compilation on or off. This can be used to enable extra debugging 2723 + code in development but not in production. For example, it controls 2724 + the behavior of the standard library's `debug_assert!` macro. 2725 + 2726 + Note that this will apply to all Rust code, including `core`. 2727 + 2728 + If unsure, say N. 2729 + 2730 + config RUST_OVERFLOW_CHECKS 2731 + bool "Overflow checks" 2732 + default y 2733 + depends on RUST 2734 + help 2735 + Enables rustc's `-Coverflow-checks` codegen option. 2736 + 2737 + This flag allows you to control the behavior of runtime integer 2738 + overflow. When overflow-checks are enabled, a Rust panic will occur 2739 + on overflow. 2740 + 2741 + Note that this will apply to all Rust code, including `core`. 2742 + 2743 + If unsure, say Y. 2744 + 2745 + endmenu # "Rust" 2746 + 2713 2747 source "Documentation/Kconfig" 2714 2748 2715 2749 endmenu # Kernel hacking
+8
rust/.gitignore
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + 3 + target.json 4 + bindings_generated.rs 5 + bindings_helpers_generated.rs 6 + exports_*_generated.h 7 + doc/ 8 + test/
+381
rust/Makefile
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + 3 + always-$(CONFIG_RUST) += target.json 4 + no-clean-files += target.json 5 + 6 + obj-$(CONFIG_RUST) += core.o compiler_builtins.o 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. 11 + obj-$(CONFIG_RUST) += helpers.o 12 + CFLAGS_REMOVE_helpers.o = -Wmissing-prototypes -Wmissing-declarations 13 + 14 + always-$(CONFIG_RUST) += libmacros.so 15 + no-clean-files += libmacros.so 16 + 17 + always-$(CONFIG_RUST) += bindings/bindings_generated.rs bindings/bindings_helpers_generated.rs 18 + obj-$(CONFIG_RUST) += alloc.o bindings.o kernel.o 19 + always-$(CONFIG_RUST) += exports_alloc_generated.h exports_bindings_generated.h \ 20 + exports_kernel_generated.h 21 + 22 + obj-$(CONFIG_RUST) += exports.o 23 + 24 + # Avoids running `$(RUSTC)` for the sysroot when it may not be available. 25 + ifdef CONFIG_RUST 26 + 27 + # `$(rust_flags)` is passed in case the user added `--sysroot`. 28 + rustc_sysroot := $(shell $(RUSTC) $(rust_flags) --print sysroot) 29 + rustc_host_target := $(shell $(RUSTC) --version --verbose | grep -F 'host: ' | cut -d' ' -f2) 30 + RUST_LIB_SRC ?= $(rustc_sysroot)/lib/rustlib/src/rust/library 31 + 32 + ifeq ($(quiet),silent_) 33 + cargo_quiet=-q 34 + rust_test_quiet=-q 35 + rustdoc_test_quiet=--test-args -q 36 + else ifeq ($(quiet),quiet_) 37 + rust_test_quiet=-q 38 + rustdoc_test_quiet=--test-args -q 39 + else 40 + cargo_quiet=--verbose 41 + endif 42 + 43 + core-cfgs = \ 44 + --cfg no_fp_fmt_parse 45 + 46 + alloc-cfgs = \ 47 + --cfg no_fmt \ 48 + --cfg no_global_oom_handling \ 49 + --cfg no_macros \ 50 + --cfg no_rc \ 51 + --cfg no_str \ 52 + --cfg no_string \ 53 + --cfg no_sync \ 54 + --cfg no_thin 55 + 56 + quiet_cmd_rustdoc = RUSTDOC $(if $(rustdoc_host),H, ) $< 57 + cmd_rustdoc = \ 58 + OBJTREE=$(abspath $(objtree)) \ 59 + $(RUSTDOC) $(if $(rustdoc_host),$(rust_common_flags),$(rust_flags)) \ 60 + $(rustc_target_flags) -L$(objtree)/$(obj) \ 61 + --output $(objtree)/$(obj)/doc \ 62 + --crate-name $(subst rustdoc-,,$@) \ 63 + @$(objtree)/include/generated/rustc_cfg $< 64 + 65 + # The `html_logo_url` and `html_favicon_url` forms of the `doc` attribute 66 + # can be used to specify a custom logo. However: 67 + # - The given value is used as-is, thus it cannot be relative or a local file 68 + # (unlike the non-custom case) since the generated docs have subfolders. 69 + # - It requires adding it to every crate. 70 + # - It requires changing `core` which comes from the sysroot. 71 + # 72 + # Using `-Zcrate-attr` would solve the last two points, but not the first. 73 + # The https://github.com/rust-lang/rfcs/pull/3226 RFC suggests two new 74 + # command-like flags to solve the issue. Meanwhile, we use the non-custom case 75 + # and then retouch the generated files. 76 + rustdoc: rustdoc-core rustdoc-macros rustdoc-compiler_builtins \ 77 + rustdoc-alloc rustdoc-kernel 78 + $(Q)cp $(srctree)/Documentation/images/logo.svg $(objtree)/$(obj)/doc 79 + $(Q)cp $(srctree)/Documentation/images/COPYING-logo $(objtree)/$(obj)/doc 80 + $(Q)find $(objtree)/$(obj)/doc -name '*.html' -type f -print0 | xargs -0 sed -Ei \ 81 + -e 's:rust-logo\.svg:logo.svg:g' \ 82 + -e 's:rust-logo\.png:logo.svg:g' \ 83 + -e 's:favicon\.svg:logo.svg:g' \ 84 + -e 's:<link rel="alternate icon" type="image/png" href="[./]*favicon-(16x16|32x32)\.png">::g' 85 + $(Q)echo '.logo-container > img { object-fit: contain; }' \ 86 + >> $(objtree)/$(obj)/doc/rustdoc.css 87 + 88 + rustdoc-macros: private rustdoc_host = yes 89 + rustdoc-macros: private rustc_target_flags = --crate-type proc-macro \ 90 + --extern proc_macro 91 + rustdoc-macros: $(src)/macros/lib.rs FORCE 92 + $(call if_changed,rustdoc) 93 + 94 + rustdoc-core: private rustc_target_flags = $(core-cfgs) 95 + rustdoc-core: $(RUST_LIB_SRC)/core/src/lib.rs FORCE 96 + $(call if_changed,rustdoc) 97 + 98 + rustdoc-compiler_builtins: $(src)/compiler_builtins.rs rustdoc-core FORCE 99 + $(call if_changed,rustdoc) 100 + 101 + # We need to allow `rustdoc::broken_intra_doc_links` because some 102 + # `no_global_oom_handling` functions refer to non-`no_global_oom_handling` 103 + # functions. Ideally `rustdoc` would have a way to distinguish broken links 104 + # due to things that are "configured out" vs. entirely non-existing ones. 105 + rustdoc-alloc: private rustc_target_flags = $(alloc-cfgs) \ 106 + -Arustdoc::broken_intra_doc_links 107 + rustdoc-alloc: $(src)/alloc/lib.rs rustdoc-core rustdoc-compiler_builtins FORCE 108 + $(call if_changed,rustdoc) 109 + 110 + rustdoc-kernel: private rustc_target_flags = --extern alloc \ 111 + --extern macros=$(objtree)/$(obj)/libmacros.so \ 112 + --extern bindings 113 + rustdoc-kernel: $(src)/kernel/lib.rs rustdoc-core rustdoc-macros \ 114 + rustdoc-compiler_builtins rustdoc-alloc $(obj)/libmacros.so \ 115 + $(obj)/bindings.o FORCE 116 + $(call if_changed,rustdoc) 117 + 118 + quiet_cmd_rustc_test_library = RUSTC TL $< 119 + cmd_rustc_test_library = \ 120 + OBJTREE=$(abspath $(objtree)) \ 121 + $(RUSTC) $(rust_common_flags) \ 122 + @$(objtree)/include/generated/rustc_cfg $(rustc_target_flags) \ 123 + --crate-type $(if $(rustc_test_library_proc),proc-macro,rlib) \ 124 + --out-dir $(objtree)/$(obj)/test --cfg testlib \ 125 + --sysroot $(objtree)/$(obj)/test/sysroot \ 126 + -L$(objtree)/$(obj)/test \ 127 + --crate-name $(subst rusttest-,,$(subst rusttestlib-,,$@)) $< 128 + 129 + rusttestlib-macros: private rustc_target_flags = --extern proc_macro 130 + rusttestlib-macros: private rustc_test_library_proc = yes 131 + rusttestlib-macros: $(src)/macros/lib.rs rusttest-prepare FORCE 132 + $(call if_changed,rustc_test_library) 133 + 134 + rusttestlib-bindings: $(src)/bindings/lib.rs rusttest-prepare FORCE 135 + $(call if_changed,rustc_test_library) 136 + 137 + quiet_cmd_rustdoc_test = RUSTDOC T $< 138 + cmd_rustdoc_test = \ 139 + OBJTREE=$(abspath $(objtree)) \ 140 + $(RUSTDOC) --test $(rust_common_flags) \ 141 + @$(objtree)/include/generated/rustc_cfg \ 142 + $(rustc_target_flags) $(rustdoc_test_target_flags) \ 143 + --sysroot $(objtree)/$(obj)/test/sysroot $(rustdoc_test_quiet) \ 144 + -L$(objtree)/$(obj)/test --output $(objtree)/$(obj)/doc \ 145 + --crate-name $(subst rusttest-,,$@) $< 146 + 147 + # We cannot use `-Zpanic-abort-tests` because some tests are dynamic, 148 + # so for the moment we skip `-Cpanic=abort`. 149 + quiet_cmd_rustc_test = RUSTC T $< 150 + cmd_rustc_test = \ 151 + OBJTREE=$(abspath $(objtree)) \ 152 + $(RUSTC) --test $(rust_common_flags) \ 153 + @$(objtree)/include/generated/rustc_cfg \ 154 + $(rustc_target_flags) --out-dir $(objtree)/$(obj)/test \ 155 + --sysroot $(objtree)/$(obj)/test/sysroot \ 156 + -L$(objtree)/$(obj)/test \ 157 + --crate-name $(subst rusttest-,,$@) $<; \ 158 + $(objtree)/$(obj)/test/$(subst rusttest-,,$@) $(rust_test_quiet) \ 159 + $(rustc_test_run_flags) 160 + 161 + rusttest: rusttest-macros rusttest-kernel 162 + 163 + # This prepares a custom sysroot with our custom `alloc` instead of 164 + # the standard one. 165 + # 166 + # This requires several hacks: 167 + # - Unlike `core` and `alloc`, `std` depends on more than a dozen crates, 168 + # including third-party crates that need to be downloaded, plus custom 169 + # `build.rs` steps. Thus hardcoding things here is not maintainable. 170 + # - `cargo` knows how to build the standard library, but it is an unstable 171 + # feature so far (`-Zbuild-std`). 172 + # - `cargo` only considers the use case of building the standard library 173 + # to use it in a given package. Thus we need to create a dummy package 174 + # and pick the generated libraries from there. 175 + # - Since we only keep a subset of upstream `alloc` in-tree, we need 176 + # to recreate it on the fly by putting our sources on top. 177 + # - The usual ways of modifying the dependency graph in `cargo` do not seem 178 + # to apply for the `-Zbuild-std` steps, thus we have to mislead it 179 + # by modifying the sources in the sysroot. 180 + # - To avoid messing with the user's Rust installation, we create a clone 181 + # of the sysroot. However, `cargo` ignores `RUSTFLAGS` in the `-Zbuild-std` 182 + # steps, thus we use a wrapper binary passed via `RUSTC` to pass the flag. 183 + # 184 + # In the future, we hope to avoid the whole ordeal by either: 185 + # - Making the `test` crate not depend on `std` (either improving upstream 186 + # or having our own custom crate). 187 + # - Making the tests run in kernel space (requires the previous point). 188 + # - Making `std` and friends be more like a "normal" crate, so that 189 + # `-Zbuild-std` and related hacks are not needed. 190 + quiet_cmd_rustsysroot = RUSTSYSROOT 191 + cmd_rustsysroot = \ 192 + rm -rf $(objtree)/$(obj)/test; \ 193 + mkdir -p $(objtree)/$(obj)/test; \ 194 + cp -a $(rustc_sysroot) $(objtree)/$(obj)/test/sysroot; \ 195 + cp -r $(srctree)/$(src)/alloc/* \ 196 + $(objtree)/$(obj)/test/sysroot/lib/rustlib/src/rust/library/alloc/src; \ 197 + echo '\#!/bin/sh' > $(objtree)/$(obj)/test/rustc_sysroot; \ 198 + echo "$(RUSTC) --sysroot=$(abspath $(objtree)/$(obj)/test/sysroot) \"\$$@\"" \ 199 + >> $(objtree)/$(obj)/test/rustc_sysroot; \ 200 + chmod u+x $(objtree)/$(obj)/test/rustc_sysroot; \ 201 + $(CARGO) -q new $(objtree)/$(obj)/test/dummy; \ 202 + RUSTC=$(objtree)/$(obj)/test/rustc_sysroot $(CARGO) $(cargo_quiet) \ 203 + test -Zbuild-std --target $(rustc_host_target) \ 204 + --manifest-path $(objtree)/$(obj)/test/dummy/Cargo.toml; \ 205 + rm $(objtree)/$(obj)/test/sysroot/lib/rustlib/$(rustc_host_target)/lib/*; \ 206 + cp $(objtree)/$(obj)/test/dummy/target/$(rustc_host_target)/debug/deps/* \ 207 + $(objtree)/$(obj)/test/sysroot/lib/rustlib/$(rustc_host_target)/lib 208 + 209 + rusttest-prepare: FORCE 210 + $(call if_changed,rustsysroot) 211 + 212 + rusttest-macros: private rustc_target_flags = --extern proc_macro 213 + rusttest-macros: private rustdoc_test_target_flags = --crate-type proc-macro 214 + rusttest-macros: $(src)/macros/lib.rs rusttest-prepare FORCE 215 + $(call if_changed,rustc_test) 216 + $(call if_changed,rustdoc_test) 217 + 218 + rusttest-kernel: private rustc_target_flags = --extern alloc \ 219 + --extern macros --extern bindings 220 + rusttest-kernel: $(src)/kernel/lib.rs rusttest-prepare \ 221 + rusttestlib-macros rusttestlib-bindings FORCE 222 + $(call if_changed,rustc_test) 223 + $(call if_changed,rustc_test_library) 224 + 225 + filechk_rust_target = $(objtree)/scripts/generate_rust_target < $< 226 + 227 + $(obj)/target.json: $(objtree)/include/config/auto.conf FORCE 228 + $(call filechk,rust_target) 229 + 230 + ifdef CONFIG_CC_IS_CLANG 231 + bindgen_c_flags = $(c_flags) 232 + else 233 + # bindgen relies on libclang to parse C. Ideally, bindgen would support a GCC 234 + # plugin backend and/or the Clang driver would be perfectly compatible with GCC. 235 + # 236 + # For the moment, here we are tweaking the flags on the fly. This is a hack, 237 + # and some kernel configurations may not work (e.g. `GCC_PLUGIN_RANDSTRUCT` 238 + # if we end up using one of those structs). 239 + bindgen_skip_c_flags := -mno-fp-ret-in-387 -mpreferred-stack-boundary=% \ 240 + -mskip-rax-setup -mgeneral-regs-only -msign-return-address=% \ 241 + -mindirect-branch=thunk-extern -mindirect-branch-register \ 242 + -mfunction-return=thunk-extern -mrecord-mcount -mabi=lp64 \ 243 + -mindirect-branch-cs-prefix -mstack-protector-guard% -mtraceback=no \ 244 + -mno-pointers-to-nested-functions -mno-string \ 245 + -mno-strict-align -mstrict-align \ 246 + -fconserve-stack -falign-jumps=% -falign-loops=% \ 247 + -femit-struct-debug-baseonly -fno-ipa-cp-clone -fno-ipa-sra \ 248 + -fno-partial-inlining -fplugin-arg-arm_ssp_per_task_plugin-% \ 249 + -fno-reorder-blocks -fno-allow-store-data-races -fasan-shadow-offset=% \ 250 + -fzero-call-used-regs=% -fno-stack-clash-protection \ 251 + -fno-inline-functions-called-once \ 252 + --param=% --param asan-% 253 + 254 + # Derived from `scripts/Makefile.clang`. 255 + BINDGEN_TARGET_x86 := x86_64-linux-gnu 256 + BINDGEN_TARGET := $(BINDGEN_TARGET_$(SRCARCH)) 257 + 258 + # All warnings are inhibited since GCC builds are very experimental, 259 + # many GCC warnings are not supported by Clang, they may only appear in 260 + # some configurations, with new GCC versions, etc. 261 + bindgen_extra_c_flags = -w --target=$(BINDGEN_TARGET) 262 + 263 + bindgen_c_flags = $(filter-out $(bindgen_skip_c_flags), $(c_flags)) \ 264 + $(bindgen_extra_c_flags) 265 + endif 266 + 267 + ifdef CONFIG_LTO 268 + bindgen_c_flags_lto = $(filter-out $(CC_FLAGS_LTO), $(bindgen_c_flags)) 269 + else 270 + bindgen_c_flags_lto = $(bindgen_c_flags) 271 + endif 272 + 273 + bindgen_c_flags_final = $(bindgen_c_flags_lto) -D__BINDGEN__ 274 + 275 + quiet_cmd_bindgen = BINDGEN $@ 276 + cmd_bindgen = \ 277 + $(BINDGEN) $< $(bindgen_target_flags) \ 278 + --use-core --with-derive-default --ctypes-prefix core::ffi --no-layout-tests \ 279 + --no-debug '.*' \ 280 + --size_t-is-usize -o $@ -- $(bindgen_c_flags_final) -DMODULE \ 281 + $(bindgen_target_cflags) $(bindgen_target_extra) 282 + 283 + $(obj)/bindings/bindings_generated.rs: private bindgen_target_flags = \ 284 + $(shell grep -v '^\#\|^$$' $(srctree)/$(src)/bindgen_parameters) 285 + $(obj)/bindings/bindings_generated.rs: $(src)/bindings/bindings_helper.h \ 286 + $(src)/bindgen_parameters FORCE 287 + $(call if_changed_dep,bindgen) 288 + 289 + # See `CFLAGS_REMOVE_helpers.o` above. In addition, Clang on C does not warn 290 + # with `-Wmissing-declarations` (unlike GCC), so it is not strictly needed here 291 + # given it is `libclang`; but for consistency, future Clang changes and/or 292 + # a potential future GCC backend for `bindgen`, we disable it too. 293 + $(obj)/bindings/bindings_helpers_generated.rs: private bindgen_target_flags = \ 294 + --blacklist-type '.*' --whitelist-var '' \ 295 + --whitelist-function 'rust_helper_.*' 296 + $(obj)/bindings/bindings_helpers_generated.rs: private bindgen_target_cflags = \ 297 + -I$(objtree)/$(obj) -Wno-missing-prototypes -Wno-missing-declarations 298 + $(obj)/bindings/bindings_helpers_generated.rs: private bindgen_target_extra = ; \ 299 + sed -Ei 's/pub fn rust_helper_([a-zA-Z0-9_]*)/#[link_name="rust_helper_\1"]\n pub fn \1/g' $@ 300 + $(obj)/bindings/bindings_helpers_generated.rs: $(src)/helpers.c FORCE 301 + $(call if_changed_dep,bindgen) 302 + 303 + quiet_cmd_exports = EXPORTS $@ 304 + cmd_exports = \ 305 + $(NM) -p --defined-only $< \ 306 + | grep -E ' (T|R|D) ' | cut -d ' ' -f 3 \ 307 + | xargs -Isymbol \ 308 + echo 'EXPORT_SYMBOL_RUST_GPL(symbol);' > $@ 309 + 310 + $(obj)/exports_core_generated.h: $(obj)/core.o FORCE 311 + $(call if_changed,exports) 312 + 313 + $(obj)/exports_alloc_generated.h: $(obj)/alloc.o FORCE 314 + $(call if_changed,exports) 315 + 316 + $(obj)/exports_bindings_generated.h: $(obj)/bindings.o FORCE 317 + $(call if_changed,exports) 318 + 319 + $(obj)/exports_kernel_generated.h: $(obj)/kernel.o FORCE 320 + $(call if_changed,exports) 321 + 322 + quiet_cmd_rustc_procmacro = $(RUSTC_OR_CLIPPY_QUIET) P $@ 323 + cmd_rustc_procmacro = \ 324 + $(RUSTC_OR_CLIPPY) $(rust_common_flags) \ 325 + --emit=dep-info,link --extern proc_macro \ 326 + --crate-type proc-macro --out-dir $(objtree)/$(obj) \ 327 + --crate-name $(patsubst lib%.so,%,$(notdir $@)) $<; \ 328 + mv $(objtree)/$(obj)/$(patsubst lib%.so,%,$(notdir $@)).d $(depfile); \ 329 + sed -i '/^\#/d' $(depfile) 330 + 331 + # Procedural macros can only be used with the `rustc` that compiled it. 332 + # Therefore, to get `libmacros.so` automatically recompiled when the compiler 333 + # version changes, we add `core.o` as a dependency (even if it is not needed). 334 + $(obj)/libmacros.so: $(src)/macros/lib.rs $(obj)/core.o FORCE 335 + $(call if_changed_dep,rustc_procmacro) 336 + 337 + quiet_cmd_rustc_library = $(if $(skip_clippy),RUSTC,$(RUSTC_OR_CLIPPY_QUIET)) L $@ 338 + cmd_rustc_library = \ 339 + OBJTREE=$(abspath $(objtree)) \ 340 + $(if $(skip_clippy),$(RUSTC),$(RUSTC_OR_CLIPPY)) \ 341 + $(filter-out $(skip_flags),$(rust_flags) $(rustc_target_flags)) \ 342 + --emit=dep-info,obj,metadata --crate-type rlib \ 343 + --out-dir $(objtree)/$(obj) -L$(objtree)/$(obj) \ 344 + --crate-name $(patsubst %.o,%,$(notdir $@)) $<; \ 345 + mv $(objtree)/$(obj)/$(patsubst %.o,%,$(notdir $@)).d $(depfile); \ 346 + sed -i '/^\#/d' $(depfile) \ 347 + $(if $(rustc_objcopy),;$(OBJCOPY) $(rustc_objcopy) $@) 348 + 349 + rust-analyzer: 350 + $(Q)$(srctree)/scripts/generate_rust_analyzer.py $(srctree) $(objtree) \ 351 + $(RUST_LIB_SRC) > $(objtree)/rust-project.json 352 + 353 + $(obj)/core.o: private skip_clippy = 1 354 + $(obj)/core.o: private skip_flags = -Dunreachable_pub 355 + $(obj)/core.o: private rustc_target_flags = $(core-cfgs) 356 + $(obj)/core.o: $(RUST_LIB_SRC)/core/src/lib.rs $(obj)/target.json FORCE 357 + $(call if_changed_dep,rustc_library) 358 + 359 + $(obj)/compiler_builtins.o: private rustc_objcopy = -w -W '__*' 360 + $(obj)/compiler_builtins.o: $(src)/compiler_builtins.rs $(obj)/core.o FORCE 361 + $(call if_changed_dep,rustc_library) 362 + 363 + $(obj)/alloc.o: private skip_clippy = 1 364 + $(obj)/alloc.o: private skip_flags = -Dunreachable_pub 365 + $(obj)/alloc.o: private rustc_target_flags = $(alloc-cfgs) 366 + $(obj)/alloc.o: $(src)/alloc/lib.rs $(obj)/compiler_builtins.o FORCE 367 + $(call if_changed_dep,rustc_library) 368 + 369 + $(obj)/bindings.o: $(src)/bindings/lib.rs \ 370 + $(obj)/compiler_builtins.o \ 371 + $(obj)/bindings/bindings_generated.rs \ 372 + $(obj)/bindings/bindings_helpers_generated.rs FORCE 373 + $(call if_changed_dep,rustc_library) 374 + 375 + $(obj)/kernel.o: private rustc_target_flags = --extern alloc \ 376 + --extern macros --extern bindings 377 + $(obj)/kernel.o: $(src)/kernel/lib.rs $(obj)/alloc.o \ 378 + $(obj)/libmacros.so $(obj)/bindings.o FORCE 379 + $(call if_changed_dep,rustc_library) 380 + 381 + endif # CONFIG_RUST
+21
rust/bindgen_parameters
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + 3 + --opaque-type xregs_state 4 + --opaque-type desc_struct 5 + --opaque-type arch_lbr_state 6 + --opaque-type local_apic 7 + 8 + # Packed type cannot transitively contain a `#[repr(align)]` type. 9 + --opaque-type x86_msi_data 10 + --opaque-type x86_msi_addr_lo 11 + 12 + # `try` is a reserved keyword since Rust 2018; solved in `bindgen` v0.59.2, 13 + # commit 2aed6b021680 ("context: Escape the try keyword properly"). 14 + --opaque-type kunit_try_catch 15 + 16 + # If SMP is disabled, `arch_spinlock_t` is defined as a ZST which triggers a Rust 17 + # warning. We don't need to peek into it anyway. 18 + --opaque-type spinlock 19 + 20 + # `seccomp`'s comment gets understood as a doctest 21 + --no-doc-comments
+3 -3
scripts/Kconfig.include
··· 36 36 as-instr = $(success,printf "%b\n" "$(1)" | $(CC) $(CLANG_FLAGS) -c -x assembler -o /dev/null -) 37 37 38 38 # check if $(CC) and $(LD) exist 39 - $(error-if,$(failure,command -v $(CC)),compiler '$(CC)' not found) 39 + $(error-if,$(failure,command -v $(CC)),C compiler '$(CC)' not found) 40 40 $(error-if,$(failure,command -v $(LD)),linker '$(LD)' not found) 41 41 42 - # Get the compiler name, version, and error out if it is not supported. 42 + # Get the C compiler name, version, and error out if it is not supported. 43 43 cc-info := $(shell,$(srctree)/scripts/cc-version.sh $(CC)) 44 - $(error-if,$(success,test -z "$(cc-info)"),Sorry$(comma) this compiler is not supported.) 44 + $(error-if,$(success,test -z "$(cc-info)"),Sorry$(comma) this C compiler is not supported.) 45 45 cc-name := $(shell,set -- $(cc-info) && echo $1) 46 46 cc-version := $(shell,set -- $(cc-info) && echo $2) 47 47
+3
scripts/Makefile
··· 10 10 hostprogs-always-$(CONFIG_ASN1) += asn1_compiler 11 11 hostprogs-always-$(CONFIG_MODULE_SIG_FORMAT) += sign-file 12 12 hostprogs-always-$(CONFIG_SYSTEM_EXTRA_CERTIFICATE) += insert-sys-cert 13 + hostprogs-always-$(CONFIG_RUST) += generate_rust_target 14 + 15 + generate_rust_target-rust := y 13 16 14 17 HOSTCFLAGS_sorttable.o = -I$(srctree)/tools/include 15 18 HOSTLDLIBS_sorttable = -lpthread
+60
scripts/Makefile.build
··· 26 26 EXTRA_LDFLAGS := 27 27 asflags-y := 28 28 ccflags-y := 29 + rustflags-y := 29 30 cppflags-y := 30 31 ldflags-y := 31 32 ··· 271 270 272 271 $(obj)/%.lst: $(src)/%.c FORCE 273 272 $(call if_changed_dep,cc_lst_c) 273 + 274 + # Compile Rust sources (.rs) 275 + # --------------------------------------------------------------------------- 276 + 277 + rust_allowed_features := core_ffi_c 278 + 279 + rust_common_cmd = \ 280 + RUST_MODFILE=$(modfile) $(RUSTC_OR_CLIPPY) $(rust_flags) \ 281 + -Zallow-features=$(rust_allowed_features) \ 282 + -Zcrate-attr=no_std \ 283 + -Zcrate-attr='feature($(rust_allowed_features))' \ 284 + --extern alloc --extern kernel \ 285 + --crate-type rlib --out-dir $(obj) -L $(objtree)/rust/ \ 286 + --crate-name $(basename $(notdir $@)) 287 + 288 + rust_handle_depfile = \ 289 + mv $(obj)/$(basename $(notdir $@)).d $(depfile); \ 290 + sed -i '/^\#/d' $(depfile) 291 + 292 + # `--emit=obj`, `--emit=asm` and `--emit=llvm-ir` imply a single codegen unit 293 + # will be used. We explicitly request `-Ccodegen-units=1` in any case, and 294 + # the compiler shows a warning if it is not 1. However, if we ever stop 295 + # requesting it explicitly and we start using some other `--emit` that does not 296 + # imply it (and for which codegen is performed), then we would be out of sync, 297 + # i.e. the outputs we would get for the different single targets (e.g. `.ll`) 298 + # would not match each other. 299 + 300 + quiet_cmd_rustc_o_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@ 301 + cmd_rustc_o_rs = \ 302 + $(rust_common_cmd) --emit=dep-info,obj $<; \ 303 + $(rust_handle_depfile) 304 + 305 + $(obj)/%.o: $(src)/%.rs FORCE 306 + $(call if_changed_dep,rustc_o_rs) 307 + 308 + quiet_cmd_rustc_rsi_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@ 309 + cmd_rustc_rsi_rs = \ 310 + $(rust_common_cmd) --emit=dep-info -Zunpretty=expanded $< >$@; \ 311 + command -v $(RUSTFMT) >/dev/null && $(RUSTFMT) $@; \ 312 + $(rust_handle_depfile) 313 + 314 + $(obj)/%.rsi: $(src)/%.rs FORCE 315 + $(call if_changed_dep,rustc_rsi_rs) 316 + 317 + quiet_cmd_rustc_s_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@ 318 + cmd_rustc_s_rs = \ 319 + $(rust_common_cmd) --emit=dep-info,asm $<; \ 320 + $(rust_handle_depfile) 321 + 322 + $(obj)/%.s: $(src)/%.rs FORCE 323 + $(call if_changed_dep,rustc_s_rs) 324 + 325 + quiet_cmd_rustc_ll_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@ 326 + cmd_rustc_ll_rs = \ 327 + $(rust_common_cmd) --emit=dep-info,llvm-ir $<; \ 328 + $(rust_handle_depfile) 329 + 330 + $(obj)/%.ll: $(src)/%.rs FORCE 331 + $(call if_changed_dep,rustc_ll_rs) 274 332 275 333 # Compile assembler sources (.S) 276 334 # ---------------------------------------------------------------------------
+8
scripts/Makefile.debug
··· 1 1 DEBUG_CFLAGS := 2 + DEBUG_RUSTFLAGS := 3 + 2 4 debug-flags-y := -g 3 5 4 6 ifdef CONFIG_DEBUG_INFO_SPLIT ··· 19 17 20 18 ifdef CONFIG_DEBUG_INFO_REDUCED 21 19 DEBUG_CFLAGS += -fno-var-tracking 20 + DEBUG_RUSTFLAGS += -Cdebuginfo=1 22 21 ifdef CONFIG_CC_IS_GCC 23 22 DEBUG_CFLAGS += -femit-struct-debug-baseonly 24 23 endif 24 + else 25 + DEBUG_RUSTFLAGS += -Cdebuginfo=2 25 26 endif 26 27 27 28 ifdef CONFIG_DEBUG_INFO_COMPRESSED ··· 35 30 36 31 KBUILD_CFLAGS += $(DEBUG_CFLAGS) 37 32 export DEBUG_CFLAGS 33 + 34 + KBUILD_RUSTFLAGS += $(DEBUG_RUSTFLAGS) 35 + export DEBUG_RUSTFLAGS
+31 -3
scripts/Makefile.host
··· 22 22 # to preprocess a data file. 23 23 # 24 24 # Both C and C++ are supported, but preferred language is C for such utilities. 25 + # Rust is also supported, but it may only be used in scenarios where a Rust 26 + # toolchain is required to be available (e.g. when `CONFIG_RUST` is enabled). 25 27 # 26 28 # Sample syntax (see Documentation/kbuild/makefiles.rst for reference) 27 29 # hostprogs := bin2hex ··· 39 37 # qconf-objs := menu.o 40 38 # Will compile qconf as a C++ program, and menu as a C program. 41 39 # They are linked as C++ code to the executable qconf 40 + # 41 + # hostprogs := target 42 + # target-rust := y 43 + # Will compile `target` as a Rust program, using `target.rs` as the crate root. 44 + # The crate may consist of several source files. 42 45 43 46 # C code 44 47 # Executables compiled from a single .c file 45 48 host-csingle := $(foreach m,$(hostprogs), \ 46 - $(if $($(m)-objs)$($(m)-cxxobjs),,$(m))) 49 + $(if $($(m)-objs)$($(m)-cxxobjs)$($(m)-rust),,$(m))) 47 50 48 51 # C executables linked based on several .o files 49 52 host-cmulti := $(foreach m,$(hostprogs),\ 50 - $(if $($(m)-cxxobjs),,$(if $($(m)-objs),$(m)))) 53 + $(if $($(m)-cxxobjs)$($(m)-rust),,$(if $($(m)-objs),$(m)))) 51 54 52 55 # Object (.o) files compiled from .c files 53 56 host-cobjs := $(sort $(foreach m,$(hostprogs),$($(m)-objs))) ··· 65 58 # C++ Object (.o) files compiled from .cc files 66 59 host-cxxobjs := $(sort $(foreach m,$(host-cxxmulti),$($(m)-cxxobjs))) 67 60 61 + # Rust code 62 + # Executables compiled from a single Rust crate (which may consist of 63 + # one or more .rs files) 64 + host-rust := $(foreach m,$(hostprogs),$(if $($(m)-rust),$(m))) 65 + 68 66 host-csingle := $(addprefix $(obj)/,$(host-csingle)) 69 67 host-cmulti := $(addprefix $(obj)/,$(host-cmulti)) 70 68 host-cobjs := $(addprefix $(obj)/,$(host-cobjs)) 71 69 host-cxxmulti := $(addprefix $(obj)/,$(host-cxxmulti)) 72 70 host-cxxobjs := $(addprefix $(obj)/,$(host-cxxobjs)) 71 + host-rust := $(addprefix $(obj)/,$(host-rust)) 73 72 74 73 ##### 75 74 # Handle options to gcc. Support building with separate output directory ··· 84 71 $(HOSTCFLAGS_$(target-stem).o) 85 72 _hostcxx_flags = $(KBUILD_HOSTCXXFLAGS) $(HOST_EXTRACXXFLAGS) \ 86 73 $(HOSTCXXFLAGS_$(target-stem).o) 74 + _hostrust_flags = $(KBUILD_HOSTRUSTFLAGS) $(HOST_EXTRARUSTFLAGS) \ 75 + $(HOSTRUSTFLAGS_$(target-stem)) 87 76 88 77 # $(objtree)/$(obj) for including generated headers from checkin source files 89 78 ifeq ($(KBUILD_EXTMOD),) ··· 97 82 98 83 hostc_flags = -Wp,-MMD,$(depfile) $(_hostc_flags) 99 84 hostcxx_flags = -Wp,-MMD,$(depfile) $(_hostcxx_flags) 85 + hostrust_flags = $(_hostrust_flags) 100 86 101 87 ##### 102 88 # Compile programs on the host ··· 144 128 $(host-cxxobjs): $(obj)/%.o: $(src)/%.cc FORCE 145 129 $(call if_changed_dep,host-cxxobjs) 146 130 131 + # Create executable from a single Rust crate (which may consist of 132 + # one or more `.rs` files) 133 + # host-rust -> Executable 134 + quiet_cmd_host-rust = HOSTRUSTC $@ 135 + cmd_host-rust = \ 136 + $(HOSTRUSTC) $(hostrust_flags) --emit=dep-info,link \ 137 + --out-dir=$(obj)/ $<; \ 138 + mv $(obj)/$(target-stem).d $(depfile); \ 139 + sed -i '/^\#/d' $(depfile) 140 + $(host-rust): $(obj)/%: $(src)/%.rs FORCE 141 + $(call if_changed_dep,host-rust) 142 + 147 143 targets += $(host-csingle) $(host-cmulti) $(host-cobjs) \ 148 - $(host-cxxmulti) $(host-cxxobjs) 144 + $(host-cxxmulti) $(host-cxxobjs) $(host-rust)
+12
scripts/Makefile.lib
··· 8 8 # flags that take effect in current and sub directories 9 9 KBUILD_AFLAGS += $(subdir-asflags-y) 10 10 KBUILD_CFLAGS += $(subdir-ccflags-y) 11 + KBUILD_RUSTFLAGS += $(subdir-rustflags-y) 11 12 12 13 # Figure out what we need to build from the various variables 13 14 # =========================================================================== ··· 129 128 $(filter-out $(ccflags-remove-y), \ 130 129 $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(ccflags-y)) \ 131 130 $(CFLAGS_$(target-stem).o)) 131 + _rust_flags = $(filter-out $(RUSTFLAGS_REMOVE_$(target-stem).o), \ 132 + $(filter-out $(rustflags-remove-y), \ 133 + $(KBUILD_RUSTFLAGS) $(rustflags-y)) \ 134 + $(RUSTFLAGS_$(target-stem).o)) 132 135 _a_flags = $(filter-out $(AFLAGS_REMOVE_$(target-stem).o), \ 133 136 $(filter-out $(asflags-remove-y), \ 134 137 $(KBUILD_CPPFLAGS) $(KBUILD_AFLAGS) $(asflags-y)) \ ··· 207 202 $(KBUILD_CFLAGS_MODULE) $(CFLAGS_MODULE), \ 208 203 $(KBUILD_CFLAGS_KERNEL) $(CFLAGS_KERNEL) $(modfile_flags)) 209 204 205 + modkern_rustflags = \ 206 + $(if $(part-of-module), \ 207 + $(KBUILD_RUSTFLAGS_MODULE) $(RUSTFLAGS_MODULE), \ 208 + $(KBUILD_RUSTFLAGS_KERNEL) $(RUSTFLAGS_KERNEL)) 209 + 210 210 modkern_aflags = $(if $(part-of-module), \ 211 211 $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE), \ 212 212 $(KBUILD_AFLAGS_KERNEL) $(AFLAGS_KERNEL)) ··· 220 210 -include $(srctree)/include/linux/compiler_types.h \ 221 211 $(_c_flags) $(modkern_cflags) \ 222 212 $(basename_flags) $(modname_flags) 213 + 214 + rust_flags = $(_rust_flags) $(modkern_rustflags) @$(objtree)/include/generated/rustc_cfg 223 215 224 216 a_flags = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ 225 217 $(_a_flags) $(modkern_aflags)
+5 -3
scripts/Makefile.modfinal
··· 39 39 40 40 quiet_cmd_btf_ko = BTF [M] $@ 41 41 cmd_btf_ko = \ 42 - if [ -f vmlinux ]; then \ 42 + if [ ! -f vmlinux ]; then \ 43 + printf "Skipping BTF generation for %s due to unavailability of vmlinux\n" $@ 1>&2; \ 44 + elif [ -n "$(CONFIG_RUST)" ] && $(srctree)/scripts/is_rust_module.sh $@; then \ 45 + printf "Skipping BTF generation for %s because it's a Rust module\n" $@ 1>&2; \ 46 + else \ 43 47 LLVM_OBJCOPY="$(OBJCOPY)" $(PAHOLE) -J $(PAHOLE_FLAGS) --btf_base vmlinux $@; \ 44 48 $(RESOLVE_BTFIDS) -b vmlinux $@; \ 45 - else \ 46 - printf "Skipping BTF generation for %s due to unavailability of vmlinux\n" $@ 1>&2; \ 47 49 fi; 48 50 49 51 # Same as newer-prereqs, but allows to exclude specified extra dependencies
+6 -6
scripts/cc-version.sh
··· 1 1 #!/bin/sh 2 2 # SPDX-License-Identifier: GPL-2.0 3 3 # 4 - # Print the compiler name and its version in a 5 or 6-digit form. 4 + # Print the C compiler name and its version in a 5 or 6-digit form. 5 5 # Also, perform the minimum version check. 6 6 7 7 set -e 8 8 9 - # Print the compiler name and some version components. 10 - get_compiler_info() 9 + # Print the C compiler name and some version components. 10 + get_c_compiler_info() 11 11 { 12 12 cat <<- EOF | "$@" -E -P -x c - 2>/dev/null 13 13 #if defined(__clang__) ··· 32 32 33 33 # $@ instead of $1 because multiple words might be given, e.g. CC="ccache gcc". 34 34 orig_args="$@" 35 - set -- $(get_compiler_info "$@") 35 + set -- $(get_c_compiler_info "$@") 36 36 37 37 name=$1 38 38 ··· 52 52 min_version=$($min_tool_version icc) 53 53 ;; 54 54 *) 55 - echo "$orig_args: unknown compiler" >&2 55 + echo "$orig_args: unknown C compiler" >&2 56 56 exit 1 57 57 ;; 58 58 esac ··· 62 62 63 63 if [ "$cversion" -lt "$min_cversion" ]; then 64 64 echo >&2 "***" 65 - echo >&2 "*** Compiler is too old." 65 + echo >&2 "*** C compiler is too old." 66 66 echo >&2 "*** Your $name version: $version" 67 67 echo >&2 "*** Minimum $name version: $min_version" 68 68 echo >&2 "***"
+75
scripts/kconfig/confdata.c
··· 216 216 return name ? name : "include/generated/autoconf.h"; 217 217 } 218 218 219 + static const char *conf_get_rustccfg_name(void) 220 + { 221 + char *name = getenv("KCONFIG_RUSTCCFG"); 222 + 223 + return name ? name : "include/generated/rustc_cfg"; 224 + } 225 + 219 226 static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p) 220 227 { 221 228 char *p2; ··· 612 605 613 606 static void conf_write_heading(FILE *fp, const struct comment_style *cs) 614 607 { 608 + if (!cs) 609 + return; 610 + 615 611 fprintf(fp, "%s\n", cs->prefix); 616 612 617 613 fprintf(fp, "%s Automatically generated file; DO NOT EDIT.\n", ··· 753 743 val_prefix, val); 754 744 755 745 free(escaped); 746 + } 747 + 748 + static void print_symbol_for_rustccfg(FILE *fp, struct symbol *sym) 749 + { 750 + const char *val; 751 + const char *val_prefix = ""; 752 + char *val_prefixed = NULL; 753 + size_t val_prefixed_len; 754 + char *escaped = NULL; 755 + 756 + if (sym->type == S_UNKNOWN) 757 + return; 758 + 759 + val = sym_get_string_value(sym); 760 + 761 + switch (sym->type) { 762 + case S_BOOLEAN: 763 + case S_TRISTATE: 764 + /* 765 + * We do not care about disabled ones, i.e. no need for 766 + * what otherwise are "comments" in other printers. 767 + */ 768 + if (*val == 'n') 769 + return; 770 + 771 + /* 772 + * To have similar functionality to the C macro `IS_ENABLED()` 773 + * we provide an empty `--cfg CONFIG_X` here in both `y` 774 + * and `m` cases. 775 + * 776 + * Then, the common `fprintf()` below will also give us 777 + * a `--cfg CONFIG_X="y"` or `--cfg CONFIG_X="m"`, which can 778 + * be used as the equivalent of `IS_BUILTIN()`/`IS_MODULE()`. 779 + */ 780 + fprintf(fp, "--cfg=%s%s\n", CONFIG_, sym->name); 781 + break; 782 + case S_HEX: 783 + if (val[0] != '0' || (val[1] != 'x' && val[1] != 'X')) 784 + val_prefix = "0x"; 785 + break; 786 + default: 787 + break; 788 + } 789 + 790 + if (strlen(val_prefix) > 0) { 791 + val_prefixed_len = strlen(val) + strlen(val_prefix) + 1; 792 + val_prefixed = xmalloc(val_prefixed_len); 793 + snprintf(val_prefixed, val_prefixed_len, "%s%s", val_prefix, val); 794 + val = val_prefixed; 795 + } 796 + 797 + /* All values get escaped: the `--cfg` option only takes strings */ 798 + escaped = escape_string_value(val); 799 + val = escaped; 800 + 801 + fprintf(fp, "--cfg=%s%s=%s\n", CONFIG_, sym->name, val); 802 + 803 + free(escaped); 804 + free(val_prefixed); 756 805 } 757 806 758 807 /* ··· 1198 1129 ret = __conf_write_autoconf(conf_get_autoheader_name(), 1199 1130 print_symbol_for_c, 1200 1131 &comment_style_c); 1132 + if (ret) 1133 + return ret; 1134 + 1135 + ret = __conf_write_autoconf(conf_get_rustccfg_name(), 1136 + print_symbol_for_rustccfg, 1137 + NULL); 1201 1138 if (ret) 1202 1139 return ret; 1203 1140