Skip to content

Commit

Permalink
Merge pull request torvalds#625 from ojeda/kbuild
Browse files Browse the repository at this point in the history
Build system review
  • Loading branch information
ojeda authored Jan 15, 2022
2 parents 97668ff + cf00942 commit 27fe495
Show file tree
Hide file tree
Showing 13 changed files with 272 additions and 77 deletions.
38 changes: 32 additions & 6 deletions Documentation/process/changes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,12 @@ running a Linux kernel. Also, not all tools are necessary on all
systems; obviously, if you don't have any PC Card hardware, for example,
you probably needn't concern yourself with pcmciautils.

Furthermore, note that newer versions of the Rust toolchain may or may not work
because, for the moment, we depend on some unstable features. Thus, unless you
know what you are doing, use the exact version listed here. Please see
:ref:`Documentation/rust/quick-start.rst <rust_quick_start>` for details.

====================== =============== ========================================
Program Minimal version Command to check the version
====================== =============== ========================================
GNU C 5.1 gcc --version
Clang/LLVM (optional) 10.0.1 clang --version
rustc (optional) 1.58.0 rustc --version
Rust (optional) 1.58.0 rustc --version
bindgen (optional) 0.56.0 bindgen --version
GNU make 3.81 make --version
binutils 2.23 ld -v
Expand Down Expand Up @@ -85,6 +80,27 @@ kernels. Older releases aren't guaranteed to work, and we may drop workarounds
from the kernel that were used to support older versions. Please see additional
docs on :ref:`Building Linux with Clang/LLVM <kbuild_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.

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 :ref:`Documentation/rust/quick-start.rst <rust_quick_start>` for
more information.

bindgen (optional)
------------------

``bindgen`` is used to generate the Rust bindings to the C side of the kernel.
It depends on ``libclang``.

Make
----

Expand Down Expand Up @@ -369,6 +385,16 @@ Clang/LLVM

- :ref:`Getting LLVM <getting_llvm>`.

Rust
----

- :ref:`Documentation/rust/quick-start.rst <rust_quick_start>`.

bindgen
-------

- :ref:`Documentation/rust/quick-start.rst <rust_quick_start>`.

Make
----

Expand Down
35 changes: 27 additions & 8 deletions Documentation/rust/quick-start.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,17 @@ 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.
at the time of writing, they are likely not to be recent enough unless
the distribution tracks the latest releases.

To easily check whether the requirements are met, the following target
can be used::

make LLVM=1 rustavailable

This triggers the same logic used by Kconfig to determine whether
``RUST_IS_AVAILABLE`` should be enabled; but it also explains why not
if that is the case.


rustc
Expand All @@ -26,7 +36,7 @@ Rust features.
If ``rustup`` is being used, enter the checked out source code directory
and run::

rustup override set 1.58.0
rustup override set $(scripts/min-tool-version.sh rustc)

Otherwise, fetch a standalone installer or install ``rustup`` from:

Expand All @@ -43,10 +53,19 @@ If ``rustup`` is being used, run::

rustup component add rust-src

The components are installed per toolchain, thus upgrading the Rust compiler
version later on requires re-adding the component.

Otherwise, if a standalone installer is used, the Rust repository may be cloned
into the installation folder of the toolchain::

git clone --recurse-submodules https://github.com/rust-lang/rust $(rustc --print sysroot)/lib/rustlib/src/rust
git clone --recurse-submodules \
--branch $(scripts/min-tool-version.sh rustc) \
https://github.com/rust-lang/rust \
$(rustc --print sysroot)/lib/rustlib/src/rust

In this case, upgrading the Rust compiler version later on requires manually
updating this clone.


libclang
Expand All @@ -67,8 +86,8 @@ Otherwise, building LLVM takes quite a while, but it is not a complex process:

https://llvm.org/docs/GettingStarted.html#getting-the-source-code-and-building-llvm

See Documentation/kbuild/llvm.rst for more information and further ways
to fetch pre-built releases and distribution packages.
See :ref:`Documentation/kbuild/llvm.rst <kbuild_llvm>` for more information and
further ways to fetch pre-built releases and distribution packages.


bindgen
Expand All @@ -79,7 +98,7 @@ the ``bindgen`` tool. A particular version is required.

Install it via (note that this will download and build the tool from source)::

cargo install --locked --version 0.56.0 bindgen
cargo install --locked --version $(scripts/min-tool-version.sh bindgen) bindgen


Requirements: Developing
Expand Down Expand Up @@ -167,8 +186,8 @@ Configuration
-------------

``Rust support`` (``CONFIG_RUST``) needs to be enabled in the ``General setup``
menu. The option is only shown if the build system can locate ``rustc``.
In turn, this will make visible the rest of options that depend on Rust.
menu. The option is only shown if a suitable Rust toolchain is found (see
above). In turn, this will make visible the rest of options that depend on Rust.

Afterwards, go to::

Expand Down
1 change: 1 addition & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -16591,6 +16591,7 @@ F: rust/
F: samples/rust/
F: Documentation/rust/
F: lib/rust.h
F: scripts/*rust*
K: \b(?i:rust)\b

RXRPC SOCKETS (AF_RXRPC)
Expand Down
11 changes: 9 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ no-dot-config-targets := $(clean-targets) \
cscope gtags TAGS tags help% %docs check% coccicheck \
$(version_h) headers headers_% archheaders archscripts \
%asm-generic kernelversion %src-pkg dt_binding_check \
outputmakefile rustfmt rustfmtcheck
outputmakefile rustavailable rustfmt rustfmtcheck
# Installation targets should not require compiler. Unfortunately, vdso_install
# is an exception where build artifacts may be updated. This must be fixed.
no-compiler-targets := $(no-dot-config-targets) install dtbs_install \
Expand Down Expand Up @@ -809,7 +809,7 @@ KBUILD_CFLAGS += -O3
KBUILD_RUSTFLAGS_OPT_LEVEL_MAP := 3
else ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
KBUILD_CFLAGS += -Os
KBUILD_RUSTFLAGS_OPT_LEVEL_MAP := z
KBUILD_RUSTFLAGS_OPT_LEVEL_MAP := s
endif

# Always set `debug-assertions` and `overflow-checks` because their default
Expand Down Expand Up @@ -1696,6 +1696,8 @@ help:
@echo ' kselftest to existing .config.'
@echo ''
@echo 'Rust targets:'
@echo ' rustavailable - Checks whether the Rust toolchain is'
@echo ' available and, if not, explains why.'
@echo ' rustfmt - Reformat all the Rust code in the kernel'
@echo ' rustfmtcheck - Checks if all the Rust code in the kernel'
@echo ' is formatted, printing a diff otherwise.'
Expand Down Expand Up @@ -1781,6 +1783,11 @@ $(DOC_TARGETS):
# Rust targets
# ---------------------------------------------------------------------------

# "Is Rust available?" target
PHONY += rustavailable
rustavailable:
$(Q)$(CONFIG_SHELL) $(srctree)/scripts/rust-is-available.sh -v

# Documentation target
#
# Using the singular to avoid running afoul of `no-dot-config-targets`.
Expand Down
30 changes: 22 additions & 8 deletions init/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,16 @@ config LLD_VERSION
default $(ld-version) if LD_IS_LLD
default 0

config HAS_RUST
depends on ARM64 || CPU_32v6 || CPU_32v6K || (PPC64 && CPU_LITTLE_ENDIAN) || X86_64 || RISCV
def_bool $(success,$(RUSTC) --version)
config RUST_IS_AVAILABLE
def_bool $(success,$(srctree)/scripts/rust-is-available.sh)
help
This shows whether a suitable Rust toolchain is available (found).

config RUSTC_VERSION
depends on HAS_RUST
int
default $(shell,$(srctree)/scripts/rust-version.sh $(RUSTC))
Please see Documentation/rust/quick-start.rst for instructions on how
to satify the build requirements of Rust support.

In particular, the Makefile target 'rustavailable' is useful to check
why the Rust toolchain is not being detected.

config CC_CAN_LINK
bool
Expand Down Expand Up @@ -2056,9 +2058,11 @@ config PROFILING

config RUST
bool "Rust support"
depends on HAS_RUST
depends on RUST_IS_AVAILABLE
depends on ARM64 || CPU_32v6 || CPU_32v6K || (PPC64 && CPU_LITTLE_ENDIAN) || X86_64 || RISCV
depends on !COMPILE_TEST
depends on !MODVERSIONS
depends on !GCC_PLUGIN_RANDSTRUCT
default n
help
Enables Rust support in the kernel.
Expand All @@ -2073,6 +2077,16 @@ config RUST

If unsure, say N.

config RUSTC_VERSION_TEXT
depends on RUST
string
default $(shell,$(RUSTC) --version)

config BINDGEN_VERSION_TEXT
depends on RUST
string
default $(shell,$(BINDGEN) --version)

#
# Place an empty function call at each tracepoint site. Can be
# dynamically changed for a probe function.
Expand Down
2 changes: 1 addition & 1 deletion lib/Kconfig.debug
Original file line number Diff line number Diff line change
Expand Up @@ -2677,7 +2677,7 @@ config RUST_OVERFLOW_CHECKS
Enables rustc's `-Coverflow-checks` codegen option.

This flag allows you to control the behavior of runtime integer
overflow. When overflow-checks are enabled, a panic will occur
overflow. When overflow-checks are enabled, a Rust panic will occur
on overflow.

Note that this will apply to all Rust code, including `core`.
Expand Down
22 changes: 10 additions & 12 deletions rust/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -188,26 +188,24 @@ else
# bindgen relies on libclang to parse C. Ideally, bindgen would support a GCC
# plugin backend and/or the Clang driver would be perfectly compatible with GCC.
#
# For the moment, here we are tweaking the flags on the fly. Some config
# options may not work (e.g. `GCC_PLUGIN_RANDSTRUCT` if we end up using one
# of those structs).
# For the moment, here we are tweaking the flags on the fly. This is a hack,
# and some kernel configurations may not work (e.g. `GCC_PLUGIN_RANDSTRUCT`
# if we end up using one of those structs).
bindgen_skip_c_flags := -mno-fp-ret-in-387 -mpreferred-stack-boundary=% \
-mskip-rax-setup -mgeneral-regs-only -msign-return-address=% \
-mindirect-branch=thunk-extern -mindirect-branch-register -mrecord-mcount \
-mabi=lp64 -mstack-protector-guard% -fconserve-stack -falign-jumps=% \
-falign-loops=% -femit-struct-debug-baseonly \
-fno-ipa-cp-clone -fno-ipa-sra -fno-partial-inlining \
-fplugin-arg-arm_ssp_per_task_plugin-% \
-mabi=lp64 -mstack-protector-guard% -mtraceback=no \
-mno-pointers-to-nested-functions -mno-string -mno-strict-align \
-fconserve-stack -falign-jumps=% -falign-loops=% \
-femit-struct-debug-baseonly -fno-ipa-cp-clone -fno-ipa-sra \
-fno-partial-inlining -fplugin-arg-arm_ssp_per_task_plugin-% \
-fno-reorder-blocks -fno-allow-store-data-races -fasan-shadow-offset=% \
-Wno-packed-not-aligned -Wno-format-truncation -Wno-format-overflow \
-Wno-stringop-truncation -Wno-unused-but-set-variable \
-Wno-stringop-overflow -Wno-restrict -Wno-maybe-uninitialized \
-Werror=designated-init -Wno-zero-length-bounds -Wimplicit-fallthrough=% \
-Wno-alloc-size-larger-than --param=% --param asan-%

# PowerPC
bindgen_skip_c_flags += -mtraceback=no -mno-pointers-to-nested-functions \
-mno-string -mno-strict-align
-Wno-alloc-size-larger-than \
--param=% --param asan-%

# Derived from `scripts/Makefile.clang`
BINDGEN_TARGET_arm := arm-linux-gnueabi
Expand Down
6 changes: 3 additions & 3 deletions scripts/Kconfig.include
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ ld-option = $(success,$(LD) -v $(1))
as-instr = $(success,printf "%b\n" "$(1)" | $(CC) $(CLANG_FLAGS) -c -x assembler -o /dev/null -)

# check if $(CC) and $(LD) exist
$(error-if,$(failure,command -v $(CC)),compiler '$(CC)' not found)
$(error-if,$(failure,command -v $(CC)),C compiler '$(CC)' not found)
$(error-if,$(failure,command -v $(LD)),linker '$(LD)' not found)

# Get the compiler name, version, and error out if it is not supported.
# Get the C compiler name, version, and error out if it is not supported.
cc-info := $(shell,$(srctree)/scripts/cc-version.sh $(CC))
$(error-if,$(success,test -z "$(cc-info)"),Sorry$(comma) this compiler is not supported.)
$(error-if,$(success,test -z "$(cc-info)"),Sorry$(comma) this C compiler is not supported.)
cc-name := $(shell,set -- $(cc-info) && echo $1)
cc-version := $(shell,set -- $(cc-info) && echo $2)

Expand Down
12 changes: 6 additions & 6 deletions scripts/cc-version.sh
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
#
# Print the compiler name and its version in a 5 or 6-digit form.
# Print the C compiler name and its version in a 5 or 6-digit form.
# Also, perform the minimum version check.

set -e

# Print the compiler name and some version components.
get_compiler_info()
# Print the C compiler name and some version components.
get_c_compiler_info()
{
cat <<- EOF | "$@" -E -P -x c - 2>/dev/null
#if defined(__clang__)
Expand All @@ -32,7 +32,7 @@ get_canonical_version()

# $@ instead of $1 because multiple words might be given, e.g. CC="ccache gcc".
orig_args="$@"
set -- $(get_compiler_info "$@")
set -- $(get_c_compiler_info "$@")

name=$1

Expand All @@ -52,7 +52,7 @@ ICC)
min_version=$($min_tool_version icc)
;;
*)
echo "$orig_args: unknown compiler" >&2
echo "$orig_args: unknown C compiler" >&2
exit 1
;;
esac
Expand All @@ -62,7 +62,7 @@ min_cversion=$(get_canonical_version $min_version)

if [ "$cversion" -lt "$min_cversion" ]; then
echo >&2 "***"
echo >&2 "*** Compiler is too old."
echo >&2 "*** C compiler is too old."
echo >&2 "*** Your $name version: $version"
echo >&2 "*** Minimum $name version: $min_version"
echo >&2 "***"
Expand Down
6 changes: 6 additions & 0 deletions scripts/min-tool-version.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ llvm)
echo 10.0.1
fi
;;
rustc)
echo 1.58.0
;;
bindgen)
echo 0.56.0
;;
*)
echo "$1: unknown tool" >&2
exit 1
Expand Down
2 changes: 2 additions & 0 deletions scripts/rust-is-available-bindgen-libclang.h
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__)
Loading

0 comments on commit 27fe495

Please sign in to comment.