From 526c539452cec6e7e65776d5807e6c66dd65d636 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Fri, 17 May 2024 19:06:15 +0200 Subject: docs: rust: introduce the new kernel.org LLVM+Rust toolchains These combined LLVM+Rust toolchains are now available, thanks to Nathan Chancellor (ClangBuiltLinux). Thus introduce them in the Rust Quick Start guide. Signed-off-by: Nathan Chancellor Link: https://lore.kernel.org/r/20240517170615.377786-1-ojeda@kernel.org Co-developed-by: Miguel Ojeda Signed-off-by: Miguel Ojeda --- Documentation/rust/quick-start.rst | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'Documentation/rust') diff --git a/Documentation/rust/quick-start.rst b/Documentation/rust/quick-start.rst index cc3f11e0d441..6fe69a601134 100644 --- a/Documentation/rust/quick-start.rst +++ b/Documentation/rust/quick-start.rst @@ -16,6 +16,13 @@ under names like ``rustc``, ``rust-src``, ``rust-bindgen``, etc. However, at the time of writing, they are likely not to be recent enough unless the distribution tracks the latest releases. +Prebuilt stable versions of LLVM+Rust are provided on `kernel.org +`_. These are the same slim and fast +LLVM toolchains from :ref:`Getting LLVM ` with versions of Rust +added to them that Rust for Linux supports, depending on the Linux version. Two +sets are provided: the "latest LLVM" and "matching LLVM" (please see the link +for more information). + To easily check whether the requirements are met, the following target can be used:: -- cgit v1.2.3 From 9ffc80c819739ab60c42223c46b7351cec6a0e97 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Tue, 28 May 2024 18:35:02 +0200 Subject: kbuild: rust: remove now-unneeded `rusttest` custom sysroot handling Since we dropped our custom `alloc` in commit 9d0441bab775 ("rust: alloc: remove our fork of the `alloc` crate"), there is no need anymore to keep the custom sysroot hack. Thus delete it, which makes the target way simpler and faster too. This also means we are not using Cargo for anything at the moment, and that no download is required anymore, so update the main `Makefile` and the documentation accordingly. Link: https://lore.kernel.org/r/20240528163502.411600-1-ojeda@kernel.org Signed-off-by: Miguel Ojeda --- Documentation/rust/quick-start.rst | 14 -------- Documentation/rust/testing.rst | 5 ++- Makefile | 3 +- rust/Makefile | 70 +++++--------------------------------- 4 files changed, 11 insertions(+), 81 deletions(-) (limited to 'Documentation/rust') diff --git a/Documentation/rust/quick-start.rst b/Documentation/rust/quick-start.rst index 6fe69a601134..ac2f16288458 100644 --- a/Documentation/rust/quick-start.rst +++ b/Documentation/rust/quick-start.rst @@ -171,20 +171,6 @@ can be installed manually:: The standalone installers also come with ``clippy``. -cargo -***** - -``cargo`` is the Rust native build system. It is currently required to run -the tests since it is used to build a custom standard library that contains -the facilities provided by the custom ``alloc`` in the kernel. The tests can -be run using the ``rusttest`` Make target. - -If ``rustup`` is being used, all the profiles already install the tool, -thus nothing needs to be done. - -The standalone installers also come with ``cargo``. - - rustdoc ******* diff --git a/Documentation/rust/testing.rst b/Documentation/rust/testing.rst index acfd0c2be48d..568b71b415a4 100644 --- a/Documentation/rust/testing.rst +++ b/Documentation/rust/testing.rst @@ -131,9 +131,8 @@ Additionally, there are the ``#[test]`` tests. These can be run using the make LLVM=1 rusttest -This requires the kernel ``.config`` and downloads external repositories. It -runs the ``#[test]`` tests on the host (currently) and thus is fairly limited in -what these tests can test. +This requires the kernel ``.config``. It runs the ``#[test]`` tests on the host +(currently) and thus is fairly limited in what these tests can test. The Kselftests -------------- diff --git a/Makefile b/Makefile index b25b5b44af10..d4134a9f32b6 100644 --- a/Makefile +++ b/Makefile @@ -507,7 +507,6 @@ RUSTDOC = rustdoc RUSTFMT = rustfmt CLIPPY_DRIVER = clippy-driver BINDGEN = bindgen -CARGO = cargo PAHOLE = pahole RESOLVE_BTFIDS = $(objtree)/tools/bpf/resolve_btfids/resolve_btfids LEX = flex @@ -601,7 +600,7 @@ endif export RUSTC_BOOTSTRAP := 1 export ARCH SRCARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE LD CC HOSTPKG_CONFIG -export RUSTC RUSTDOC RUSTFMT RUSTC_OR_CLIPPY_QUIET RUSTC_OR_CLIPPY BINDGEN CARGO +export RUSTC RUSTDOC RUSTFMT RUSTC_OR_CLIPPY_QUIET RUSTC_OR_CLIPPY BINDGEN export HOSTRUSTC KBUILD_HOSTRUSTFLAGS export CPP AR NM STRIP OBJCOPY OBJDUMP READELF PAHOLE RESOLVE_BTFIDS LEX YACC AWK INSTALLKERNEL export PERL PYTHON3 CHECK CHECKFLAGS MAKE UTS_MACHINE HOSTCXX diff --git a/rust/Makefile b/rust/Makefile index f70d5e244fee..385378311322 100644 --- a/rust/Makefile +++ b/rust/Makefile @@ -44,17 +44,10 @@ rustc_sysroot := $(shell MAKEFLAGS= $(RUSTC) $(rust_flags) --print sysroot) rustc_host_target := $(shell $(RUSTC) --version --verbose | grep -F 'host: ' | cut -d' ' -f2) RUST_LIB_SRC ?= $(rustc_sysroot)/lib/rustlib/src/rust/library -ifeq ($(quiet),silent_) -cargo_quiet=-q +ifneq ($(quiet),) rust_test_quiet=-q rustdoc_test_quiet=--test-args -q rustdoc_test_kernel_quiet=>/dev/null -else ifeq ($(quiet),quiet_) -rust_test_quiet=-q -rustdoc_test_quiet=--test-args -q -rustdoc_test_kernel_quiet=>/dev/null -else -cargo_quiet=--verbose endif core-cfgs = \ @@ -135,22 +128,21 @@ quiet_cmd_rustc_test_library = RUSTC TL $< @$(objtree)/include/generated/rustc_cfg $(rustc_target_flags) \ --crate-type $(if $(rustc_test_library_proc),proc-macro,rlib) \ --out-dir $(objtree)/$(obj)/test --cfg testlib \ - --sysroot $(objtree)/$(obj)/test/sysroot \ -L$(objtree)/$(obj)/test \ --crate-name $(subst rusttest-,,$(subst rusttestlib-,,$@)) $< -rusttestlib-build_error: $(src)/build_error.rs rusttest-prepare FORCE +rusttestlib-build_error: $(src)/build_error.rs FORCE +$(call if_changed,rustc_test_library) rusttestlib-macros: private rustc_target_flags = --extern proc_macro rusttestlib-macros: private rustc_test_library_proc = yes -rusttestlib-macros: $(src)/macros/lib.rs rusttest-prepare FORCE +rusttestlib-macros: $(src)/macros/lib.rs FORCE +$(call if_changed,rustc_test_library) -rusttestlib-bindings: $(src)/bindings/lib.rs rusttest-prepare FORCE +rusttestlib-bindings: $(src)/bindings/lib.rs FORCE +$(call if_changed,rustc_test_library) -rusttestlib-uapi: $(src)/uapi/lib.rs rusttest-prepare FORCE +rusttestlib-uapi: $(src)/uapi/lib.rs FORCE +$(call if_changed,rustc_test_library) quiet_cmd_rustdoc_test = RUSTDOC T $< @@ -159,7 +151,7 @@ quiet_cmd_rustdoc_test = RUSTDOC T $< $(RUSTDOC) --test $(rust_common_flags) \ @$(objtree)/include/generated/rustc_cfg \ $(rustc_target_flags) $(rustdoc_test_target_flags) \ - --sysroot $(objtree)/$(obj)/test/sysroot $(rustdoc_test_quiet) \ + $(rustdoc_test_quiet) \ -L$(objtree)/$(obj)/test --output $(rustdoc_output) \ --crate-name $(subst rusttest-,,$@) $< @@ -192,7 +184,6 @@ quiet_cmd_rustc_test = RUSTC T $< $(RUSTC) --test $(rust_common_flags) \ @$(objtree)/include/generated/rustc_cfg \ $(rustc_target_flags) --out-dir $(objtree)/$(obj)/test \ - --sysroot $(objtree)/$(obj)/test/sysroot \ -L$(objtree)/$(obj)/test \ --crate-name $(subst rusttest-,,$@) $<; \ $(objtree)/$(obj)/test/$(subst rusttest-,,$@) $(rust_test_quiet) \ @@ -200,60 +191,15 @@ quiet_cmd_rustc_test = RUSTC T $< rusttest: rusttest-macros rusttest-kernel -# This prepares a custom sysroot with our custom `alloc` instead of -# the standard one. -# -# This requires several hacks: -# - Unlike `core` and `alloc`, `std` depends on more than a dozen crates, -# including third-party crates that need to be downloaded, plus custom -# `build.rs` steps. Thus hardcoding things here is not maintainable. -# - `cargo` knows how to build the standard library, but it is an unstable -# feature so far (`-Zbuild-std`). -# - `cargo` only considers the use case of building the standard library -# to use it in a given package. Thus we need to create a dummy package -# and pick the generated libraries from there. -# - The usual ways of modifying the dependency graph in `cargo` do not seem -# to apply for the `-Zbuild-std` steps, thus we have to mislead it -# by modifying the sources in the sysroot. -# - To avoid messing with the user's Rust installation, we create a clone -# of the sysroot. However, `cargo` ignores `RUSTFLAGS` in the `-Zbuild-std` -# steps, thus we use a wrapper binary passed via `RUSTC` to pass the flag. -# -# In the future, we hope to avoid the whole ordeal by either: -# - Making the `test` crate not depend on `std` (either improving upstream -# or having our own custom crate). -# - Making the tests run in kernel space (requires the previous point). -# - Making `std` and friends be more like a "normal" crate, so that -# `-Zbuild-std` and related hacks are not needed. -quiet_cmd_rustsysroot = RUSTSYSROOT - cmd_rustsysroot = \ - rm -rf $(objtree)/$(obj)/test; \ - mkdir -p $(objtree)/$(obj)/test; \ - cp -a $(rustc_sysroot) $(objtree)/$(obj)/test/sysroot; \ - echo '\#!/bin/sh' > $(objtree)/$(obj)/test/rustc_sysroot; \ - echo "$(RUSTC) --sysroot=$(abspath $(objtree)/$(obj)/test/sysroot) \"\$$@\"" \ - >> $(objtree)/$(obj)/test/rustc_sysroot; \ - chmod u+x $(objtree)/$(obj)/test/rustc_sysroot; \ - $(CARGO) -q new $(objtree)/$(obj)/test/dummy; \ - RUSTC=$(objtree)/$(obj)/test/rustc_sysroot $(CARGO) $(cargo_quiet) \ - test -Zbuild-std --target $(rustc_host_target) \ - --manifest-path $(objtree)/$(obj)/test/dummy/Cargo.toml; \ - rm $(objtree)/$(obj)/test/sysroot/lib/rustlib/$(rustc_host_target)/lib/*; \ - cp $(objtree)/$(obj)/test/dummy/target/$(rustc_host_target)/debug/deps/* \ - $(objtree)/$(obj)/test/sysroot/lib/rustlib/$(rustc_host_target)/lib - -rusttest-prepare: FORCE - +$(call if_changed,rustsysroot) - rusttest-macros: private rustc_target_flags = --extern proc_macro rusttest-macros: private rustdoc_test_target_flags = --crate-type proc-macro -rusttest-macros: $(src)/macros/lib.rs rusttest-prepare FORCE +rusttest-macros: $(src)/macros/lib.rs FORCE +$(call if_changed,rustc_test) +$(call if_changed,rustdoc_test) rusttest-kernel: private rustc_target_flags = --extern alloc \ --extern build_error --extern macros --extern bindings --extern uapi -rusttest-kernel: $(src)/kernel/lib.rs rusttest-prepare \ +rusttest-kernel: $(src)/kernel/lib.rs \ rusttestlib-build_error rusttestlib-macros rusttestlib-bindings \ rusttestlib-uapi FORCE +$(call if_changed,rustc_test) -- cgit v1.2.3 From b63c455d38be5f62a0665f3080c67334db5b4c41 Mon Sep 17 00:00:00 2001 From: Dirk Behme Date: Mon, 10 Jun 2024 14:23:32 +0200 Subject: docs: rust: no_std is used Using the #![no_std] attribute in the Rust kernel support is different to the default Rust usage. Mention this in the Documentation. Signed-off-by: Dirk Behme Reviewed-by: Trevor Gross Link: https://lore.kernel.org/r/20240610122332.3858571-1-dirk.behme@de.bosch.com [ Avoided breaking links in two lines. - Miguel ] Signed-off-by: Miguel Ojeda --- Documentation/rust/general-information.rst | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'Documentation/rust') diff --git a/Documentation/rust/general-information.rst b/Documentation/rust/general-information.rst index 4bb6ac12d482..e3f388ef4ee4 100644 --- a/Documentation/rust/general-information.rst +++ b/Documentation/rust/general-information.rst @@ -7,6 +7,14 @@ This document contains useful information to know when working with the Rust support in the kernel. +``no_std`` +---------- + +The Rust support in the kernel can link only `core `_, +but not `std `_. Crates for use in the +kernel must opt into this behavior using the ``#![no_std]`` attribute. + + Code documentation ------------------ -- cgit v1.2.3 From 63b27f4a0074bc6ef987a44ee9ad8bf960b568c2 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Tue, 9 Jul 2024 18:06:01 +0200 Subject: rust: start supporting several compiler versions It is time to start supporting several Rust compiler versions and thus establish a minimum Rust version. We may still want to upgrade the minimum sometimes in the beginning since there may be important features coming into the language that improve how we write code (e.g. field projections), which may or may not make sense to support conditionally. We will start with a window of two stable releases, and widen it over time. Thus this patch does not move the current minimum (1.78.0), but instead adds support for the recently released 1.79.0. This should already be enough for kernel developers in distributions that provide recent Rust compiler versions routinely, such as Arch Linux, Debian Unstable (outside the freeze period), Fedora Linux, Gentoo Linux (especially the testing channel), Nix (unstable) and openSUSE Tumbleweed. See the documentation patch about it later in this series. In addition, Rust for Linux is now being built-tested in Rust's pre-merge CI [1]. That is, every change that is attempting to land into the Rust compiler is tested against the kernel, and it is merged only if it passes -- thanks to the Rust project for that! Thus, with the pre-merge CI in place, both projects hope to avoid unintentional changes to Rust that break the kernel. This means that, in general, apart from intentional changes on their side (that we will need to workaround conditionally on our side), the upcoming Rust compiler versions should generally work. For instance, currently, the beta (1.80.0) and nightly (1.81.0) branches work as well. Of course, the Rust for Linux CI job in the Rust toolchain may still need to be temporarily disabled for different reasons, but the intention is to help bring Rust for Linux into stable Rust. Link: https://github.com/rust-lang/rust/pull/125209 [1] Reviewed-by: Finn Behrens Tested-by: Benno Lossin Tested-by: Andreas Hindborg Link: https://lore.kernel.org/r/20240709160615.998336-7-ojeda@kernel.org Signed-off-by: Miguel Ojeda --- Documentation/process/changes.rst | 4 +--- Documentation/rust/quick-start.rst | 15 +++++++-------- scripts/rust_is_available.sh | 8 -------- scripts/rust_is_available_test.py | 5 ----- 4 files changed, 8 insertions(+), 24 deletions(-) (limited to 'Documentation/rust') diff --git a/Documentation/process/changes.rst b/Documentation/process/changes.rst index 5685d7bfe4d0..0d0b7120792b 100644 --- a/Documentation/process/changes.rst +++ b/Documentation/process/changes.rst @@ -88,9 +88,7 @@ docs on :ref:`Building Linux with Clang/LLVM `. Rust (optional) --------------- -A particular version of the Rust toolchain is required. Newer versions may or -may not work because the kernel depends on some unstable Rust features, for -the moment. +A recent version of the Rust compiler is required. Each Rust toolchain comes with several "components", some of which are required (like ``rustc``) and some that are optional. The ``rust-src`` component (which diff --git a/Documentation/rust/quick-start.rst b/Documentation/rust/quick-start.rst index ac2f16288458..89bbfde8c96c 100644 --- a/Documentation/rust/quick-start.rst +++ b/Documentation/rust/quick-start.rst @@ -36,16 +36,15 @@ if that is the case. rustc ***** -A particular version of the Rust compiler is required. Newer versions may or -may not work because, for the moment, the kernel depends on some unstable -Rust features. +A recent version of the Rust compiler is required. If ``rustup`` is being used, enter the kernel build directory (or use -``--path=`` argument to the ``set`` sub-command) and run:: +``--path=`` argument to the ``set`` sub-command) and run, +for instance:: - rustup override set $(scripts/min-tool-version.sh rustc) + rustup override set stable -This will configure your working directory to use the correct version of +This will configure your working directory to use the given version of ``rustc`` without affecting your default toolchain. Note that the override applies to the current working directory (and its @@ -72,9 +71,9 @@ version later on requires re-adding the component. Otherwise, if a standalone installer is used, the Rust source tree may be downloaded into the toolchain's installation folder:: - curl -L "https://static.rust-lang.org/dist/rust-src-$(scripts/min-tool-version.sh rustc).tar.gz" | + curl -L "https://static.rust-lang.org/dist/rust-src-$(rustc --version | cut -d' ' -f2).tar.gz" | tar -xzf - -C "$(rustc --print sysroot)/lib" \ - "rust-src-$(scripts/min-tool-version.sh rustc)/rust-src/lib/" \ + "rust-src-$(rustc --version | cut -d' ' -f2)/rust-src/lib/" \ --strip-components=3 In this case, upgrading the Rust compiler version later on requires manually diff --git a/scripts/rust_is_available.sh b/scripts/rust_is_available.sh index 117018946b57..67cb900124cc 100755 --- a/scripts/rust_is_available.sh +++ b/scripts/rust_is_available.sh @@ -117,14 +117,6 @@ if [ "$rust_compiler_cversion" -lt "$rust_compiler_min_cversion" ]; then echo >&2 "***" exit 1 fi -if [ "$rust_compiler_cversion" -gt "$rust_compiler_min_cversion" ]; then - echo >&2 "***" - echo >&2 "*** Rust compiler '$RUSTC' is too new. This may or may not work." - echo >&2 "*** Your version: $rust_compiler_version" - echo >&2 "*** Expected version: $rust_compiler_min_version" - echo >&2 "***" - warning=1 -fi # Check that the Rust bindings generator is suitable. # diff --git a/scripts/rust_is_available_test.py b/scripts/rust_is_available_test.py index 57613fe5ed75..a255f79aafc2 100755 --- a/scripts/rust_is_available_test.py +++ b/scripts/rust_is_available_test.py @@ -193,11 +193,6 @@ else: result = self.run_script(self.Expected.FAILURE, { "RUSTC": rustc }) self.assertIn(f"Rust compiler '{rustc}' is too old.", result.stderr) - def test_rustc_new_version(self): - rustc = self.generate_rustc("rustc 1.999.0 (a8314ef7d 2099-06-27)") - result = self.run_script(self.Expected.SUCCESS_WITH_WARNINGS, { "RUSTC": rustc }) - self.assertIn(f"Rust compiler '{rustc}' is too new. This may or may not work.", result.stderr) - def test_bindgen_nonexecutable(self): result = self.run_script(self.Expected.FAILURE, { "BINDGEN": self.nonexecutable }) self.assertIn(f"Running '{self.nonexecutable}' to check the Rust bindings generator version failed with", result.stderr) -- cgit v1.2.3 From d49082faf6a001019693a837dea7b958048c731c Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Tue, 9 Jul 2024 18:06:02 +0200 Subject: rust: avoid assuming a particular `bindgen` build `bindgen`'s logic to find `libclang` (via `clang-sys`) may change over time, and depends on how it was built (e.g. Linux distributions may decide to build it differently, and we are going to provide documentation on installing it via distributions later in this series). Therefore, clarify that `bindgen` may be built in several ways and simplify the documentation by only mentioning the most prominent environment variable (`LIBCLANG_PATH`) as an example on how to tweak the search of the library at runtime (i.e. when `bindgen` is built as our documentation explains). This also avoids duplicating the documentation, like `bindgen` itself does (i.e. it refers to `clang-sys`). Similarly, replace the test we had for this (which used the real program) with a mocked one, to avoid depending on the particular build as well. Tested-by: Benno Lossin Tested-by: Andreas Hindborg Link: https://lore.kernel.org/r/20240709160615.998336-8-ojeda@kernel.org Signed-off-by: Miguel Ojeda --- Documentation/rust/quick-start.rst | 23 +++++++++-------------- scripts/rust_is_available_test.py | 25 +++++++++++++++---------- 2 files changed, 24 insertions(+), 24 deletions(-) (limited to 'Documentation/rust') diff --git a/Documentation/rust/quick-start.rst b/Documentation/rust/quick-start.rst index 89bbfde8c96c..5ea8c8914942 100644 --- a/Documentation/rust/quick-start.rst +++ b/Documentation/rust/quick-start.rst @@ -113,20 +113,15 @@ Install it via (note that this will download and build the tool from source):: cargo install --locked --version $(scripts/min-tool-version.sh bindgen) bindgen-cli -``bindgen`` needs to find a suitable ``libclang`` in order to work. If it is -not found (or a different ``libclang`` than the one found should be used), -the process can be tweaked using the environment variables understood by -``clang-sys`` (the Rust bindings crate that ``bindgen`` uses to access -``libclang``): - -* ``LLVM_CONFIG_PATH`` can be pointed to an ``llvm-config`` executable. - -* Or ``LIBCLANG_PATH`` can be pointed to a ``libclang`` shared library - or to the directory containing it. - -* Or ``CLANG_PATH`` can be pointed to a ``clang`` executable. - -For details, please see ``clang-sys``'s documentation at: +``bindgen`` uses the ``clang-sys`` crate to find a suitable ``libclang`` (which +may be linked statically, dynamically or loaded at runtime). By default, the +``cargo`` command above will produce a ``bindgen`` binary that will load +``libclang`` at runtime. If it is not found (or a different ``libclang`` than +the one found should be used), the process can be tweaked, e.g. by using the +``LIBCLANG_PATH`` environment variable. For details, please see ``clang-sys``'s +documentation at: + + https://github.com/KyleMayes/clang-sys#linking https://github.com/KyleMayes/clang-sys#environment-variables diff --git a/scripts/rust_is_available_test.py b/scripts/rust_is_available_test.py index a255f79aafc2..0481aab862ec 100755 --- a/scripts/rust_is_available_test.py +++ b/scripts/rust_is_available_test.py @@ -55,10 +55,15 @@ else: @classmethod def generate_bindgen(cls, version_stdout, libclang_stderr): + if libclang_stderr is None: + libclang_case = f"raise SystemExit({cls.bindgen_default_bindgen_libclang_failure_exit_code})" + else: + libclang_case = f"print({repr(libclang_stderr)}, file=sys.stderr)" + return cls.generate_executable(f"""#!/usr/bin/env python3 import sys if "rust_is_available_bindgen_libclang.h" in " ".join(sys.argv): - print({repr(libclang_stderr)}, file=sys.stderr) + {libclang_case} else: print({repr(version_stdout)}) """) @@ -67,6 +72,10 @@ else: def generate_bindgen_version(cls, stdout): return cls.generate_bindgen(stdout, cls.bindgen_default_bindgen_libclang_stderr) + @classmethod + def generate_bindgen_libclang_failure(cls): + return cls.generate_bindgen(cls.bindgen_default_bindgen_version_stdout, None) + @classmethod def generate_bindgen_libclang(cls, stderr): return cls.generate_bindgen(cls.bindgen_default_bindgen_version_stdout, stderr) @@ -89,6 +98,7 @@ else: cls.rust_default_sysroot = subprocess.check_output(("rustc", "--print", "sysroot")).decode().strip() cls.bindgen_default_bindgen_version_stdout = f"bindgen {cls.bindgen_default_version}" + cls.bindgen_default_bindgen_libclang_failure_exit_code = 42 cls.bindgen_default_bindgen_libclang_stderr = f"scripts/rust_is_available_bindgen_libclang.h:2:9: warning: clang version {cls.llvm_default_version} [-W#pragma-messages], err: false" cls.default_rustc = cls.generate_rustc(f"rustc {cls.rustc_default_version}") @@ -227,15 +237,10 @@ else: self.assertIn(f"Rust bindings generator '{bindgen}' is too new. This may or may not work.", result.stderr) def test_bindgen_libclang_failure(self): - for env in ( - { "LLVM_CONFIG_PATH": self.missing }, - { "LIBCLANG_PATH": self.missing }, - { "CLANG_PATH": self.missing }, - ): - with self.subTest(env=env): - result = self.run_script(self.Expected.FAILURE, env | { "PATH": os.environ["PATH"], "BINDGEN": "bindgen" }) - self.assertIn("Running 'bindgen' to check the libclang version (used by the Rust", result.stderr) - self.assertIn("bindings generator) failed with code ", result.stderr) + bindgen = self.generate_bindgen_libclang_failure() + result = self.run_script(self.Expected.FAILURE, { "BINDGEN": bindgen }) + self.assertIn(f"Running '{bindgen}' to check the libclang version (used by the Rust", result.stderr) + self.assertIn(f"bindings generator) failed with code {self.bindgen_default_bindgen_libclang_failure_exit_code}. This may be caused by", result.stderr) def test_bindgen_libclang_unexpected_version(self): bindgen = self.generate_bindgen_libclang("scripts/rust_is_available_bindgen_libclang.h:2:9: warning: clang version unexpected [-W#pragma-messages], err: false") -- cgit v1.2.3 From c844fa64a2d46982fe75e834f4a46c46d2b3b2e5 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Tue, 9 Jul 2024 18:06:04 +0200 Subject: rust: start supporting several `bindgen` versions With both the workaround for `bindgen` 0.69.0 and the warning about 0.66.0 and 0.66.1 in place, start supporting several `bindgen` versions, like it was done for the Rust compiler in a previous patch. All other versions, including the latest 0.69.4, build without errors. The `bindgen` project, like Rust, has also agreed to have the kernel in their CI [1] -- thanks! This should help both projects: `bindgen` will be able to detect early issues like those mentioned above, and the kernel will be very likely build with new releases (at least for the basic configuration being tested). Link: https://github.com/rust-lang/rust-bindgen/pull/2851 [1] Tested-by: Benno Lossin Tested-by: Andreas Hindborg Link: https://lore.kernel.org/r/20240709160615.998336-10-ojeda@kernel.org Signed-off-by: Miguel Ojeda --- Documentation/rust/quick-start.rst | 7 ++++--- scripts/rust_is_available.sh | 8 -------- scripts/rust_is_available_test.py | 5 ----- 3 files changed, 4 insertions(+), 16 deletions(-) (limited to 'Documentation/rust') diff --git a/Documentation/rust/quick-start.rst b/Documentation/rust/quick-start.rst index 5ea8c8914942..66cefbab8f9a 100644 --- a/Documentation/rust/quick-start.rst +++ b/Documentation/rust/quick-start.rst @@ -107,11 +107,12 @@ bindgen ******* The bindings to the C side of the kernel are generated at build time using -the ``bindgen`` tool. A particular version is required. +the ``bindgen`` tool. -Install it via (note that this will download and build the tool from source):: +Install it, for instance, via (note that this will download and build the tool +from source):: - cargo install --locked --version $(scripts/min-tool-version.sh bindgen) bindgen-cli + cargo install --locked bindgen-cli ``bindgen`` uses the ``clang-sys`` crate to find a suitable ``libclang`` (which may be linked statically, dynamically or loaded at runtime). By default, the diff --git a/scripts/rust_is_available.sh b/scripts/rust_is_available.sh index 1881e8f2a2b9..4531f9dd19d3 100755 --- a/scripts/rust_is_available.sh +++ b/scripts/rust_is_available.sh @@ -161,14 +161,6 @@ if [ "$rust_bindings_generator_cversion" -lt "$rust_bindings_generator_min_cvers echo >&2 "***" exit 1 fi -if [ "$rust_bindings_generator_cversion" -gt "$rust_bindings_generator_min_cversion" ]; then - echo >&2 "***" - echo >&2 "*** Rust bindings generator '$BINDGEN' is too new. This may or may not work." - echo >&2 "*** Your version: $rust_bindings_generator_version" - echo >&2 "*** Expected version: $rust_bindings_generator_min_version" - echo >&2 "***" - warning=1 -fi # Check that the `libclang` used by the Rust bindings generator is suitable. # diff --git a/scripts/rust_is_available_test.py b/scripts/rust_is_available_test.py index 0481aab862ec..d6d54b7ea42a 100755 --- a/scripts/rust_is_available_test.py +++ b/scripts/rust_is_available_test.py @@ -231,11 +231,6 @@ else: result = self.run_script(self.Expected.FAILURE, { "BINDGEN": bindgen }) self.assertIn(f"Rust bindings generator '{bindgen}' is too old.", result.stderr) - def test_bindgen_new_version(self): - bindgen = self.generate_bindgen_version("bindgen 0.999.0") - result = self.run_script(self.Expected.SUCCESS_WITH_WARNINGS, { "BINDGEN": bindgen }) - self.assertIn(f"Rust bindings generator '{bindgen}' is too new. This may or may not work.", result.stderr) - def test_bindgen_libclang_failure(self): bindgen = self.generate_bindgen_libclang_failure() result = self.run_script(self.Expected.FAILURE, { "BINDGEN": bindgen }) -- cgit v1.2.3 From b1263411112305acf2af728728591465becb45b0 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Tue, 9 Jul 2024 18:06:08 +0200 Subject: docs: rust: quick-start: add section on Linux distributions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that we are starting to support several Rust compiler and `bindgen` versions, there is a good chance some Linux distributions work out of the box. Thus, provide some instructions on how to set the toolchain up for a few major Linux distributions. This simplifies the setup users need to build the kernel. In addition, add an introduction to the document so that it is easier to understand its structure and move the LLVM+Rust kernel.org toolchains paragraph there (removing "depending on the Linux version"). We may want to reorganize the document or split it in the future, but I wanted to focus this commit on the new information added about each particular distribution. Finally, remove the `rustup`'s components mention in `changes.rst` since users do not need it if they install the toolchain via the distributions (and anyway it was too detailed for that main document). Cc: Jan Alexander Steffens Cc: Johannes Löthberg Cc: Fabian Grünbichler Cc: Josh Stone Cc: Randy Barlow Cc: Anna (navi) Figueiredo Gomes Cc: Matoro Mahri Cc: Ryan Scheel Cc: figsoda Cc: Jörg Thalheim Cc: Theodore Ni <43ngvg@masqt.com> Cc: Winter Cc: William Brown Cc: Xiaoguang Wang Cc: Andrea Righi Cc: Zixing Liu Cc: Nathan Chancellor Tested-by: Benno Lossin Tested-by: Andreas Hindborg Link: https://lore.kernel.org/r/20240709160615.998336-14-ojeda@kernel.org Signed-off-by: Miguel Ojeda --- Documentation/process/changes.rst | 5 -- Documentation/rust/quick-start.rst | 93 +++++++++++++++++++++++++++++++++----- 2 files changed, 81 insertions(+), 17 deletions(-) (limited to 'Documentation/rust') diff --git a/Documentation/process/changes.rst b/Documentation/process/changes.rst index 0d0b7120792b..0ce96ae2588c 100644 --- a/Documentation/process/changes.rst +++ b/Documentation/process/changes.rst @@ -90,11 +90,6 @@ Rust (optional) A recent version of the Rust compiler is required. -Each Rust toolchain comes with several "components", some of which are required -(like ``rustc``) and some that are optional. The ``rust-src`` component (which -is optional) needs to be installed to build the kernel. Other components are -useful for developing. - Please see Documentation/rust/quick-start.rst for instructions on how to satisfy the build requirements of Rust support. In particular, the ``Makefile`` target ``rustavailable`` is useful to check why the Rust toolchain may not diff --git a/Documentation/rust/quick-start.rst b/Documentation/rust/quick-start.rst index 66cefbab8f9a..d06a36106cd4 100644 --- a/Documentation/rust/quick-start.rst +++ b/Documentation/rust/quick-start.rst @@ -5,24 +5,93 @@ Quick Start This document describes how to get started with kernel development in Rust. +There are a few ways to install a Rust toolchain needed for kernel development. +A simple way is to use the packages from your Linux distribution if they are +suitable -- the first section below explains this approach. An advantage of this +approach is that, typically, the distribution will match the LLVM used by Rust +and Clang. + +Another way is using the prebuilt stable versions of LLVM+Rust provided on +`kernel.org `_. These are the same slim +and fast LLVM toolchains from :ref:`Getting LLVM ` with versions +of Rust added to them that Rust for Linux supports. Two sets are provided: the +"latest LLVM" and "matching LLVM" (please see the link for more information). + +Alternatively, the next two "Requirements" sections explain each component and +how to install them through ``rustup``, the standalone installers from Rust +and/or building them. + +The rest of the document explains other aspects on how to get started. + + +Distributions +------------- + +Arch Linux +********** + +Arch Linux provides recent Rust releases and thus it should generally work out +of the box, e.g.:: + + pacman -S rust rust-src rust-bindgen + + +Debian +****** + +Debian Unstable (Sid), outside of the freeze period, provides recent Rust +releases and thus it should generally work out of the box, e.g.:: + + apt install rustc rust-src bindgen rustfmt rust-clippy + + +Fedora Linux +************ + +Fedora Linux provides recent Rust releases and thus it should generally work out +of the box, e.g.:: + + dnf install rust rust-src bindgen-cli rustfmt clippy + + +Gentoo Linux +************ + +Gentoo Linux (and especially the testing branch) provides recent Rust releases +and thus it should generally work out of the box, e.g.:: + + USE='rust-src rustfmt clippy' emerge dev-lang/rust dev-util/bindgen + +``LIBCLANG_PATH`` may need to be set. + + +Nix +*** + +Nix (unstable channel) provides recent Rust releases and thus it should +generally work out of the box, e.g.:: + + { pkgs ? import {} }: + pkgs.mkShell { + nativeBuildInputs = with pkgs; [ rustc rust-bindgen rustfmt clippy ]; + RUST_LIB_SRC = "${pkgs.rust.packages.stable.rustPlatform.rustLibSrc}"; + } + + +openSUSE +******** + +openSUSE Slowroll and openSUSE Tumbleweed provide recent Rust releases and thus +they should generally work out of the box, e.g.:: + + zypper install rust rust1.79-src rust-bindgen clang + Requirements: Building ---------------------- This section explains how to fetch the tools needed for building. -Some of these requirements might be available from Linux distributions -under names like ``rustc``, ``rust-src``, ``rust-bindgen``, etc. However, -at the time of writing, they are likely not to be recent enough unless -the distribution tracks the latest releases. - -Prebuilt stable versions of LLVM+Rust are provided on `kernel.org -`_. These are the same slim and fast -LLVM toolchains from :ref:`Getting LLVM ` with versions of Rust -added to them that Rust for Linux supports, depending on the Linux version. Two -sets are provided: the "latest LLVM" and "matching LLVM" (please see the link -for more information). - To easily check whether the requirements are met, the following target can be used:: -- cgit v1.2.3