forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
rust: rework Rust toolchain detection
The name of the `HAS_RUST` option has been renamed to `RUST_IS_AVAILABLE`, and now encompasses more checks to see whether a suitable Rust toolchain is available for compiling the kernel. This will allow us later to remove the `!COMPILE_TEST` bound, which, in turn, will allow to e.g. eventually start testing the Rust support in places that do `all{yes,mod}config`. This also provides an easy way for users/developers to understand why the Rust toolchain might not be available: a Makefile target is provided which explains why that is the case, using the same logic that Kbuild/Kconfig use; which addresses some of the feedback we got. Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
- Loading branch information
Showing
7 changed files
with
198 additions
and
43 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
/* SPDX-License-Identifier: GPL-2.0 */ | ||
#pragma message("clang version " __clang_version__) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
#!/bin/sh | ||
# SPDX-License-Identifier: GPL-2.0 | ||
# | ||
# Tests whether a suitable Rust toolchain is available. | ||
# | ||
# Pass `-v` for human output and more checks (as warnings). | ||
|
||
set -e | ||
|
||
min_tool_version=$(dirname $0)/min-tool-version.sh | ||
|
||
# Convert the version string x.y.z to a canonical up-to-7-digits form. | ||
# | ||
# Note that this function uses one more digit (compared to other | ||
# instances in other version scripts) to give a bit more space to | ||
# `rustc` since it will reach 1.100.0 in late 2026. | ||
get_canonical_version() | ||
{ | ||
IFS=. | ||
set -- $1 | ||
echo $((100000 * $1 + 100 * $2 + $3)) | ||
} | ||
|
||
# Check that the Rust compiler exists. | ||
if ! command -v "$RUSTC" >/dev/null; then | ||
if [ "$1" = -v ]; then | ||
echo >&2 "***" | ||
echo >&2 "*** Rust compiler '$RUSTC' could not be found." | ||
echo >&2 "***" | ||
fi | ||
exit 1 | ||
fi | ||
|
||
# Check that the Rust bindings generator exists. | ||
if ! command -v "$BINDGEN" >/dev/null; then | ||
if [ "$1" = -v ]; then | ||
echo >&2 "***" | ||
echo >&2 "*** Rust bindings generator '$BINDGEN' could not be found." | ||
echo >&2 "***" | ||
fi | ||
exit 1 | ||
fi | ||
|
||
# Check that the Rust compiler version is suitable. | ||
# | ||
# Non-stable and distributions' versions may have a version suffix, e.g. `-dev`. | ||
rust_compiler_version=$("$RUSTC" --version | cut -f2 -d' ' | cut -f1 -d'-') | ||
rust_compiler_min_version=$($min_tool_version rustc) | ||
rust_compiler_cversion=$(get_canonical_version $rust_compiler_version) | ||
rust_compiler_min_cversion=$(get_canonical_version $rust_compiler_min_version) | ||
if [ "$rust_compiler_cversion" -lt "$rust_compiler_min_cversion" ]; then | ||
if [ "$1" = -v ]; then | ||
echo >&2 "***" | ||
echo >&2 "*** Rust compiler '$RUSTC' is too old." | ||
echo >&2 "*** Your version: $rust_compiler_version" | ||
echo >&2 "*** Minimum version: $rust_compiler_min_version" | ||
echo >&2 "***" | ||
fi | ||
exit 1 | ||
fi | ||
if [ "$1" = -v ] && [ "$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 "***" | ||
fi | ||
|
||
# Check that the Rust bindings generator is suitable. | ||
# | ||
# Non-stable and distributions' versions may have a version suffix, e.g. `-dev`. | ||
rust_bindings_generator_version=$("$BINDGEN" --version | cut -f2 -d' ' | cut -f1 -d'-') | ||
rust_bindings_generator_min_version=$($min_tool_version bindgen) | ||
rust_bindings_generator_cversion=$(get_canonical_version $rust_bindings_generator_version) | ||
rust_bindings_generator_min_cversion=$(get_canonical_version $rust_bindings_generator_min_version) | ||
if [ "$rust_bindings_generator_cversion" -lt "$rust_bindings_generator_min_cversion" ]; then | ||
if [ "$1" = -v ]; then | ||
echo >&2 "***" | ||
echo >&2 "*** Rust bindings generator '$BINDGEN' is too old." | ||
echo >&2 "*** Your version: $rust_bindings_generator_version" | ||
echo >&2 "*** Minimum version: $rust_bindings_generator_min_version" | ||
echo >&2 "***" | ||
fi | ||
exit 1 | ||
fi | ||
if [ "$1" = -v ] && [ "$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 "***" | ||
fi | ||
|
||
# Check that the `libclang` used by the Rust bindings generator is suitable. | ||
# | ||
# There may be a better way to do this in the future, | ||
# see https://github.com/rust-lang/rust-bindgen/issues/2138 | ||
bindgen_libclang_full_version=$(\ | ||
"$BINDGEN" $(dirname $0)/rust-is-available-bindgen-libclang.h 2>&1 >/dev/null \ | ||
| grep -F 'clang version' \ | ||
| sed -E 's:^.*(clang version .*) \[.*$:\1:' \ | ||
) | ||
bindgen_libclang_version=$(echo "$bindgen_libclang_full_version" | cut -f3 -d' ') | ||
bindgen_libclang_min_version=$($min_tool_version llvm) | ||
bindgen_libclang_cversion=$(get_canonical_version $bindgen_libclang_version) | ||
bindgen_libclang_min_cversion=$(get_canonical_version $bindgen_libclang_min_version) | ||
if [ "$bindgen_libclang_cversion" -lt "$bindgen_libclang_min_cversion" ]; then | ||
if [ "$1" = -v ]; then | ||
echo >&2 "***" | ||
echo >&2 "*** libclang (used by the Rust bindings generator '$BINDGEN') is too old." | ||
echo >&2 "*** Your version: $bindgen_libclang_version" | ||
echo >&2 "*** Minimum version: $bindgen_libclang_min_version" | ||
echo >&2 "***" | ||
fi | ||
exit 1 | ||
fi | ||
|
||
# If the C compiler is Clang, then we can also check whether its full version | ||
# matches exactly the `libclang` used by the Rust bindings generator. | ||
if [ "$1" = -v ]; then | ||
cc_name=$($(dirname $0)/cc-version.sh "$CC" | cut -f1 -d' ') | ||
if [ "$cc_name" = Clang ]; then | ||
clang_full_version=$("$CC" --version | grep -F 'clang version') | ||
if [ "$clang_full_version" != "$bindgen_libclang_full_version" ]; then | ||
echo >&2 "***" | ||
echo >&2 "*** libclang (used by the Rust bindings generator '$BINDGEN') full version does not match Clang's. This may be a problem." | ||
echo >&2 "*** libclang: $bindgen_libclang_full_version" | ||
echo >&2 "*** Clang: $clang_full_version" | ||
echo >&2 "***" | ||
fi | ||
fi | ||
fi | ||
|
||
# Check that the source code for the `core` standard library exists. | ||
# | ||
# `$KRUSTFLAGS` is passed in case the user added `--sysroot`. | ||
rustc_sysroot=$("$RUSTC" $KRUSTFLAGS --print sysroot) | ||
rustc_src="$rustc_sysroot/lib/rustlib/src/rust/library" | ||
rustc_src_core="$rustc_src/core/src/lib.rs" | ||
if [ ! -e "$rustc_src_core" ]; then | ||
if [ "$1" = -v ]; then | ||
echo >&2 "***" | ||
echo >&2 "*** Source code for the 'core' standard library could not be found" | ||
echo >&2 "*** at '$rustc_src_core'." | ||
echo >&2 "***" | ||
fi | ||
exit 1 | ||
fi | ||
|
||
# Success! | ||
if [ "$1" = -v ]; then | ||
echo >&2 "Rust is available!" | ||
fi |
This file was deleted.
Oops, something went wrong.