2021-07-03 14:42:57 +00:00
|
|
|
# SPDX-License-Identifier: GPL-2.0
|
|
|
|
|
2023-07-18 15:15:33 +00:00
|
|
|
# Where to place rustdoc generated documentation
|
|
|
|
rustdoc_output := $(objtree)/Documentation/output/rust/rustdoc
|
|
|
|
|
2021-07-03 14:42:57 +00:00
|
|
|
obj-$(CONFIG_RUST) += core.o compiler_builtins.o
|
|
|
|
always-$(CONFIG_RUST) += exports_core_generated.h
|
|
|
|
|
|
|
|
# Missing prototypes are expected in the helpers since these are exported
|
|
|
|
# for Rust only, thus there is no header nor prototypes.
|
2024-08-15 10:30:26 +00:00
|
|
|
obj-$(CONFIG_RUST) += helpers/helpers.o
|
|
|
|
CFLAGS_REMOVE_helpers/helpers.o = -Wmissing-prototypes -Wmissing-declarations
|
2021-07-03 14:42:57 +00:00
|
|
|
|
|
|
|
always-$(CONFIG_RUST) += libmacros.so
|
|
|
|
no-clean-files += libmacros.so
|
|
|
|
|
|
|
|
always-$(CONFIG_RUST) += bindings/bindings_generated.rs bindings/bindings_helpers_generated.rs
|
|
|
|
obj-$(CONFIG_RUST) += alloc.o bindings.o kernel.o
|
2024-08-17 16:51:32 +00:00
|
|
|
always-$(CONFIG_RUST) += exports_alloc_generated.h exports_helpers_generated.h \
|
|
|
|
exports_bindings_generated.h exports_kernel_generated.h
|
2021-07-03 14:42:57 +00:00
|
|
|
|
2023-04-03 09:33:52 +00:00
|
|
|
always-$(CONFIG_RUST) += uapi/uapi_generated.rs
|
|
|
|
obj-$(CONFIG_RUST) += uapi.o
|
|
|
|
|
2022-11-10 16:41:37 +00:00
|
|
|
ifdef CONFIG_RUST_BUILD_ASSERT_ALLOW
|
|
|
|
obj-$(CONFIG_RUST) += build_error.o
|
|
|
|
else
|
|
|
|
always-$(CONFIG_RUST) += build_error.o
|
|
|
|
endif
|
|
|
|
|
2021-07-03 14:42:57 +00:00
|
|
|
obj-$(CONFIG_RUST) += exports.o
|
|
|
|
|
rust: support running Rust documentation tests as KUnit ones
Rust has documentation tests: these are typically examples of
usage of any item (e.g. function, struct, module...).
They are very convenient because they are just written
alongside the documentation. For instance:
/// Sums two numbers.
///
/// ```
/// assert_eq!(mymod::f(10, 20), 30);
/// ```
pub fn f(a: i32, b: i32) -> i32 {
a + b
}
In userspace, the tests are collected and run via `rustdoc`.
Using the tool as-is would be useful already, since it allows
to compile-test most tests (thus enforcing they are kept
in sync with the code they document) and run those that do not
depend on in-kernel APIs.
However, by transforming the tests into a KUnit test suite,
they can also be run inside the kernel. Moreover, the tests
get to be compiled as other Rust kernel objects instead of
targeting userspace.
On top of that, the integration with KUnit means the Rust
support gets to reuse the existing testing facilities. For
instance, the kernel log would look like:
KTAP version 1
1..1
KTAP version 1
# Subtest: rust_doctests_kernel
1..59
# rust_doctest_kernel_build_assert_rs_0.location: rust/kernel/build_assert.rs:13
ok 1 rust_doctest_kernel_build_assert_rs_0
# rust_doctest_kernel_build_assert_rs_1.location: rust/kernel/build_assert.rs:56
ok 2 rust_doctest_kernel_build_assert_rs_1
# rust_doctest_kernel_init_rs_0.location: rust/kernel/init.rs:122
ok 3 rust_doctest_kernel_init_rs_0
...
# rust_doctest_kernel_types_rs_2.location: rust/kernel/types.rs:150
ok 59 rust_doctest_kernel_types_rs_2
# rust_doctests_kernel: pass:59 fail:0 skip:0 total:59
# Totals: pass:59 fail:0 skip:0 total:59
ok 1 rust_doctests_kernel
Therefore, add support for running Rust documentation tests
in KUnit. Some other notes about the current implementation
and support follow.
The transformation is performed by a couple scripts written
as Rust hostprogs.
Tests using the `?` operator are also supported as usual, e.g.:
/// ```
/// # use kernel::{spawn_work_item, workqueue};
/// spawn_work_item!(workqueue::system(), || pr_info!("x"))?;
/// # Ok::<(), Error>(())
/// ```
The tests are also compiled with Clippy under `CLIPPY=1`, just
like normal code, thus also benefitting from extra linting.
The names of the tests are currently automatically generated.
This allows to reduce the burden for documentation writers,
while keeping them fairly stable for bisection. This is an
improvement over the `rustdoc`-generated names, which include
the line number; but ideally we would like to get `rustdoc` to
provide the Rust item path and a number (for multiple examples
in a single documented Rust item).
In order for developers to easily see from which original line
a failed doctests came from, a KTAP diagnostic line is printed
to the log, containing the location (file and line) of the
original test (i.e. instead of the location in the generated
Rust file):
# rust_doctest_kernel_types_rs_2.location: rust/kernel/types.rs:150
This line follows the syntax for declaring test metadata in the
proposed KTAP v2 spec [1], which may be used for the proposed
KUnit test attributes API [2]. Thus hopefully this will make
migration easier later on (suggested by David [3]).
The original line in that test attribute is figured out by
providing an anchor (suggested by Boqun [4]). The original file
is found by walking the filesystem, checking directory prefixes
to reduce the amount of combinations to check, and it is only
done once per file. Ambiguities are detected and reported.
A notable difference from KUnit C tests is that the Rust tests
appear to assert using the usual `assert!` and `assert_eq!`
macros from the Rust standard library (`core`). We provide
a custom version that forwards the call to KUnit instead.
Importantly, these macros do not require passing context,
unlike the KUnit C ones (i.e. `struct kunit *`). This makes
them easier to use, and readers of the documentation do not need
to care about which testing framework is used. In addition, it
may allow us to test third-party code more easily in the future.
However, a current limitation is that KUnit does not support
assertions in other tasks. Thus we presently simply print an
error to the kernel log if an assertion actually failed. This
should be revisited to properly fail the test, perhaps saving
the context somewhere else, or letting KUnit handle it.
Link: https://lore.kernel.org/lkml/20230420205734.1288498-1-rmoar@google.com/ [1]
Link: https://lore.kernel.org/linux-kselftest/20230707210947.1208717-1-rmoar@google.com/ [2]
Link: https://lore.kernel.org/rust-for-linux/CABVgOSkOLO-8v6kdAGpmYnZUb+LKOX0CtYCo-Bge7r_2YTuXDQ@mail.gmail.com/ [3]
Link: https://lore.kernel.org/rust-for-linux/ZIps86MbJF%2FiGIzd@boqun-archlinux/ [4]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-07-18 05:27:51 +00:00
|
|
|
always-$(CONFIG_RUST_KERNEL_DOCTESTS) += doctests_kernel_generated.rs
|
|
|
|
always-$(CONFIG_RUST_KERNEL_DOCTESTS) += doctests_kernel_generated_kunit.c
|
|
|
|
|
|
|
|
obj-$(CONFIG_RUST_KERNEL_DOCTESTS) += doctests_kernel_generated.o
|
|
|
|
obj-$(CONFIG_RUST_KERNEL_DOCTESTS) += doctests_kernel_generated_kunit.o
|
|
|
|
|
2021-07-03 14:42:57 +00:00
|
|
|
# Avoids running `$(RUSTC)` for the sysroot when it may not be available.
|
|
|
|
ifdef CONFIG_RUST
|
|
|
|
|
|
|
|
# `$(rust_flags)` is passed in case the user added `--sysroot`.
|
kbuild: mark `rustc` (and others) invocations as recursive
`rustc` (like Cargo) may take advantage of the jobserver at any time
(e.g. for backend parallelism, or eventually frontend too). In the kernel,
we call `rustc` with `-Ccodegen-units=1` (and `-Zthreads` is 1 so far),
so we do not expect parallelism. However, in the upcoming Rust 1.76.0, a
warning is emitted by `rustc` [1] when it cannot connect to the jobserver
it was passed (in many cases, but not all: compiling and `--print sysroot`
do, but `--version` does not). And given GNU Make always passes
the jobserver in the environment variable (even when a line is deemed
non-recursive), `rustc` will end up complaining about it (in particular
in Make 4.3 where there is only the simple pipe jobserver style).
One solution is to remove the jobserver from `MAKEFLAGS`. However, we
can mark the lines with calls to `rustc` (and Cargo) as recursive, which
looks simpler. This is being documented as a recommendation in `rustc`
[2] and allows us to be ready for the time we may use parallelism inside
`rustc` (potentially now, if a user passes `-Zthreads`). Thus do so.
Similarly, do the same for `rustdoc` and `cargo` calls.
Finally, there is one case that the solution does not cover, which is the
`$(shell ...)` call we have. Thus, for that one, set an empty `MAKEFLAGS`
environment variable.
Link: https://github.com/rust-lang/rust/issues/120515 [1]
Acked-by: Masahiro Yamada <masahiroy@kernel.org>
Link: https://github.com/rust-lang/rust/pull/121564 [2]
Link: https://lore.kernel.org/r/20240217002638.57373-1-ojeda@kernel.org
[ Reworded to add link to PR documenting the recommendation. ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2024-02-17 00:26:37 +00:00
|
|
|
rustc_sysroot := $(shell MAKEFLAGS= $(RUSTC) $(rust_flags) --print sysroot)
|
2021-07-03 14:42:57 +00:00
|
|
|
rustc_host_target := $(shell $(RUSTC) --version --verbose | grep -F 'host: ' | cut -d' ' -f2)
|
|
|
|
RUST_LIB_SRC ?= $(rustc_sysroot)/lib/rustlib/src/rust/library
|
|
|
|
|
2024-05-28 16:35:02 +00:00
|
|
|
ifneq ($(quiet),)
|
2021-07-03 14:42:57 +00:00
|
|
|
rust_test_quiet=-q
|
|
|
|
rustdoc_test_quiet=--test-args -q
|
rust: support running Rust documentation tests as KUnit ones
Rust has documentation tests: these are typically examples of
usage of any item (e.g. function, struct, module...).
They are very convenient because they are just written
alongside the documentation. For instance:
/// Sums two numbers.
///
/// ```
/// assert_eq!(mymod::f(10, 20), 30);
/// ```
pub fn f(a: i32, b: i32) -> i32 {
a + b
}
In userspace, the tests are collected and run via `rustdoc`.
Using the tool as-is would be useful already, since it allows
to compile-test most tests (thus enforcing they are kept
in sync with the code they document) and run those that do not
depend on in-kernel APIs.
However, by transforming the tests into a KUnit test suite,
they can also be run inside the kernel. Moreover, the tests
get to be compiled as other Rust kernel objects instead of
targeting userspace.
On top of that, the integration with KUnit means the Rust
support gets to reuse the existing testing facilities. For
instance, the kernel log would look like:
KTAP version 1
1..1
KTAP version 1
# Subtest: rust_doctests_kernel
1..59
# rust_doctest_kernel_build_assert_rs_0.location: rust/kernel/build_assert.rs:13
ok 1 rust_doctest_kernel_build_assert_rs_0
# rust_doctest_kernel_build_assert_rs_1.location: rust/kernel/build_assert.rs:56
ok 2 rust_doctest_kernel_build_assert_rs_1
# rust_doctest_kernel_init_rs_0.location: rust/kernel/init.rs:122
ok 3 rust_doctest_kernel_init_rs_0
...
# rust_doctest_kernel_types_rs_2.location: rust/kernel/types.rs:150
ok 59 rust_doctest_kernel_types_rs_2
# rust_doctests_kernel: pass:59 fail:0 skip:0 total:59
# Totals: pass:59 fail:0 skip:0 total:59
ok 1 rust_doctests_kernel
Therefore, add support for running Rust documentation tests
in KUnit. Some other notes about the current implementation
and support follow.
The transformation is performed by a couple scripts written
as Rust hostprogs.
Tests using the `?` operator are also supported as usual, e.g.:
/// ```
/// # use kernel::{spawn_work_item, workqueue};
/// spawn_work_item!(workqueue::system(), || pr_info!("x"))?;
/// # Ok::<(), Error>(())
/// ```
The tests are also compiled with Clippy under `CLIPPY=1`, just
like normal code, thus also benefitting from extra linting.
The names of the tests are currently automatically generated.
This allows to reduce the burden for documentation writers,
while keeping them fairly stable for bisection. This is an
improvement over the `rustdoc`-generated names, which include
the line number; but ideally we would like to get `rustdoc` to
provide the Rust item path and a number (for multiple examples
in a single documented Rust item).
In order for developers to easily see from which original line
a failed doctests came from, a KTAP diagnostic line is printed
to the log, containing the location (file and line) of the
original test (i.e. instead of the location in the generated
Rust file):
# rust_doctest_kernel_types_rs_2.location: rust/kernel/types.rs:150
This line follows the syntax for declaring test metadata in the
proposed KTAP v2 spec [1], which may be used for the proposed
KUnit test attributes API [2]. Thus hopefully this will make
migration easier later on (suggested by David [3]).
The original line in that test attribute is figured out by
providing an anchor (suggested by Boqun [4]). The original file
is found by walking the filesystem, checking directory prefixes
to reduce the amount of combinations to check, and it is only
done once per file. Ambiguities are detected and reported.
A notable difference from KUnit C tests is that the Rust tests
appear to assert using the usual `assert!` and `assert_eq!`
macros from the Rust standard library (`core`). We provide
a custom version that forwards the call to KUnit instead.
Importantly, these macros do not require passing context,
unlike the KUnit C ones (i.e. `struct kunit *`). This makes
them easier to use, and readers of the documentation do not need
to care about which testing framework is used. In addition, it
may allow us to test third-party code more easily in the future.
However, a current limitation is that KUnit does not support
assertions in other tasks. Thus we presently simply print an
error to the kernel log if an assertion actually failed. This
should be revisited to properly fail the test, perhaps saving
the context somewhere else, or letting KUnit handle it.
Link: https://lore.kernel.org/lkml/20230420205734.1288498-1-rmoar@google.com/ [1]
Link: https://lore.kernel.org/linux-kselftest/20230707210947.1208717-1-rmoar@google.com/ [2]
Link: https://lore.kernel.org/rust-for-linux/CABVgOSkOLO-8v6kdAGpmYnZUb+LKOX0CtYCo-Bge7r_2YTuXDQ@mail.gmail.com/ [3]
Link: https://lore.kernel.org/rust-for-linux/ZIps86MbJF%2FiGIzd@boqun-archlinux/ [4]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-07-18 05:27:51 +00:00
|
|
|
rustdoc_test_kernel_quiet=>/dev/null
|
2021-07-03 14:42:57 +00:00
|
|
|
endif
|
|
|
|
|
|
|
|
core-cfgs = \
|
|
|
|
--cfg no_fp_fmt_parse
|
|
|
|
|
|
|
|
alloc-cfgs = \
|
|
|
|
--cfg no_global_oom_handling \
|
|
|
|
--cfg no_rc \
|
2024-03-28 01:35:56 +00:00
|
|
|
--cfg no_sync
|
2021-07-03 14:42:57 +00:00
|
|
|
|
|
|
|
quiet_cmd_rustdoc = RUSTDOC $(if $(rustdoc_host),H, ) $<
|
|
|
|
cmd_rustdoc = \
|
|
|
|
OBJTREE=$(abspath $(objtree)) \
|
|
|
|
$(RUSTDOC) $(if $(rustdoc_host),$(rust_common_flags),$(rust_flags)) \
|
|
|
|
$(rustc_target_flags) -L$(objtree)/$(obj) \
|
2024-08-18 14:12:49 +00:00
|
|
|
-Zunstable-options --generate-link-to-definition \
|
2023-07-18 15:15:33 +00:00
|
|
|
--output $(rustdoc_output) \
|
2021-07-03 14:42:57 +00:00
|
|
|
--crate-name $(subst rustdoc-,,$@) \
|
2023-10-31 20:10:14 +00:00
|
|
|
$(if $(rustdoc_host),,--sysroot=/dev/null) \
|
2021-07-03 14:42:57 +00:00
|
|
|
@$(objtree)/include/generated/rustc_cfg $<
|
|
|
|
|
|
|
|
# The `html_logo_url` and `html_favicon_url` forms of the `doc` attribute
|
|
|
|
# can be used to specify a custom logo. However:
|
|
|
|
# - The given value is used as-is, thus it cannot be relative or a local file
|
|
|
|
# (unlike the non-custom case) since the generated docs have subfolders.
|
|
|
|
# - It requires adding it to every crate.
|
|
|
|
# - It requires changing `core` which comes from the sysroot.
|
|
|
|
#
|
|
|
|
# Using `-Zcrate-attr` would solve the last two points, but not the first.
|
|
|
|
# The https://github.com/rust-lang/rfcs/pull/3226 RFC suggests two new
|
|
|
|
# command-like flags to solve the issue. Meanwhile, we use the non-custom case
|
|
|
|
# and then retouch the generated files.
|
|
|
|
rustdoc: rustdoc-core rustdoc-macros rustdoc-compiler_builtins \
|
|
|
|
rustdoc-alloc rustdoc-kernel
|
2023-10-18 15:55:27 +00:00
|
|
|
$(Q)cp $(srctree)/Documentation/images/logo.svg $(rustdoc_output)/static.files/
|
|
|
|
$(Q)cp $(srctree)/Documentation/images/COPYING-logo $(rustdoc_output)/static.files/
|
2023-07-18 15:15:33 +00:00
|
|
|
$(Q)find $(rustdoc_output) -name '*.html' -type f -print0 | xargs -0 sed -Ei \
|
2023-10-18 15:55:27 +00:00
|
|
|
-e 's:rust-logo-[0-9a-f]+\.svg:logo.svg:g' \
|
|
|
|
-e 's:favicon-[0-9a-f]+\.svg:logo.svg:g' \
|
2023-12-15 23:54:28 +00:00
|
|
|
-e 's:<link rel="alternate icon" type="image/png" href="[/.]+/static\.files/favicon-(16x16|32x32)-[0-9a-f]+\.png">::g' \
|
2024-03-06 10:42:22 +00:00
|
|
|
-e 's:<a href="srctree/([^"]+)">:<a href="$(realpath $(srctree))/\1">:g'
|
2023-10-18 15:55:27 +00:00
|
|
|
$(Q)for f in $(rustdoc_output)/static.files/rustdoc-*.css; do \
|
|
|
|
echo ".logo-container > img { object-fit: contain; }" >> $$f; done
|
2021-07-03 14:42:57 +00:00
|
|
|
|
|
|
|
rustdoc-macros: private rustdoc_host = yes
|
|
|
|
rustdoc-macros: private rustc_target_flags = --crate-type proc-macro \
|
|
|
|
--extern proc_macro
|
|
|
|
rustdoc-macros: $(src)/macros/lib.rs FORCE
|
kbuild: mark `rustc` (and others) invocations as recursive
`rustc` (like Cargo) may take advantage of the jobserver at any time
(e.g. for backend parallelism, or eventually frontend too). In the kernel,
we call `rustc` with `-Ccodegen-units=1` (and `-Zthreads` is 1 so far),
so we do not expect parallelism. However, in the upcoming Rust 1.76.0, a
warning is emitted by `rustc` [1] when it cannot connect to the jobserver
it was passed (in many cases, but not all: compiling and `--print sysroot`
do, but `--version` does not). And given GNU Make always passes
the jobserver in the environment variable (even when a line is deemed
non-recursive), `rustc` will end up complaining about it (in particular
in Make 4.3 where there is only the simple pipe jobserver style).
One solution is to remove the jobserver from `MAKEFLAGS`. However, we
can mark the lines with calls to `rustc` (and Cargo) as recursive, which
looks simpler. This is being documented as a recommendation in `rustc`
[2] and allows us to be ready for the time we may use parallelism inside
`rustc` (potentially now, if a user passes `-Zthreads`). Thus do so.
Similarly, do the same for `rustdoc` and `cargo` calls.
Finally, there is one case that the solution does not cover, which is the
`$(shell ...)` call we have. Thus, for that one, set an empty `MAKEFLAGS`
environment variable.
Link: https://github.com/rust-lang/rust/issues/120515 [1]
Acked-by: Masahiro Yamada <masahiroy@kernel.org>
Link: https://github.com/rust-lang/rust/pull/121564 [2]
Link: https://lore.kernel.org/r/20240217002638.57373-1-ojeda@kernel.org
[ Reworded to add link to PR documenting the recommendation. ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2024-02-17 00:26:37 +00:00
|
|
|
+$(call if_changed,rustdoc)
|
2021-07-03 14:42:57 +00:00
|
|
|
|
|
|
|
rustdoc-core: private rustc_target_flags = $(core-cfgs)
|
|
|
|
rustdoc-core: $(RUST_LIB_SRC)/core/src/lib.rs FORCE
|
kbuild: mark `rustc` (and others) invocations as recursive
`rustc` (like Cargo) may take advantage of the jobserver at any time
(e.g. for backend parallelism, or eventually frontend too). In the kernel,
we call `rustc` with `-Ccodegen-units=1` (and `-Zthreads` is 1 so far),
so we do not expect parallelism. However, in the upcoming Rust 1.76.0, a
warning is emitted by `rustc` [1] when it cannot connect to the jobserver
it was passed (in many cases, but not all: compiling and `--print sysroot`
do, but `--version` does not). And given GNU Make always passes
the jobserver in the environment variable (even when a line is deemed
non-recursive), `rustc` will end up complaining about it (in particular
in Make 4.3 where there is only the simple pipe jobserver style).
One solution is to remove the jobserver from `MAKEFLAGS`. However, we
can mark the lines with calls to `rustc` (and Cargo) as recursive, which
looks simpler. This is being documented as a recommendation in `rustc`
[2] and allows us to be ready for the time we may use parallelism inside
`rustc` (potentially now, if a user passes `-Zthreads`). Thus do so.
Similarly, do the same for `rustdoc` and `cargo` calls.
Finally, there is one case that the solution does not cover, which is the
`$(shell ...)` call we have. Thus, for that one, set an empty `MAKEFLAGS`
environment variable.
Link: https://github.com/rust-lang/rust/issues/120515 [1]
Acked-by: Masahiro Yamada <masahiroy@kernel.org>
Link: https://github.com/rust-lang/rust/pull/121564 [2]
Link: https://lore.kernel.org/r/20240217002638.57373-1-ojeda@kernel.org
[ Reworded to add link to PR documenting the recommendation. ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2024-02-17 00:26:37 +00:00
|
|
|
+$(call if_changed,rustdoc)
|
2021-07-03 14:42:57 +00:00
|
|
|
|
|
|
|
rustdoc-compiler_builtins: $(src)/compiler_builtins.rs rustdoc-core FORCE
|
kbuild: mark `rustc` (and others) invocations as recursive
`rustc` (like Cargo) may take advantage of the jobserver at any time
(e.g. for backend parallelism, or eventually frontend too). In the kernel,
we call `rustc` with `-Ccodegen-units=1` (and `-Zthreads` is 1 so far),
so we do not expect parallelism. However, in the upcoming Rust 1.76.0, a
warning is emitted by `rustc` [1] when it cannot connect to the jobserver
it was passed (in many cases, but not all: compiling and `--print sysroot`
do, but `--version` does not). And given GNU Make always passes
the jobserver in the environment variable (even when a line is deemed
non-recursive), `rustc` will end up complaining about it (in particular
in Make 4.3 where there is only the simple pipe jobserver style).
One solution is to remove the jobserver from `MAKEFLAGS`. However, we
can mark the lines with calls to `rustc` (and Cargo) as recursive, which
looks simpler. This is being documented as a recommendation in `rustc`
[2] and allows us to be ready for the time we may use parallelism inside
`rustc` (potentially now, if a user passes `-Zthreads`). Thus do so.
Similarly, do the same for `rustdoc` and `cargo` calls.
Finally, there is one case that the solution does not cover, which is the
`$(shell ...)` call we have. Thus, for that one, set an empty `MAKEFLAGS`
environment variable.
Link: https://github.com/rust-lang/rust/issues/120515 [1]
Acked-by: Masahiro Yamada <masahiroy@kernel.org>
Link: https://github.com/rust-lang/rust/pull/121564 [2]
Link: https://lore.kernel.org/r/20240217002638.57373-1-ojeda@kernel.org
[ Reworded to add link to PR documenting the recommendation. ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2024-02-17 00:26:37 +00:00
|
|
|
+$(call if_changed,rustdoc)
|
2021-07-03 14:42:57 +00:00
|
|
|
|
|
|
|
# We need to allow `rustdoc::broken_intra_doc_links` because some
|
|
|
|
# `no_global_oom_handling` functions refer to non-`no_global_oom_handling`
|
|
|
|
# functions. Ideally `rustdoc` would have a way to distinguish broken links
|
|
|
|
# due to things that are "configured out" vs. entirely non-existing ones.
|
|
|
|
rustdoc-alloc: private rustc_target_flags = $(alloc-cfgs) \
|
|
|
|
-Arustdoc::broken_intra_doc_links
|
2024-03-28 01:35:56 +00:00
|
|
|
rustdoc-alloc: $(RUST_LIB_SRC)/alloc/src/lib.rs rustdoc-core rustdoc-compiler_builtins FORCE
|
kbuild: mark `rustc` (and others) invocations as recursive
`rustc` (like Cargo) may take advantage of the jobserver at any time
(e.g. for backend parallelism, or eventually frontend too). In the kernel,
we call `rustc` with `-Ccodegen-units=1` (and `-Zthreads` is 1 so far),
so we do not expect parallelism. However, in the upcoming Rust 1.76.0, a
warning is emitted by `rustc` [1] when it cannot connect to the jobserver
it was passed (in many cases, but not all: compiling and `--print sysroot`
do, but `--version` does not). And given GNU Make always passes
the jobserver in the environment variable (even when a line is deemed
non-recursive), `rustc` will end up complaining about it (in particular
in Make 4.3 where there is only the simple pipe jobserver style).
One solution is to remove the jobserver from `MAKEFLAGS`. However, we
can mark the lines with calls to `rustc` (and Cargo) as recursive, which
looks simpler. This is being documented as a recommendation in `rustc`
[2] and allows us to be ready for the time we may use parallelism inside
`rustc` (potentially now, if a user passes `-Zthreads`). Thus do so.
Similarly, do the same for `rustdoc` and `cargo` calls.
Finally, there is one case that the solution does not cover, which is the
`$(shell ...)` call we have. Thus, for that one, set an empty `MAKEFLAGS`
environment variable.
Link: https://github.com/rust-lang/rust/issues/120515 [1]
Acked-by: Masahiro Yamada <masahiroy@kernel.org>
Link: https://github.com/rust-lang/rust/pull/121564 [2]
Link: https://lore.kernel.org/r/20240217002638.57373-1-ojeda@kernel.org
[ Reworded to add link to PR documenting the recommendation. ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2024-02-17 00:26:37 +00:00
|
|
|
+$(call if_changed,rustdoc)
|
2021-07-03 14:42:57 +00:00
|
|
|
|
|
|
|
rustdoc-kernel: private rustc_target_flags = --extern alloc \
|
2022-11-10 16:41:37 +00:00
|
|
|
--extern build_error --extern macros=$(objtree)/$(obj)/libmacros.so \
|
2023-04-03 09:33:52 +00:00
|
|
|
--extern bindings --extern uapi
|
2021-07-03 14:42:57 +00:00
|
|
|
rustdoc-kernel: $(src)/kernel/lib.rs rustdoc-core rustdoc-macros \
|
|
|
|
rustdoc-compiler_builtins rustdoc-alloc $(obj)/libmacros.so \
|
|
|
|
$(obj)/bindings.o FORCE
|
kbuild: mark `rustc` (and others) invocations as recursive
`rustc` (like Cargo) may take advantage of the jobserver at any time
(e.g. for backend parallelism, or eventually frontend too). In the kernel,
we call `rustc` with `-Ccodegen-units=1` (and `-Zthreads` is 1 so far),
so we do not expect parallelism. However, in the upcoming Rust 1.76.0, a
warning is emitted by `rustc` [1] when it cannot connect to the jobserver
it was passed (in many cases, but not all: compiling and `--print sysroot`
do, but `--version` does not). And given GNU Make always passes
the jobserver in the environment variable (even when a line is deemed
non-recursive), `rustc` will end up complaining about it (in particular
in Make 4.3 where there is only the simple pipe jobserver style).
One solution is to remove the jobserver from `MAKEFLAGS`. However, we
can mark the lines with calls to `rustc` (and Cargo) as recursive, which
looks simpler. This is being documented as a recommendation in `rustc`
[2] and allows us to be ready for the time we may use parallelism inside
`rustc` (potentially now, if a user passes `-Zthreads`). Thus do so.
Similarly, do the same for `rustdoc` and `cargo` calls.
Finally, there is one case that the solution does not cover, which is the
`$(shell ...)` call we have. Thus, for that one, set an empty `MAKEFLAGS`
environment variable.
Link: https://github.com/rust-lang/rust/issues/120515 [1]
Acked-by: Masahiro Yamada <masahiroy@kernel.org>
Link: https://github.com/rust-lang/rust/pull/121564 [2]
Link: https://lore.kernel.org/r/20240217002638.57373-1-ojeda@kernel.org
[ Reworded to add link to PR documenting the recommendation. ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2024-02-17 00:26:37 +00:00
|
|
|
+$(call if_changed,rustdoc)
|
2021-07-03 14:42:57 +00:00
|
|
|
|
|
|
|
quiet_cmd_rustc_test_library = RUSTC TL $<
|
|
|
|
cmd_rustc_test_library = \
|
|
|
|
OBJTREE=$(abspath $(objtree)) \
|
|
|
|
$(RUSTC) $(rust_common_flags) \
|
|
|
|
@$(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 \
|
|
|
|
-L$(objtree)/$(obj)/test \
|
|
|
|
--crate-name $(subst rusttest-,,$(subst rusttestlib-,,$@)) $<
|
|
|
|
|
2024-05-28 16:35:02 +00:00
|
|
|
rusttestlib-build_error: $(src)/build_error.rs FORCE
|
kbuild: mark `rustc` (and others) invocations as recursive
`rustc` (like Cargo) may take advantage of the jobserver at any time
(e.g. for backend parallelism, or eventually frontend too). In the kernel,
we call `rustc` with `-Ccodegen-units=1` (and `-Zthreads` is 1 so far),
so we do not expect parallelism. However, in the upcoming Rust 1.76.0, a
warning is emitted by `rustc` [1] when it cannot connect to the jobserver
it was passed (in many cases, but not all: compiling and `--print sysroot`
do, but `--version` does not). And given GNU Make always passes
the jobserver in the environment variable (even when a line is deemed
non-recursive), `rustc` will end up complaining about it (in particular
in Make 4.3 where there is only the simple pipe jobserver style).
One solution is to remove the jobserver from `MAKEFLAGS`. However, we
can mark the lines with calls to `rustc` (and Cargo) as recursive, which
looks simpler. This is being documented as a recommendation in `rustc`
[2] and allows us to be ready for the time we may use parallelism inside
`rustc` (potentially now, if a user passes `-Zthreads`). Thus do so.
Similarly, do the same for `rustdoc` and `cargo` calls.
Finally, there is one case that the solution does not cover, which is the
`$(shell ...)` call we have. Thus, for that one, set an empty `MAKEFLAGS`
environment variable.
Link: https://github.com/rust-lang/rust/issues/120515 [1]
Acked-by: Masahiro Yamada <masahiroy@kernel.org>
Link: https://github.com/rust-lang/rust/pull/121564 [2]
Link: https://lore.kernel.org/r/20240217002638.57373-1-ojeda@kernel.org
[ Reworded to add link to PR documenting the recommendation. ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2024-02-17 00:26:37 +00:00
|
|
|
+$(call if_changed,rustc_test_library)
|
2022-11-10 16:41:37 +00:00
|
|
|
|
2021-07-03 14:42:57 +00:00
|
|
|
rusttestlib-macros: private rustc_target_flags = --extern proc_macro
|
|
|
|
rusttestlib-macros: private rustc_test_library_proc = yes
|
2024-05-28 16:35:02 +00:00
|
|
|
rusttestlib-macros: $(src)/macros/lib.rs FORCE
|
kbuild: mark `rustc` (and others) invocations as recursive
`rustc` (like Cargo) may take advantage of the jobserver at any time
(e.g. for backend parallelism, or eventually frontend too). In the kernel,
we call `rustc` with `-Ccodegen-units=1` (and `-Zthreads` is 1 so far),
so we do not expect parallelism. However, in the upcoming Rust 1.76.0, a
warning is emitted by `rustc` [1] when it cannot connect to the jobserver
it was passed (in many cases, but not all: compiling and `--print sysroot`
do, but `--version` does not). And given GNU Make always passes
the jobserver in the environment variable (even when a line is deemed
non-recursive), `rustc` will end up complaining about it (in particular
in Make 4.3 where there is only the simple pipe jobserver style).
One solution is to remove the jobserver from `MAKEFLAGS`. However, we
can mark the lines with calls to `rustc` (and Cargo) as recursive, which
looks simpler. This is being documented as a recommendation in `rustc`
[2] and allows us to be ready for the time we may use parallelism inside
`rustc` (potentially now, if a user passes `-Zthreads`). Thus do so.
Similarly, do the same for `rustdoc` and `cargo` calls.
Finally, there is one case that the solution does not cover, which is the
`$(shell ...)` call we have. Thus, for that one, set an empty `MAKEFLAGS`
environment variable.
Link: https://github.com/rust-lang/rust/issues/120515 [1]
Acked-by: Masahiro Yamada <masahiroy@kernel.org>
Link: https://github.com/rust-lang/rust/pull/121564 [2]
Link: https://lore.kernel.org/r/20240217002638.57373-1-ojeda@kernel.org
[ Reworded to add link to PR documenting the recommendation. ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2024-02-17 00:26:37 +00:00
|
|
|
+$(call if_changed,rustc_test_library)
|
2021-07-03 14:42:57 +00:00
|
|
|
|
2024-05-28 16:35:02 +00:00
|
|
|
rusttestlib-bindings: $(src)/bindings/lib.rs FORCE
|
kbuild: mark `rustc` (and others) invocations as recursive
`rustc` (like Cargo) may take advantage of the jobserver at any time
(e.g. for backend parallelism, or eventually frontend too). In the kernel,
we call `rustc` with `-Ccodegen-units=1` (and `-Zthreads` is 1 so far),
so we do not expect parallelism. However, in the upcoming Rust 1.76.0, a
warning is emitted by `rustc` [1] when it cannot connect to the jobserver
it was passed (in many cases, but not all: compiling and `--print sysroot`
do, but `--version` does not). And given GNU Make always passes
the jobserver in the environment variable (even when a line is deemed
non-recursive), `rustc` will end up complaining about it (in particular
in Make 4.3 where there is only the simple pipe jobserver style).
One solution is to remove the jobserver from `MAKEFLAGS`. However, we
can mark the lines with calls to `rustc` (and Cargo) as recursive, which
looks simpler. This is being documented as a recommendation in `rustc`
[2] and allows us to be ready for the time we may use parallelism inside
`rustc` (potentially now, if a user passes `-Zthreads`). Thus do so.
Similarly, do the same for `rustdoc` and `cargo` calls.
Finally, there is one case that the solution does not cover, which is the
`$(shell ...)` call we have. Thus, for that one, set an empty `MAKEFLAGS`
environment variable.
Link: https://github.com/rust-lang/rust/issues/120515 [1]
Acked-by: Masahiro Yamada <masahiroy@kernel.org>
Link: https://github.com/rust-lang/rust/pull/121564 [2]
Link: https://lore.kernel.org/r/20240217002638.57373-1-ojeda@kernel.org
[ Reworded to add link to PR documenting the recommendation. ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2024-02-17 00:26:37 +00:00
|
|
|
+$(call if_changed,rustc_test_library)
|
2021-07-03 14:42:57 +00:00
|
|
|
|
2024-05-28 16:35:02 +00:00
|
|
|
rusttestlib-uapi: $(src)/uapi/lib.rs FORCE
|
kbuild: mark `rustc` (and others) invocations as recursive
`rustc` (like Cargo) may take advantage of the jobserver at any time
(e.g. for backend parallelism, or eventually frontend too). In the kernel,
we call `rustc` with `-Ccodegen-units=1` (and `-Zthreads` is 1 so far),
so we do not expect parallelism. However, in the upcoming Rust 1.76.0, a
warning is emitted by `rustc` [1] when it cannot connect to the jobserver
it was passed (in many cases, but not all: compiling and `--print sysroot`
do, but `--version` does not). And given GNU Make always passes
the jobserver in the environment variable (even when a line is deemed
non-recursive), `rustc` will end up complaining about it (in particular
in Make 4.3 where there is only the simple pipe jobserver style).
One solution is to remove the jobserver from `MAKEFLAGS`. However, we
can mark the lines with calls to `rustc` (and Cargo) as recursive, which
looks simpler. This is being documented as a recommendation in `rustc`
[2] and allows us to be ready for the time we may use parallelism inside
`rustc` (potentially now, if a user passes `-Zthreads`). Thus do so.
Similarly, do the same for `rustdoc` and `cargo` calls.
Finally, there is one case that the solution does not cover, which is the
`$(shell ...)` call we have. Thus, for that one, set an empty `MAKEFLAGS`
environment variable.
Link: https://github.com/rust-lang/rust/issues/120515 [1]
Acked-by: Masahiro Yamada <masahiroy@kernel.org>
Link: https://github.com/rust-lang/rust/pull/121564 [2]
Link: https://lore.kernel.org/r/20240217002638.57373-1-ojeda@kernel.org
[ Reworded to add link to PR documenting the recommendation. ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2024-02-17 00:26:37 +00:00
|
|
|
+$(call if_changed,rustc_test_library)
|
2023-04-03 09:33:52 +00:00
|
|
|
|
2021-07-03 14:42:57 +00:00
|
|
|
quiet_cmd_rustdoc_test = RUSTDOC T $<
|
|
|
|
cmd_rustdoc_test = \
|
|
|
|
OBJTREE=$(abspath $(objtree)) \
|
|
|
|
$(RUSTDOC) --test $(rust_common_flags) \
|
|
|
|
@$(objtree)/include/generated/rustc_cfg \
|
|
|
|
$(rustc_target_flags) $(rustdoc_test_target_flags) \
|
2024-05-28 16:35:02 +00:00
|
|
|
$(rustdoc_test_quiet) \
|
2023-07-18 15:15:33 +00:00
|
|
|
-L$(objtree)/$(obj)/test --output $(rustdoc_output) \
|
2021-07-03 14:42:57 +00:00
|
|
|
--crate-name $(subst rusttest-,,$@) $<
|
|
|
|
|
rust: support running Rust documentation tests as KUnit ones
Rust has documentation tests: these are typically examples of
usage of any item (e.g. function, struct, module...).
They are very convenient because they are just written
alongside the documentation. For instance:
/// Sums two numbers.
///
/// ```
/// assert_eq!(mymod::f(10, 20), 30);
/// ```
pub fn f(a: i32, b: i32) -> i32 {
a + b
}
In userspace, the tests are collected and run via `rustdoc`.
Using the tool as-is would be useful already, since it allows
to compile-test most tests (thus enforcing they are kept
in sync with the code they document) and run those that do not
depend on in-kernel APIs.
However, by transforming the tests into a KUnit test suite,
they can also be run inside the kernel. Moreover, the tests
get to be compiled as other Rust kernel objects instead of
targeting userspace.
On top of that, the integration with KUnit means the Rust
support gets to reuse the existing testing facilities. For
instance, the kernel log would look like:
KTAP version 1
1..1
KTAP version 1
# Subtest: rust_doctests_kernel
1..59
# rust_doctest_kernel_build_assert_rs_0.location: rust/kernel/build_assert.rs:13
ok 1 rust_doctest_kernel_build_assert_rs_0
# rust_doctest_kernel_build_assert_rs_1.location: rust/kernel/build_assert.rs:56
ok 2 rust_doctest_kernel_build_assert_rs_1
# rust_doctest_kernel_init_rs_0.location: rust/kernel/init.rs:122
ok 3 rust_doctest_kernel_init_rs_0
...
# rust_doctest_kernel_types_rs_2.location: rust/kernel/types.rs:150
ok 59 rust_doctest_kernel_types_rs_2
# rust_doctests_kernel: pass:59 fail:0 skip:0 total:59
# Totals: pass:59 fail:0 skip:0 total:59
ok 1 rust_doctests_kernel
Therefore, add support for running Rust documentation tests
in KUnit. Some other notes about the current implementation
and support follow.
The transformation is performed by a couple scripts written
as Rust hostprogs.
Tests using the `?` operator are also supported as usual, e.g.:
/// ```
/// # use kernel::{spawn_work_item, workqueue};
/// spawn_work_item!(workqueue::system(), || pr_info!("x"))?;
/// # Ok::<(), Error>(())
/// ```
The tests are also compiled with Clippy under `CLIPPY=1`, just
like normal code, thus also benefitting from extra linting.
The names of the tests are currently automatically generated.
This allows to reduce the burden for documentation writers,
while keeping them fairly stable for bisection. This is an
improvement over the `rustdoc`-generated names, which include
the line number; but ideally we would like to get `rustdoc` to
provide the Rust item path and a number (for multiple examples
in a single documented Rust item).
In order for developers to easily see from which original line
a failed doctests came from, a KTAP diagnostic line is printed
to the log, containing the location (file and line) of the
original test (i.e. instead of the location in the generated
Rust file):
# rust_doctest_kernel_types_rs_2.location: rust/kernel/types.rs:150
This line follows the syntax for declaring test metadata in the
proposed KTAP v2 spec [1], which may be used for the proposed
KUnit test attributes API [2]. Thus hopefully this will make
migration easier later on (suggested by David [3]).
The original line in that test attribute is figured out by
providing an anchor (suggested by Boqun [4]). The original file
is found by walking the filesystem, checking directory prefixes
to reduce the amount of combinations to check, and it is only
done once per file. Ambiguities are detected and reported.
A notable difference from KUnit C tests is that the Rust tests
appear to assert using the usual `assert!` and `assert_eq!`
macros from the Rust standard library (`core`). We provide
a custom version that forwards the call to KUnit instead.
Importantly, these macros do not require passing context,
unlike the KUnit C ones (i.e. `struct kunit *`). This makes
them easier to use, and readers of the documentation do not need
to care about which testing framework is used. In addition, it
may allow us to test third-party code more easily in the future.
However, a current limitation is that KUnit does not support
assertions in other tasks. Thus we presently simply print an
error to the kernel log if an assertion actually failed. This
should be revisited to properly fail the test, perhaps saving
the context somewhere else, or letting KUnit handle it.
Link: https://lore.kernel.org/lkml/20230420205734.1288498-1-rmoar@google.com/ [1]
Link: https://lore.kernel.org/linux-kselftest/20230707210947.1208717-1-rmoar@google.com/ [2]
Link: https://lore.kernel.org/rust-for-linux/CABVgOSkOLO-8v6kdAGpmYnZUb+LKOX0CtYCo-Bge7r_2YTuXDQ@mail.gmail.com/ [3]
Link: https://lore.kernel.org/rust-for-linux/ZIps86MbJF%2FiGIzd@boqun-archlinux/ [4]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-07-18 05:27:51 +00:00
|
|
|
quiet_cmd_rustdoc_test_kernel = RUSTDOC TK $<
|
|
|
|
cmd_rustdoc_test_kernel = \
|
|
|
|
rm -rf $(objtree)/$(obj)/test/doctests/kernel; \
|
|
|
|
mkdir -p $(objtree)/$(obj)/test/doctests/kernel; \
|
|
|
|
OBJTREE=$(abspath $(objtree)) \
|
|
|
|
$(RUSTDOC) --test $(rust_flags) \
|
|
|
|
-L$(objtree)/$(obj) --extern alloc --extern kernel \
|
|
|
|
--extern build_error --extern macros \
|
|
|
|
--extern bindings --extern uapi \
|
|
|
|
--no-run --crate-name kernel -Zunstable-options \
|
2023-10-31 20:10:14 +00:00
|
|
|
--sysroot=/dev/null \
|
rust: support running Rust documentation tests as KUnit ones
Rust has documentation tests: these are typically examples of
usage of any item (e.g. function, struct, module...).
They are very convenient because they are just written
alongside the documentation. For instance:
/// Sums two numbers.
///
/// ```
/// assert_eq!(mymod::f(10, 20), 30);
/// ```
pub fn f(a: i32, b: i32) -> i32 {
a + b
}
In userspace, the tests are collected and run via `rustdoc`.
Using the tool as-is would be useful already, since it allows
to compile-test most tests (thus enforcing they are kept
in sync with the code they document) and run those that do not
depend on in-kernel APIs.
However, by transforming the tests into a KUnit test suite,
they can also be run inside the kernel. Moreover, the tests
get to be compiled as other Rust kernel objects instead of
targeting userspace.
On top of that, the integration with KUnit means the Rust
support gets to reuse the existing testing facilities. For
instance, the kernel log would look like:
KTAP version 1
1..1
KTAP version 1
# Subtest: rust_doctests_kernel
1..59
# rust_doctest_kernel_build_assert_rs_0.location: rust/kernel/build_assert.rs:13
ok 1 rust_doctest_kernel_build_assert_rs_0
# rust_doctest_kernel_build_assert_rs_1.location: rust/kernel/build_assert.rs:56
ok 2 rust_doctest_kernel_build_assert_rs_1
# rust_doctest_kernel_init_rs_0.location: rust/kernel/init.rs:122
ok 3 rust_doctest_kernel_init_rs_0
...
# rust_doctest_kernel_types_rs_2.location: rust/kernel/types.rs:150
ok 59 rust_doctest_kernel_types_rs_2
# rust_doctests_kernel: pass:59 fail:0 skip:0 total:59
# Totals: pass:59 fail:0 skip:0 total:59
ok 1 rust_doctests_kernel
Therefore, add support for running Rust documentation tests
in KUnit. Some other notes about the current implementation
and support follow.
The transformation is performed by a couple scripts written
as Rust hostprogs.
Tests using the `?` operator are also supported as usual, e.g.:
/// ```
/// # use kernel::{spawn_work_item, workqueue};
/// spawn_work_item!(workqueue::system(), || pr_info!("x"))?;
/// # Ok::<(), Error>(())
/// ```
The tests are also compiled with Clippy under `CLIPPY=1`, just
like normal code, thus also benefitting from extra linting.
The names of the tests are currently automatically generated.
This allows to reduce the burden for documentation writers,
while keeping them fairly stable for bisection. This is an
improvement over the `rustdoc`-generated names, which include
the line number; but ideally we would like to get `rustdoc` to
provide the Rust item path and a number (for multiple examples
in a single documented Rust item).
In order for developers to easily see from which original line
a failed doctests came from, a KTAP diagnostic line is printed
to the log, containing the location (file and line) of the
original test (i.e. instead of the location in the generated
Rust file):
# rust_doctest_kernel_types_rs_2.location: rust/kernel/types.rs:150
This line follows the syntax for declaring test metadata in the
proposed KTAP v2 spec [1], which may be used for the proposed
KUnit test attributes API [2]. Thus hopefully this will make
migration easier later on (suggested by David [3]).
The original line in that test attribute is figured out by
providing an anchor (suggested by Boqun [4]). The original file
is found by walking the filesystem, checking directory prefixes
to reduce the amount of combinations to check, and it is only
done once per file. Ambiguities are detected and reported.
A notable difference from KUnit C tests is that the Rust tests
appear to assert using the usual `assert!` and `assert_eq!`
macros from the Rust standard library (`core`). We provide
a custom version that forwards the call to KUnit instead.
Importantly, these macros do not require passing context,
unlike the KUnit C ones (i.e. `struct kunit *`). This makes
them easier to use, and readers of the documentation do not need
to care about which testing framework is used. In addition, it
may allow us to test third-party code more easily in the future.
However, a current limitation is that KUnit does not support
assertions in other tasks. Thus we presently simply print an
error to the kernel log if an assertion actually failed. This
should be revisited to properly fail the test, perhaps saving
the context somewhere else, or letting KUnit handle it.
Link: https://lore.kernel.org/lkml/20230420205734.1288498-1-rmoar@google.com/ [1]
Link: https://lore.kernel.org/linux-kselftest/20230707210947.1208717-1-rmoar@google.com/ [2]
Link: https://lore.kernel.org/rust-for-linux/CABVgOSkOLO-8v6kdAGpmYnZUb+LKOX0CtYCo-Bge7r_2YTuXDQ@mail.gmail.com/ [3]
Link: https://lore.kernel.org/rust-for-linux/ZIps86MbJF%2FiGIzd@boqun-archlinux/ [4]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-07-18 05:27:51 +00:00
|
|
|
--test-builder $(objtree)/scripts/rustdoc_test_builder \
|
|
|
|
$< $(rustdoc_test_kernel_quiet); \
|
|
|
|
$(objtree)/scripts/rustdoc_test_gen
|
|
|
|
|
|
|
|
%/doctests_kernel_generated.rs %/doctests_kernel_generated_kunit.c: \
|
|
|
|
$(src)/kernel/lib.rs $(obj)/kernel.o \
|
|
|
|
$(objtree)/scripts/rustdoc_test_builder \
|
|
|
|
$(objtree)/scripts/rustdoc_test_gen FORCE
|
kbuild: mark `rustc` (and others) invocations as recursive
`rustc` (like Cargo) may take advantage of the jobserver at any time
(e.g. for backend parallelism, or eventually frontend too). In the kernel,
we call `rustc` with `-Ccodegen-units=1` (and `-Zthreads` is 1 so far),
so we do not expect parallelism. However, in the upcoming Rust 1.76.0, a
warning is emitted by `rustc` [1] when it cannot connect to the jobserver
it was passed (in many cases, but not all: compiling and `--print sysroot`
do, but `--version` does not). And given GNU Make always passes
the jobserver in the environment variable (even when a line is deemed
non-recursive), `rustc` will end up complaining about it (in particular
in Make 4.3 where there is only the simple pipe jobserver style).
One solution is to remove the jobserver from `MAKEFLAGS`. However, we
can mark the lines with calls to `rustc` (and Cargo) as recursive, which
looks simpler. This is being documented as a recommendation in `rustc`
[2] and allows us to be ready for the time we may use parallelism inside
`rustc` (potentially now, if a user passes `-Zthreads`). Thus do so.
Similarly, do the same for `rustdoc` and `cargo` calls.
Finally, there is one case that the solution does not cover, which is the
`$(shell ...)` call we have. Thus, for that one, set an empty `MAKEFLAGS`
environment variable.
Link: https://github.com/rust-lang/rust/issues/120515 [1]
Acked-by: Masahiro Yamada <masahiroy@kernel.org>
Link: https://github.com/rust-lang/rust/pull/121564 [2]
Link: https://lore.kernel.org/r/20240217002638.57373-1-ojeda@kernel.org
[ Reworded to add link to PR documenting the recommendation. ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2024-02-17 00:26:37 +00:00
|
|
|
+$(call if_changed,rustdoc_test_kernel)
|
rust: support running Rust documentation tests as KUnit ones
Rust has documentation tests: these are typically examples of
usage of any item (e.g. function, struct, module...).
They are very convenient because they are just written
alongside the documentation. For instance:
/// Sums two numbers.
///
/// ```
/// assert_eq!(mymod::f(10, 20), 30);
/// ```
pub fn f(a: i32, b: i32) -> i32 {
a + b
}
In userspace, the tests are collected and run via `rustdoc`.
Using the tool as-is would be useful already, since it allows
to compile-test most tests (thus enforcing they are kept
in sync with the code they document) and run those that do not
depend on in-kernel APIs.
However, by transforming the tests into a KUnit test suite,
they can also be run inside the kernel. Moreover, the tests
get to be compiled as other Rust kernel objects instead of
targeting userspace.
On top of that, the integration with KUnit means the Rust
support gets to reuse the existing testing facilities. For
instance, the kernel log would look like:
KTAP version 1
1..1
KTAP version 1
# Subtest: rust_doctests_kernel
1..59
# rust_doctest_kernel_build_assert_rs_0.location: rust/kernel/build_assert.rs:13
ok 1 rust_doctest_kernel_build_assert_rs_0
# rust_doctest_kernel_build_assert_rs_1.location: rust/kernel/build_assert.rs:56
ok 2 rust_doctest_kernel_build_assert_rs_1
# rust_doctest_kernel_init_rs_0.location: rust/kernel/init.rs:122
ok 3 rust_doctest_kernel_init_rs_0
...
# rust_doctest_kernel_types_rs_2.location: rust/kernel/types.rs:150
ok 59 rust_doctest_kernel_types_rs_2
# rust_doctests_kernel: pass:59 fail:0 skip:0 total:59
# Totals: pass:59 fail:0 skip:0 total:59
ok 1 rust_doctests_kernel
Therefore, add support for running Rust documentation tests
in KUnit. Some other notes about the current implementation
and support follow.
The transformation is performed by a couple scripts written
as Rust hostprogs.
Tests using the `?` operator are also supported as usual, e.g.:
/// ```
/// # use kernel::{spawn_work_item, workqueue};
/// spawn_work_item!(workqueue::system(), || pr_info!("x"))?;
/// # Ok::<(), Error>(())
/// ```
The tests are also compiled with Clippy under `CLIPPY=1`, just
like normal code, thus also benefitting from extra linting.
The names of the tests are currently automatically generated.
This allows to reduce the burden for documentation writers,
while keeping them fairly stable for bisection. This is an
improvement over the `rustdoc`-generated names, which include
the line number; but ideally we would like to get `rustdoc` to
provide the Rust item path and a number (for multiple examples
in a single documented Rust item).
In order for developers to easily see from which original line
a failed doctests came from, a KTAP diagnostic line is printed
to the log, containing the location (file and line) of the
original test (i.e. instead of the location in the generated
Rust file):
# rust_doctest_kernel_types_rs_2.location: rust/kernel/types.rs:150
This line follows the syntax for declaring test metadata in the
proposed KTAP v2 spec [1], which may be used for the proposed
KUnit test attributes API [2]. Thus hopefully this will make
migration easier later on (suggested by David [3]).
The original line in that test attribute is figured out by
providing an anchor (suggested by Boqun [4]). The original file
is found by walking the filesystem, checking directory prefixes
to reduce the amount of combinations to check, and it is only
done once per file. Ambiguities are detected and reported.
A notable difference from KUnit C tests is that the Rust tests
appear to assert using the usual `assert!` and `assert_eq!`
macros from the Rust standard library (`core`). We provide
a custom version that forwards the call to KUnit instead.
Importantly, these macros do not require passing context,
unlike the KUnit C ones (i.e. `struct kunit *`). This makes
them easier to use, and readers of the documentation do not need
to care about which testing framework is used. In addition, it
may allow us to test third-party code more easily in the future.
However, a current limitation is that KUnit does not support
assertions in other tasks. Thus we presently simply print an
error to the kernel log if an assertion actually failed. This
should be revisited to properly fail the test, perhaps saving
the context somewhere else, or letting KUnit handle it.
Link: https://lore.kernel.org/lkml/20230420205734.1288498-1-rmoar@google.com/ [1]
Link: https://lore.kernel.org/linux-kselftest/20230707210947.1208717-1-rmoar@google.com/ [2]
Link: https://lore.kernel.org/rust-for-linux/CABVgOSkOLO-8v6kdAGpmYnZUb+LKOX0CtYCo-Bge7r_2YTuXDQ@mail.gmail.com/ [3]
Link: https://lore.kernel.org/rust-for-linux/ZIps86MbJF%2FiGIzd@boqun-archlinux/ [4]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-07-18 05:27:51 +00:00
|
|
|
|
2021-07-03 14:42:57 +00:00
|
|
|
# We cannot use `-Zpanic-abort-tests` because some tests are dynamic,
|
|
|
|
# so for the moment we skip `-Cpanic=abort`.
|
|
|
|
quiet_cmd_rustc_test = RUSTC T $<
|
|
|
|
cmd_rustc_test = \
|
|
|
|
OBJTREE=$(abspath $(objtree)) \
|
|
|
|
$(RUSTC) --test $(rust_common_flags) \
|
|
|
|
@$(objtree)/include/generated/rustc_cfg \
|
|
|
|
$(rustc_target_flags) --out-dir $(objtree)/$(obj)/test \
|
|
|
|
-L$(objtree)/$(obj)/test \
|
|
|
|
--crate-name $(subst rusttest-,,$@) $<; \
|
|
|
|
$(objtree)/$(obj)/test/$(subst rusttest-,,$@) $(rust_test_quiet) \
|
|
|
|
$(rustc_test_run_flags)
|
|
|
|
|
|
|
|
rusttest: rusttest-macros rusttest-kernel
|
|
|
|
|
|
|
|
rusttest-macros: private rustc_target_flags = --extern proc_macro
|
|
|
|
rusttest-macros: private rustdoc_test_target_flags = --crate-type proc-macro
|
2024-05-28 16:35:02 +00:00
|
|
|
rusttest-macros: $(src)/macros/lib.rs FORCE
|
kbuild: mark `rustc` (and others) invocations as recursive
`rustc` (like Cargo) may take advantage of the jobserver at any time
(e.g. for backend parallelism, or eventually frontend too). In the kernel,
we call `rustc` with `-Ccodegen-units=1` (and `-Zthreads` is 1 so far),
so we do not expect parallelism. However, in the upcoming Rust 1.76.0, a
warning is emitted by `rustc` [1] when it cannot connect to the jobserver
it was passed (in many cases, but not all: compiling and `--print sysroot`
do, but `--version` does not). And given GNU Make always passes
the jobserver in the environment variable (even when a line is deemed
non-recursive), `rustc` will end up complaining about it (in particular
in Make 4.3 where there is only the simple pipe jobserver style).
One solution is to remove the jobserver from `MAKEFLAGS`. However, we
can mark the lines with calls to `rustc` (and Cargo) as recursive, which
looks simpler. This is being documented as a recommendation in `rustc`
[2] and allows us to be ready for the time we may use parallelism inside
`rustc` (potentially now, if a user passes `-Zthreads`). Thus do so.
Similarly, do the same for `rustdoc` and `cargo` calls.
Finally, there is one case that the solution does not cover, which is the
`$(shell ...)` call we have. Thus, for that one, set an empty `MAKEFLAGS`
environment variable.
Link: https://github.com/rust-lang/rust/issues/120515 [1]
Acked-by: Masahiro Yamada <masahiroy@kernel.org>
Link: https://github.com/rust-lang/rust/pull/121564 [2]
Link: https://lore.kernel.org/r/20240217002638.57373-1-ojeda@kernel.org
[ Reworded to add link to PR documenting the recommendation. ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2024-02-17 00:26:37 +00:00
|
|
|
+$(call if_changed,rustc_test)
|
|
|
|
+$(call if_changed,rustdoc_test)
|
2021-07-03 14:42:57 +00:00
|
|
|
|
|
|
|
rusttest-kernel: private rustc_target_flags = --extern alloc \
|
2023-04-03 09:33:52 +00:00
|
|
|
--extern build_error --extern macros --extern bindings --extern uapi
|
2024-05-28 16:35:02 +00:00
|
|
|
rusttest-kernel: $(src)/kernel/lib.rs \
|
2023-04-03 09:33:52 +00:00
|
|
|
rusttestlib-build_error rusttestlib-macros rusttestlib-bindings \
|
|
|
|
rusttestlib-uapi FORCE
|
kbuild: mark `rustc` (and others) invocations as recursive
`rustc` (like Cargo) may take advantage of the jobserver at any time
(e.g. for backend parallelism, or eventually frontend too). In the kernel,
we call `rustc` with `-Ccodegen-units=1` (and `-Zthreads` is 1 so far),
so we do not expect parallelism. However, in the upcoming Rust 1.76.0, a
warning is emitted by `rustc` [1] when it cannot connect to the jobserver
it was passed (in many cases, but not all: compiling and `--print sysroot`
do, but `--version` does not). And given GNU Make always passes
the jobserver in the environment variable (even when a line is deemed
non-recursive), `rustc` will end up complaining about it (in particular
in Make 4.3 where there is only the simple pipe jobserver style).
One solution is to remove the jobserver from `MAKEFLAGS`. However, we
can mark the lines with calls to `rustc` (and Cargo) as recursive, which
looks simpler. This is being documented as a recommendation in `rustc`
[2] and allows us to be ready for the time we may use parallelism inside
`rustc` (potentially now, if a user passes `-Zthreads`). Thus do so.
Similarly, do the same for `rustdoc` and `cargo` calls.
Finally, there is one case that the solution does not cover, which is the
`$(shell ...)` call we have. Thus, for that one, set an empty `MAKEFLAGS`
environment variable.
Link: https://github.com/rust-lang/rust/issues/120515 [1]
Acked-by: Masahiro Yamada <masahiroy@kernel.org>
Link: https://github.com/rust-lang/rust/pull/121564 [2]
Link: https://lore.kernel.org/r/20240217002638.57373-1-ojeda@kernel.org
[ Reworded to add link to PR documenting the recommendation. ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2024-02-17 00:26:37 +00:00
|
|
|
+$(call if_changed,rustc_test)
|
|
|
|
+$(call if_changed,rustc_test_library)
|
2021-07-03 14:42:57 +00:00
|
|
|
|
|
|
|
ifdef CONFIG_CC_IS_CLANG
|
|
|
|
bindgen_c_flags = $(c_flags)
|
|
|
|
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. 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 \
|
|
|
|
-mfunction-return=thunk-extern -mrecord-mcount -mabi=lp64 \
|
|
|
|
-mindirect-branch-cs-prefix -mstack-protector-guard% -mtraceback=no \
|
|
|
|
-mno-pointers-to-nested-functions -mno-string \
|
|
|
|
-mno-strict-align -mstrict-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=% \
|
|
|
|
-fzero-call-used-regs=% -fno-stack-clash-protection \
|
2023-07-11 07:19:14 +00:00
|
|
|
-fno-inline-functions-called-once -fsanitize=bounds-strict \
|
2024-07-31 13:43:46 +00:00
|
|
|
-fstrict-flex-arrays=% -fmin-function-alignment=% \
|
2021-07-03 14:42:57 +00:00
|
|
|
--param=% --param asan-%
|
|
|
|
|
|
|
|
# Derived from `scripts/Makefile.clang`.
|
|
|
|
BINDGEN_TARGET_x86 := x86_64-linux-gnu
|
2023-10-20 15:50:56 +00:00
|
|
|
BINDGEN_TARGET_arm64 := aarch64-linux-gnu
|
2021-07-03 14:42:57 +00:00
|
|
|
BINDGEN_TARGET := $(BINDGEN_TARGET_$(SRCARCH))
|
|
|
|
|
|
|
|
# All warnings are inhibited since GCC builds are very experimental,
|
|
|
|
# many GCC warnings are not supported by Clang, they may only appear in
|
|
|
|
# some configurations, with new GCC versions, etc.
|
|
|
|
bindgen_extra_c_flags = -w --target=$(BINDGEN_TARGET)
|
|
|
|
|
2023-02-10 21:51:41 +00:00
|
|
|
# Auto variable zero-initialization requires an additional special option with
|
|
|
|
# clang that is going to be removed sometime in the future (likely in
|
|
|
|
# clang-18), so make sure to pass this option only if clang supports it
|
|
|
|
# (libclang major version < 16).
|
|
|
|
#
|
|
|
|
# https://github.com/llvm/llvm-project/issues/44842
|
|
|
|
# https://github.com/llvm/llvm-project/blob/llvmorg-16.0.0-rc2/clang/docs/ReleaseNotes.rst#deprecated-compiler-flags
|
|
|
|
ifdef CONFIG_INIT_STACK_ALL_ZERO
|
|
|
|
libclang_maj_ver=$(shell $(BINDGEN) $(srctree)/scripts/rust_is_available_bindgen_libclang.h 2>&1 | sed -ne 's/.*clang version \([0-9]*\).*/\1/p')
|
|
|
|
ifeq ($(shell expr $(libclang_maj_ver) \< 16), 1)
|
|
|
|
bindgen_extra_c_flags += -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang
|
|
|
|
endif
|
|
|
|
endif
|
|
|
|
|
2021-07-03 14:42:57 +00:00
|
|
|
bindgen_c_flags = $(filter-out $(bindgen_skip_c_flags), $(c_flags)) \
|
|
|
|
$(bindgen_extra_c_flags)
|
|
|
|
endif
|
|
|
|
|
|
|
|
ifdef CONFIG_LTO
|
|
|
|
bindgen_c_flags_lto = $(filter-out $(CC_FLAGS_LTO), $(bindgen_c_flags))
|
|
|
|
else
|
|
|
|
bindgen_c_flags_lto = $(bindgen_c_flags)
|
|
|
|
endif
|
|
|
|
|
|
|
|
bindgen_c_flags_final = $(bindgen_c_flags_lto) -D__BINDGEN__
|
|
|
|
|
|
|
|
quiet_cmd_bindgen = BINDGEN $@
|
|
|
|
cmd_bindgen = \
|
|
|
|
$(BINDGEN) $< $(bindgen_target_flags) \
|
|
|
|
--use-core --with-derive-default --ctypes-prefix core::ffi --no-layout-tests \
|
rust: enable bindgen's `--enable-function-attribute-detection` flag
`bindgen` is able to detect certain function attributes and annotate
functions correspondingly in its output for the Rust side, when the
`--enable-function-attribute-detection` is passed.
In particular, it is currently able to use `__must_check` in C
(`#[must_use]` in Rust), which give us a bunch of annotations that are
nice to have to prevent possible issues in Rust abstractions, e.g.:
extern "C" {
+ #[must_use]
pub fn kobject_add(
kobj: *mut kobject,
parent: *mut kobject,
fmt: *const core::ffi::c_char,
...
) -> core::ffi::c_int;
}
Apparently, there are edge cases where this can make generation very slow,
which is why it is behind a flag [1], but it does not seem to affect us
in any major way at the moment.
Thus enable it.
Link: https://github.com/rust-lang/rust-bindgen/issues/1465 [1]
Link: https://lore.kernel.org/rust-for-linux/CANiq72=u5Nrz_NW3U3_VqywJkD8pECA07q2pFDd1wjtXOWdkAQ@mail.gmail.com/
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Tested-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Gary Guo <gary@garyguo.net>
Acked-by: Danilo Krummrich <dakr@kernel.org>
Link: https://lore.kernel.org/r/20240814163722.1550064-1-ojeda@kernel.org
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2024-08-14 16:37:22 +00:00
|
|
|
--no-debug '.*' --enable-function-attribute-detection \
|
rust: bindgen: upgrade to 0.65.1
In LLVM 16, anonymous items may return names like `(unnamed union at ..)`
rather than empty names [1], which breaks Rust-enabled builds because
bindgen assumed an empty name instead of detecting them via
`clang_Cursor_isAnonymous` [2]:
$ make rustdoc LLVM=1 CLIPPY=1 -j$(nproc)
RUSTC L rust/core.o
BINDGEN rust/bindings/bindings_generated.rs
BINDGEN rust/bindings/bindings_helpers_generated.rs
BINDGEN rust/uapi/uapi_generated.rs
thread 'main' panicked at '"ftrace_branch_data_union_(anonymous_at__/_/include/linux/compiler_types_h_146_2)" is not a valid Ident', .../proc-macro2-1.0.24/src/fallback.rs:693:9
...
thread 'main' panicked at '"ftrace_branch_data_union_(anonymous_at__/_/include/linux/compiler_types_h_146_2)" is not a valid Ident', .../proc-macro2-1.0.24/src/fallback.rs:693:9
...
This was fixed in bindgen 0.62.0. Therefore, upgrade bindgen to
a more recent version, 0.65.1, to support LLVM 16.
Since bindgen 0.58.0 changed the `--{white,black}list-*` flags to
`--{allow,block}list-*` [3], update them on our side too.
In addition, bindgen 0.61.0 moved its CLI utility into a binary crate
called `bindgen-cli` [4]. Thus update the installation command in the
Quick Start guide.
Moreover, bindgen 0.61.0 changed the default functionality to bind
`size_t` to `usize` [5] and added the `--no-size_t-is-usize` flag
to not bind `size_t` as `usize`. Then bindgen 0.65.0 removed
the `--size_t-is-usize` flag [6]. Thus stop passing the flag to bindgen.
Finally, bindgen 0.61.0 added support for the `noreturn` attribute (in
its different forms) [7]. Thus remove the infinite loop in our Rust
panic handler after calling `BUG()`, since bindgen now correctly
generates a `BUG()` binding that returns `!` instead of `()`.
Link: https://github.com/llvm/llvm-project/commit/19e984ef8f49bc3ccced15621989fa9703b2cd5b [1]
Link: https://github.com/rust-lang/rust-bindgen/pull/2319 [2]
Link: https://github.com/rust-lang/rust-bindgen/pull/1990 [3]
Link: https://github.com/rust-lang/rust-bindgen/pull/2284 [4]
Link: https://github.com/rust-lang/rust-bindgen/commit/cc78b6fdb6e829e5fb8fa1639f2182cb49333569 [5]
Link: https://github.com/rust-lang/rust-bindgen/pull/2408 [6]
Link: https://github.com/rust-lang/rust-bindgen/issues/2094 [7]
Signed-off-by: Aakash Sen Sharma <aakashsensharma@gmail.com>
Closes: https://github.com/Rust-for-Linux/linux/issues/1013
Tested-by: Ariel Miculas <amiculas@cisco.com>
Reviewed-by: Gary Guo <gary@garyguo.net>
Link: https://lore.kernel.org/r/20230612194311.24826-1-aakashsensharma@gmail.com
[ Reworded commit message. Mentioned the `bindgen-cli` binary crate
change, linked to it and updated the Quick Start guide. Re-added a
deleted "as" word in a code comment and reflowed comment to respect
the maximum length. ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2023-06-12 19:43:11 +00:00
|
|
|
-o $@ -- $(bindgen_c_flags_final) -DMODULE \
|
2021-07-03 14:42:57 +00:00
|
|
|
$(bindgen_target_cflags) $(bindgen_target_extra)
|
|
|
|
|
|
|
|
$(obj)/bindings/bindings_generated.rs: private bindgen_target_flags = \
|
kbuild: use $(src) instead of $(srctree)/$(src) for source directory
Kbuild conventionally uses $(obj)/ for generated files, and $(src)/ for
checked-in source files. It is merely a convention without any functional
difference. In fact, $(obj) and $(src) are exactly the same, as defined
in scripts/Makefile.build:
src := $(obj)
When the kernel is built in a separate output directory, $(src) does
not accurately reflect the source directory location. While Kbuild
resolves this discrepancy by specifying VPATH=$(srctree) to search for
source files, it does not cover all cases. For example, when adding a
header search path for local headers, -I$(srctree)/$(src) is typically
passed to the compiler.
This introduces inconsistency between upstream and downstream Makefiles
because $(src) is used instead of $(srctree)/$(src) for the latter.
To address this inconsistency, this commit changes the semantics of
$(src) so that it always points to the directory in the source tree.
Going forward, the variables used in Makefiles will have the following
meanings:
$(obj) - directory in the object tree
$(src) - directory in the source tree (changed by this commit)
$(objtree) - the top of the kernel object tree
$(srctree) - the top of the kernel source tree
Consequently, $(srctree)/$(src) in upstream Makefiles need to be replaced
with $(src).
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Reviewed-by: Nicolas Schier <nicolas@fjasle.eu>
2024-04-27 14:55:02 +00:00
|
|
|
$(shell grep -Ev '^#|^$$' $(src)/bindgen_parameters)
|
2023-11-04 14:56:56 +00:00
|
|
|
$(obj)/bindings/bindings_generated.rs: private bindgen_target_extra = ; \
|
|
|
|
sed -Ei 's/pub const RUST_CONST_HELPER_([a-zA-Z0-9_]*)/pub const \1/g' $@
|
2021-07-03 14:42:57 +00:00
|
|
|
$(obj)/bindings/bindings_generated.rs: $(src)/bindings/bindings_helper.h \
|
|
|
|
$(src)/bindgen_parameters FORCE
|
|
|
|
$(call if_changed_dep,bindgen)
|
|
|
|
|
2023-04-03 09:33:52 +00:00
|
|
|
$(obj)/uapi/uapi_generated.rs: private bindgen_target_flags = \
|
kbuild: use $(src) instead of $(srctree)/$(src) for source directory
Kbuild conventionally uses $(obj)/ for generated files, and $(src)/ for
checked-in source files. It is merely a convention without any functional
difference. In fact, $(obj) and $(src) are exactly the same, as defined
in scripts/Makefile.build:
src := $(obj)
When the kernel is built in a separate output directory, $(src) does
not accurately reflect the source directory location. While Kbuild
resolves this discrepancy by specifying VPATH=$(srctree) to search for
source files, it does not cover all cases. For example, when adding a
header search path for local headers, -I$(srctree)/$(src) is typically
passed to the compiler.
This introduces inconsistency between upstream and downstream Makefiles
because $(src) is used instead of $(srctree)/$(src) for the latter.
To address this inconsistency, this commit changes the semantics of
$(src) so that it always points to the directory in the source tree.
Going forward, the variables used in Makefiles will have the following
meanings:
$(obj) - directory in the object tree
$(src) - directory in the source tree (changed by this commit)
$(objtree) - the top of the kernel object tree
$(srctree) - the top of the kernel source tree
Consequently, $(srctree)/$(src) in upstream Makefiles need to be replaced
with $(src).
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Reviewed-by: Nicolas Schier <nicolas@fjasle.eu>
2024-04-27 14:55:02 +00:00
|
|
|
$(shell grep -Ev '^#|^$$' $(src)/bindgen_parameters)
|
2023-04-03 09:33:52 +00:00
|
|
|
$(obj)/uapi/uapi_generated.rs: $(src)/uapi/uapi_helper.h \
|
|
|
|
$(src)/bindgen_parameters FORCE
|
|
|
|
$(call if_changed_dep,bindgen)
|
|
|
|
|
2021-07-03 14:42:57 +00:00
|
|
|
# See `CFLAGS_REMOVE_helpers.o` above. In addition, Clang on C does not warn
|
|
|
|
# with `-Wmissing-declarations` (unlike GCC), so it is not strictly needed here
|
|
|
|
# given it is `libclang`; but for consistency, future Clang changes and/or
|
|
|
|
# a potential future GCC backend for `bindgen`, we disable it too.
|
|
|
|
$(obj)/bindings/bindings_helpers_generated.rs: private bindgen_target_flags = \
|
rust: bindgen: upgrade to 0.65.1
In LLVM 16, anonymous items may return names like `(unnamed union at ..)`
rather than empty names [1], which breaks Rust-enabled builds because
bindgen assumed an empty name instead of detecting them via
`clang_Cursor_isAnonymous` [2]:
$ make rustdoc LLVM=1 CLIPPY=1 -j$(nproc)
RUSTC L rust/core.o
BINDGEN rust/bindings/bindings_generated.rs
BINDGEN rust/bindings/bindings_helpers_generated.rs
BINDGEN rust/uapi/uapi_generated.rs
thread 'main' panicked at '"ftrace_branch_data_union_(anonymous_at__/_/include/linux/compiler_types_h_146_2)" is not a valid Ident', .../proc-macro2-1.0.24/src/fallback.rs:693:9
...
thread 'main' panicked at '"ftrace_branch_data_union_(anonymous_at__/_/include/linux/compiler_types_h_146_2)" is not a valid Ident', .../proc-macro2-1.0.24/src/fallback.rs:693:9
...
This was fixed in bindgen 0.62.0. Therefore, upgrade bindgen to
a more recent version, 0.65.1, to support LLVM 16.
Since bindgen 0.58.0 changed the `--{white,black}list-*` flags to
`--{allow,block}list-*` [3], update them on our side too.
In addition, bindgen 0.61.0 moved its CLI utility into a binary crate
called `bindgen-cli` [4]. Thus update the installation command in the
Quick Start guide.
Moreover, bindgen 0.61.0 changed the default functionality to bind
`size_t` to `usize` [5] and added the `--no-size_t-is-usize` flag
to not bind `size_t` as `usize`. Then bindgen 0.65.0 removed
the `--size_t-is-usize` flag [6]. Thus stop passing the flag to bindgen.
Finally, bindgen 0.61.0 added support for the `noreturn` attribute (in
its different forms) [7]. Thus remove the infinite loop in our Rust
panic handler after calling `BUG()`, since bindgen now correctly
generates a `BUG()` binding that returns `!` instead of `()`.
Link: https://github.com/llvm/llvm-project/commit/19e984ef8f49bc3ccced15621989fa9703b2cd5b [1]
Link: https://github.com/rust-lang/rust-bindgen/pull/2319 [2]
Link: https://github.com/rust-lang/rust-bindgen/pull/1990 [3]
Link: https://github.com/rust-lang/rust-bindgen/pull/2284 [4]
Link: https://github.com/rust-lang/rust-bindgen/commit/cc78b6fdb6e829e5fb8fa1639f2182cb49333569 [5]
Link: https://github.com/rust-lang/rust-bindgen/pull/2408 [6]
Link: https://github.com/rust-lang/rust-bindgen/issues/2094 [7]
Signed-off-by: Aakash Sen Sharma <aakashsensharma@gmail.com>
Closes: https://github.com/Rust-for-Linux/linux/issues/1013
Tested-by: Ariel Miculas <amiculas@cisco.com>
Reviewed-by: Gary Guo <gary@garyguo.net>
Link: https://lore.kernel.org/r/20230612194311.24826-1-aakashsensharma@gmail.com
[ Reworded commit message. Mentioned the `bindgen-cli` binary crate
change, linked to it and updated the Quick Start guide. Re-added a
deleted "as" word in a code comment and reflowed comment to respect
the maximum length. ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2023-06-12 19:43:11 +00:00
|
|
|
--blocklist-type '.*' --allowlist-var '' \
|
|
|
|
--allowlist-function 'rust_helper_.*'
|
2021-07-03 14:42:57 +00:00
|
|
|
$(obj)/bindings/bindings_helpers_generated.rs: private bindgen_target_cflags = \
|
|
|
|
-I$(objtree)/$(obj) -Wno-missing-prototypes -Wno-missing-declarations
|
|
|
|
$(obj)/bindings/bindings_helpers_generated.rs: private bindgen_target_extra = ; \
|
|
|
|
sed -Ei 's/pub fn rust_helper_([a-zA-Z0-9_]*)/#[link_name="rust_helper_\1"]\n pub fn \1/g' $@
|
2024-08-15 10:30:26 +00:00
|
|
|
$(obj)/bindings/bindings_helpers_generated.rs: $(src)/helpers/helpers.c FORCE
|
2021-07-03 14:42:57 +00:00
|
|
|
$(call if_changed_dep,bindgen)
|
|
|
|
|
|
|
|
quiet_cmd_exports = EXPORTS $@
|
|
|
|
cmd_exports = \
|
|
|
|
$(NM) -p --defined-only $< \
|
Rust changes for v6.12
Toolchain and infrastructure:
- Support 'MITIGATION_{RETHUNK,RETPOLINE,SLS}' (which cleans up objtool
warnings), teach objtool about 'noreturn' Rust symbols and mimic
'___ADDRESSABLE()' for 'module_{init,exit}'. With that, we should be
objtool-warning-free, so enable it to run for all Rust object files.
- KASAN (no 'SW_TAGS'), KCFI and shadow call sanitizer support.
- Support 'RUSTC_VERSION', including re-config and re-build on change.
- Split helpers file into several files in a folder, to avoid conflicts
in it. Eventually those files will be moved to the right places with
the new build system. In addition, remove the need to manually export
the symbols defined there, reusing existing machinery for that.
- Relax restriction on configurations with Rust + GCC plugins to just
the RANDSTRUCT plugin.
'kernel' crate:
- New 'list' module: doubly-linked linked list for use with reference
counted values, which is heavily used by the upcoming Rust Binder.
This includes 'ListArc' (a wrapper around 'Arc' that is guaranteed
unique for the given ID), 'AtomicTracker' (tracks whether a 'ListArc'
exists using an atomic), 'ListLinks' (the prev/next pointers for an
item in a linked list), 'List' (the linked list itself), 'Iter' (an
iterator over a 'List'), 'Cursor' (a cursor into a 'List' that allows
to remove elements), 'ListArcField' (a field exclusively owned by a
'ListArc'), as well as support for heterogeneous lists.
- New 'rbtree' module: red-black tree abstractions used by the upcoming
Rust Binder. This includes 'RBTree' (the red-black tree itself),
'RBTreeNode' (a node), 'RBTreeNodeReservation' (a memory reservation
for a node), 'Iter' and 'IterMut' (immutable and mutable iterators),
'Cursor' (bidirectional cursor that allows to remove elements), as
well as an entry API similar to the Rust standard library one.
- 'init' module: add 'write_[pin_]init' methods and the 'InPlaceWrite'
trait. Add the 'assert_pinned!' macro.
- 'sync' module: implement the 'InPlaceInit' trait for 'Arc' by
introducing an associated type in the trait.
- 'alloc' module: add 'drop_contents' method to 'BoxExt'.
- 'types' module: implement the 'ForeignOwnable' trait for
'Pin<Box<T>>' and improve the trait's documentation. In addition,
add the 'into_raw' method to the 'ARef' type.
- 'error' module: in preparation for the upcoming Rust support for
32-bit architectures, like arm, locally allow Clippy lint for those.
Documentation:
- https://rust.docs.kernel.org has been announced, so link to it.
- Enable rustdoc's "jump to definition" feature, making its output a
bit closer to the experience in a cross-referencer.
- Debian Testing now also provides recent Rust releases (outside of
the freeze period), so add it to the list.
MAINTAINERS:
- Trevor is joining as reviewer of the "RUST" entry.
And a few other small bits.
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEEPjU5OPd5QIZ9jqqOGXyLc2htIW0FAmbzNz4ACgkQGXyLc2ht
IW3muA/9HcPL0QqVB5+SqSRqcatmrFU/wq8Oaa6Z/No0JaynqyikK+R1WNokUd/5
WpQi4PC1OYV+ekyAuWdkooKmaSqagH5r53XlezNw+cM5zo8y7p0otVlbepQ0t3Ky
pVEmfDRIeSFXsKrg91BJUKyJf70TQlgSggDVCExlanfOjPz88C1+s3EcJ/XWYGKQ
cRk/XDdbF5eNaldp2MriVF0fw7XktgIrmVzxt/z0lb4PE7RaCAnO6gSQI+90Vb2d
zvyOYKS4AkqE3suFvDIIUlPUv+8XbACj0c4wvBZHH5uZGTbgWUffqygJ45GqChEt
c4fS/+E8VaM1z0EvxNczC0nQkfLwkTc1mgbP+sG3VZJMPVCJ2zQan1/ond7GqCpw
pt6uQaGvDsAvllm7sbiAIVaAY81icqyYWKfNBXLLEL7DhY5je5Wq+E83XQ8d5u5F
EuapnZhW3y12d6UCsSe9bD8W45NFoWHPXky1TzT+whTxnX1yH9YsPXbJceGSbbgd
Lw3GmUtZx2bVAMToVjNFD2lPA3OmPY1e2lk0jwzTuQrEXfnZYuzbjqs3YUijb7xR
AlsWfIb0IHBwHWpB7da24ezqWP2VD4eaDdD8/+LmDSj6XLngxMNWRLKmXT000eTW
vIFP9GJrvag2R3YFPhrurgGpRsp8HUTLtvcZROxp2JVQGQ7Z4Ww=
=52BN
-----END PGP SIGNATURE-----
Merge tag 'rust-6.12' of https://github.com/Rust-for-Linux/linux
Pull Rust updates from Miguel Ojeda:
"Toolchain and infrastructure:
- Support 'MITIGATION_{RETHUNK,RETPOLINE,SLS}' (which cleans up
objtool warnings), teach objtool about 'noreturn' Rust symbols and
mimic '___ADDRESSABLE()' for 'module_{init,exit}'. With that, we
should be objtool-warning-free, so enable it to run for all Rust
object files.
- KASAN (no 'SW_TAGS'), KCFI and shadow call sanitizer support.
- Support 'RUSTC_VERSION', including re-config and re-build on
change.
- Split helpers file into several files in a folder, to avoid
conflicts in it. Eventually those files will be moved to the right
places with the new build system. In addition, remove the need to
manually export the symbols defined there, reusing existing
machinery for that.
- Relax restriction on configurations with Rust + GCC plugins to just
the RANDSTRUCT plugin.
'kernel' crate:
- New 'list' module: doubly-linked linked list for use with reference
counted values, which is heavily used by the upcoming Rust Binder.
This includes 'ListArc' (a wrapper around 'Arc' that is guaranteed
unique for the given ID), 'AtomicTracker' (tracks whether a
'ListArc' exists using an atomic), 'ListLinks' (the prev/next
pointers for an item in a linked list), 'List' (the linked list
itself), 'Iter' (an iterator over a 'List'), 'Cursor' (a cursor
into a 'List' that allows to remove elements), 'ListArcField' (a
field exclusively owned by a 'ListArc'), as well as support for
heterogeneous lists.
- New 'rbtree' module: red-black tree abstractions used by the
upcoming Rust Binder.
This includes 'RBTree' (the red-black tree itself), 'RBTreeNode' (a
node), 'RBTreeNodeReservation' (a memory reservation for a node),
'Iter' and 'IterMut' (immutable and mutable iterators), 'Cursor'
(bidirectional cursor that allows to remove elements), as well as
an entry API similar to the Rust standard library one.
- 'init' module: add 'write_[pin_]init' methods and the
'InPlaceWrite' trait. Add the 'assert_pinned!' macro.
- 'sync' module: implement the 'InPlaceInit' trait for 'Arc' by
introducing an associated type in the trait.
- 'alloc' module: add 'drop_contents' method to 'BoxExt'.
- 'types' module: implement the 'ForeignOwnable' trait for
'Pin<Box<T>>' and improve the trait's documentation. In addition,
add the 'into_raw' method to the 'ARef' type.
- 'error' module: in preparation for the upcoming Rust support for
32-bit architectures, like arm, locally allow Clippy lint for
those.
Documentation:
- https://rust.docs.kernel.org has been announced, so link to it.
- Enable rustdoc's "jump to definition" feature, making its output a
bit closer to the experience in a cross-referencer.
- Debian Testing now also provides recent Rust releases (outside of
the freeze period), so add it to the list.
MAINTAINERS:
- Trevor is joining as reviewer of the "RUST" entry.
And a few other small bits"
* tag 'rust-6.12' of https://github.com/Rust-for-Linux/linux: (54 commits)
kasan: rust: Add KASAN smoke test via UAF
kbuild: rust: Enable KASAN support
rust: kasan: Rust does not support KHWASAN
kbuild: rust: Define probing macros for rustc
kasan: simplify and clarify Makefile
rust: cfi: add support for CFI_CLANG with Rust
cfi: add CONFIG_CFI_ICALL_NORMALIZE_INTEGERS
rust: support for shadow call stack sanitizer
docs: rust: include other expressions in conditional compilation section
kbuild: rust: replace proc macros dependency on `core.o` with the version text
kbuild: rust: rebuild if the version text changes
kbuild: rust: re-run Kconfig if the version text changes
kbuild: rust: add `CONFIG_RUSTC_VERSION`
rust: avoid `box_uninit_write` feature
MAINTAINERS: add Trevor Gross as Rust reviewer
rust: rbtree: add `RBTree::entry`
rust: rbtree: add cursor
rust: rbtree: add mutable iterator
rust: rbtree: add iterator
rust: rbtree: add red-black tree implementation backed by the C version
...
2024-09-25 17:25:40 +00:00
|
|
|
| awk '$$2~/(T|R|D|B)/ && $$3!~/__cfi/ {printf "EXPORT_SYMBOL_RUST_GPL(%s);\n",$$3}' > $@
|
2021-07-03 14:42:57 +00:00
|
|
|
|
|
|
|
$(obj)/exports_core_generated.h: $(obj)/core.o FORCE
|
|
|
|
$(call if_changed,exports)
|
|
|
|
|
|
|
|
$(obj)/exports_alloc_generated.h: $(obj)/alloc.o FORCE
|
|
|
|
$(call if_changed,exports)
|
|
|
|
|
2024-08-17 16:51:32 +00:00
|
|
|
# Even though Rust kernel modules should never use the bindings directly,
|
|
|
|
# symbols from the `bindings` crate and the C helpers need to be exported
|
|
|
|
# because Rust generics and inlined functions may not get their code generated
|
|
|
|
# in the crate where they are defined. Other helpers, called from non-inline
|
|
|
|
# functions, may not be exported, in principle. However, in general, the Rust
|
|
|
|
# compiler does not guarantee codegen will be performed for a non-inline
|
|
|
|
# function either. Therefore, we export all symbols from helpers and bindings.
|
|
|
|
# In the future, this may be revisited to reduce the number of exports after
|
|
|
|
# the compiler is informed about the places codegen is required.
|
|
|
|
$(obj)/exports_helpers_generated.h: $(obj)/helpers/helpers.o FORCE
|
|
|
|
$(call if_changed,exports)
|
|
|
|
|
2021-07-03 14:42:57 +00:00
|
|
|
$(obj)/exports_bindings_generated.h: $(obj)/bindings.o FORCE
|
|
|
|
$(call if_changed,exports)
|
|
|
|
|
|
|
|
$(obj)/exports_kernel_generated.h: $(obj)/kernel.o FORCE
|
|
|
|
$(call if_changed,exports)
|
|
|
|
|
|
|
|
quiet_cmd_rustc_procmacro = $(RUSTC_OR_CLIPPY_QUIET) P $@
|
|
|
|
cmd_rustc_procmacro = \
|
|
|
|
$(RUSTC_OR_CLIPPY) $(rust_common_flags) \
|
2023-10-05 21:39:58 +00:00
|
|
|
-Clinker-flavor=gcc -Clinker=$(HOSTCC) \
|
|
|
|
-Clink-args='$(call escsq,$(KBUILD_HOSTLDFLAGS))' \
|
kbuild: specify output names separately for each emission type from rustc
In Kbuild, two different rules must not write to the same file, but
it happens when compiling rust source files.
For example, set CONFIG_SAMPLE_RUST_MINIMAL=m and run the following:
$ make -j$(nproc) samples/rust/rust_minimal.o samples/rust/rust_minimal.rsi \
samples/rust/rust_minimal.s samples/rust/rust_minimal.ll
[snip]
RUSTC [M] samples/rust/rust_minimal.o
RUSTC [M] samples/rust/rust_minimal.rsi
RUSTC [M] samples/rust/rust_minimal.s
RUSTC [M] samples/rust/rust_minimal.ll
mv: cannot stat 'samples/rust/rust_minimal.d': No such file or directory
make[3]: *** [scripts/Makefile.build:334: samples/rust/rust_minimal.ll] Error 1
make[3]: *** Waiting for unfinished jobs....
mv: cannot stat 'samples/rust/rust_minimal.d': No such file or directory
make[3]: *** [scripts/Makefile.build:309: samples/rust/rust_minimal.o] Error 1
mv: cannot stat 'samples/rust/rust_minimal.d': No such file or directory
make[3]: *** [scripts/Makefile.build:326: samples/rust/rust_minimal.s] Error 1
make[2]: *** [scripts/Makefile.build:504: samples/rust] Error 2
make[1]: *** [scripts/Makefile.build:504: samples] Error 2
make: *** [Makefile:2008: .] Error 2
The reason for the error is that 4 threads running in parallel renames
the same file, samples/rust/rust_minimal.d.
This does not happen when compiling C or assembly files because
-Wp,-MMD,$(depfile) explicitly specifies the dependency filepath.
$(depfile) is a unique path for each target.
Currently, rustc is only given --out-dir and --emit=<list-of-types>
So, all the rust build rules output the dep-info into the default
<CRATE_NAME>.d, which causes the path conflict.
Fortunately, the --emit option is able to specify the output path
individually, with the form --emit=<type>=<path>.
Add --emit=dep-info=$(depfile) to the common part. Also, remove the
redundant --out-dir because the output path is specified for each type.
The code gets much cleaner because we do not need to rename *.d files.
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Reviewed-by: Miguel Ojeda <ojeda@kernel.org>
Tested-by: Miguel Ojeda <ojeda@kernel.org>
Reviewed-by: Vincenzo Palazzo <vincenzopalazzodev@gmail.com>
2023-01-07 09:18:15 +00:00
|
|
|
--emit=dep-info=$(depfile) --emit=link=$@ --extern proc_macro \
|
|
|
|
--crate-type proc-macro \
|
2023-01-07 09:18:17 +00:00
|
|
|
--crate-name $(patsubst lib%.so,%,$(notdir $@)) $<
|
2021-07-03 14:42:57 +00:00
|
|
|
|
|
|
|
# Procedural macros can only be used with the `rustc` that compiled it.
|
2024-09-02 16:55:31 +00:00
|
|
|
$(obj)/libmacros.so: $(src)/macros/lib.rs FORCE
|
kbuild: mark `rustc` (and others) invocations as recursive
`rustc` (like Cargo) may take advantage of the jobserver at any time
(e.g. for backend parallelism, or eventually frontend too). In the kernel,
we call `rustc` with `-Ccodegen-units=1` (and `-Zthreads` is 1 so far),
so we do not expect parallelism. However, in the upcoming Rust 1.76.0, a
warning is emitted by `rustc` [1] when it cannot connect to the jobserver
it was passed (in many cases, but not all: compiling and `--print sysroot`
do, but `--version` does not). And given GNU Make always passes
the jobserver in the environment variable (even when a line is deemed
non-recursive), `rustc` will end up complaining about it (in particular
in Make 4.3 where there is only the simple pipe jobserver style).
One solution is to remove the jobserver from `MAKEFLAGS`. However, we
can mark the lines with calls to `rustc` (and Cargo) as recursive, which
looks simpler. This is being documented as a recommendation in `rustc`
[2] and allows us to be ready for the time we may use parallelism inside
`rustc` (potentially now, if a user passes `-Zthreads`). Thus do so.
Similarly, do the same for `rustdoc` and `cargo` calls.
Finally, there is one case that the solution does not cover, which is the
`$(shell ...)` call we have. Thus, for that one, set an empty `MAKEFLAGS`
environment variable.
Link: https://github.com/rust-lang/rust/issues/120515 [1]
Acked-by: Masahiro Yamada <masahiroy@kernel.org>
Link: https://github.com/rust-lang/rust/pull/121564 [2]
Link: https://lore.kernel.org/r/20240217002638.57373-1-ojeda@kernel.org
[ Reworded to add link to PR documenting the recommendation. ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2024-02-17 00:26:37 +00:00
|
|
|
+$(call if_changed_dep,rustc_procmacro)
|
2021-07-03 14:42:57 +00:00
|
|
|
|
|
|
|
quiet_cmd_rustc_library = $(if $(skip_clippy),RUSTC,$(RUSTC_OR_CLIPPY_QUIET)) L $@
|
|
|
|
cmd_rustc_library = \
|
|
|
|
OBJTREE=$(abspath $(objtree)) \
|
|
|
|
$(if $(skip_clippy),$(RUSTC),$(RUSTC_OR_CLIPPY)) \
|
|
|
|
$(filter-out $(skip_flags),$(rust_flags) $(rustc_target_flags)) \
|
kbuild: specify output names separately for each emission type from rustc
In Kbuild, two different rules must not write to the same file, but
it happens when compiling rust source files.
For example, set CONFIG_SAMPLE_RUST_MINIMAL=m and run the following:
$ make -j$(nproc) samples/rust/rust_minimal.o samples/rust/rust_minimal.rsi \
samples/rust/rust_minimal.s samples/rust/rust_minimal.ll
[snip]
RUSTC [M] samples/rust/rust_minimal.o
RUSTC [M] samples/rust/rust_minimal.rsi
RUSTC [M] samples/rust/rust_minimal.s
RUSTC [M] samples/rust/rust_minimal.ll
mv: cannot stat 'samples/rust/rust_minimal.d': No such file or directory
make[3]: *** [scripts/Makefile.build:334: samples/rust/rust_minimal.ll] Error 1
make[3]: *** Waiting for unfinished jobs....
mv: cannot stat 'samples/rust/rust_minimal.d': No such file or directory
make[3]: *** [scripts/Makefile.build:309: samples/rust/rust_minimal.o] Error 1
mv: cannot stat 'samples/rust/rust_minimal.d': No such file or directory
make[3]: *** [scripts/Makefile.build:326: samples/rust/rust_minimal.s] Error 1
make[2]: *** [scripts/Makefile.build:504: samples/rust] Error 2
make[1]: *** [scripts/Makefile.build:504: samples] Error 2
make: *** [Makefile:2008: .] Error 2
The reason for the error is that 4 threads running in parallel renames
the same file, samples/rust/rust_minimal.d.
This does not happen when compiling C or assembly files because
-Wp,-MMD,$(depfile) explicitly specifies the dependency filepath.
$(depfile) is a unique path for each target.
Currently, rustc is only given --out-dir and --emit=<list-of-types>
So, all the rust build rules output the dep-info into the default
<CRATE_NAME>.d, which causes the path conflict.
Fortunately, the --emit option is able to specify the output path
individually, with the form --emit=<type>=<path>.
Add --emit=dep-info=$(depfile) to the common part. Also, remove the
redundant --out-dir because the output path is specified for each type.
The code gets much cleaner because we do not need to rename *.d files.
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Reviewed-by: Miguel Ojeda <ojeda@kernel.org>
Tested-by: Miguel Ojeda <ojeda@kernel.org>
Reviewed-by: Vincenzo Palazzo <vincenzopalazzodev@gmail.com>
2023-01-07 09:18:15 +00:00
|
|
|
--emit=dep-info=$(depfile) --emit=obj=$@ \
|
|
|
|
--emit=metadata=$(dir $@)$(patsubst %.o,lib%.rmeta,$(notdir $@)) \
|
|
|
|
--crate-type rlib -L$(objtree)/$(obj) \
|
2023-01-07 09:18:17 +00:00
|
|
|
--crate-name $(patsubst %.o,%,$(notdir $@)) $< \
|
2023-10-31 20:10:14 +00:00
|
|
|
--sysroot=/dev/null \
|
2024-07-25 18:33:23 +00:00
|
|
|
$(if $(rustc_objcopy),;$(OBJCOPY) $(rustc_objcopy) $@) \
|
|
|
|
$(cmd_objtool)
|
2021-07-03 14:42:57 +00:00
|
|
|
|
|
|
|
rust-analyzer:
|
2023-04-11 09:17:15 +00:00
|
|
|
$(Q)$(srctree)/scripts/generate_rust_analyzer.py \
|
2023-08-04 17:14:39 +00:00
|
|
|
--cfgs='core=$(core-cfgs)' --cfgs='alloc=$(alloc-cfgs)' \
|
2024-03-06 10:42:22 +00:00
|
|
|
$(realpath $(srctree)) $(realpath $(objtree)) \
|
2024-07-24 17:27:06 +00:00
|
|
|
$(rustc_sysroot) $(RUST_LIB_SRC) $(KBUILD_EXTMOD) > \
|
2023-04-11 09:17:15 +00:00
|
|
|
$(if $(KBUILD_EXTMOD),$(extmod_prefix),$(objtree))/rust-project.json
|
2021-07-03 14:42:57 +00:00
|
|
|
|
2022-12-05 21:50:00 +00:00
|
|
|
redirect-intrinsics = \
|
2024-08-06 15:06:19 +00:00
|
|
|
__addsf3 __eqsf2 __extendsfdf2 __gesf2 __lesf2 __ltsf2 __mulsf3 __nesf2 __truncdfsf2 __unordsf2 \
|
|
|
|
__adddf3 __eqdf2 __ledf2 __ltdf2 __muldf3 __unorddf2 \
|
2022-12-05 21:50:00 +00:00
|
|
|
__muloti4 __multi3 \
|
|
|
|
__udivmodti4 __udivti3 __umodti3
|
|
|
|
|
|
|
|
ifneq ($(or $(CONFIG_ARM64),$(and $(CONFIG_RISCV),$(CONFIG_64BIT))),)
|
|
|
|
# These intrinsics are defined for ARM64 and RISCV64
|
|
|
|
redirect-intrinsics += \
|
|
|
|
__ashrti3 \
|
|
|
|
__ashlti3 __lshrti3
|
|
|
|
endif
|
|
|
|
|
2024-07-25 18:33:23 +00:00
|
|
|
define rule_rustc_library
|
|
|
|
$(call cmd_and_fixdep,rustc_library)
|
|
|
|
$(call cmd,gen_objtooldep)
|
|
|
|
endef
|
|
|
|
|
2021-07-03 14:42:57 +00:00
|
|
|
$(obj)/core.o: private skip_clippy = 1
|
rust: relax most deny-level lints to warnings
Since we are starting to support several Rust toolchains, lints (including
Clippy ones) now may behave differently and lint groups may include
new lints.
Therefore, to maximize the chances a given version works, relax some
deny-level lints to warnings. It may also make our lives a bit easier
while developing new code or refactoring.
To be clear, the requirements for in-tree code are still the same, since
Rust code still needs to be warning-free (patches should be clean under
`WERROR=y`) and the set of lints is not changed.
`unsafe_op_in_unsafe_fn` is left unmodified, i.e. as an error, since it is
becoming the default in the language (warn-by-default in Rust 2024 [1] and
ideally an error later on) and thus it should also be very well tested. In
addition, it is simple enough that it should not have false positives
(unlike e.g. `rust_2018_idioms`'s `explicit_outlives_requirements`).
`non_ascii_idents` is left unmodified as well, i.e. as an error, since
it is unlikely one gains any productivity during development if it
were a warning (in fact, it may be worse, since it is likely one made
a typo). In addition, it should not have false positives.
Finally, put the two `-D` ones at the top and take the chance to do one
per line.
Link: https://github.com/rust-lang/rust/pull/112038 [1]
Reviewed-by: Finn Behrens <me@kloenk.dev>
Tested-by: Benno Lossin <benno.lossin@proton.me>
Tested-by: Andreas Hindborg <a.hindborg@samsung.com>
Link: https://lore.kernel.org/r/20240709160615.998336-5-ojeda@kernel.org
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2024-07-09 16:05:59 +00:00
|
|
|
$(obj)/core.o: private skip_flags = -Wunreachable_pub
|
2022-12-05 21:50:00 +00:00
|
|
|
$(obj)/core.o: private rustc_objcopy = $(foreach sym,$(redirect-intrinsics),--redefine-sym $(sym)=__rust$(sym))
|
2021-07-03 14:42:57 +00:00
|
|
|
$(obj)/core.o: private rustc_target_flags = $(core-cfgs)
|
2024-09-02 16:55:30 +00:00
|
|
|
$(obj)/core.o: $(RUST_LIB_SRC)/core/src/lib.rs \
|
|
|
|
$(wildcard $(objtree)/include/config/RUSTC_VERSION_TEXT) FORCE
|
2024-07-25 18:33:23 +00:00
|
|
|
+$(call if_changed_rule,rustc_library)
|
arch: um: rust: Add i386 support for Rust
At present, Rust in the kernel only supports 64-bit x86, so UML has
followed suit. However, it's significantly easier to support 32-bit i386
on UML than on bare metal, as UML does not use the -mregparm option
(which alters the ABI), which is not yet supported by rustc[1].
Add support for CONFIG_RUST on um/i386, by adding a new target config to
generate_rust_target, and replacing various checks on CONFIG_X86_64 to
also support CONFIG_X86_32.
We still use generate_rust_target, rather than a built-in rustc target,
in order to match x86_64, provide a future place for -mregparm, and more
easily disable floating point instructions.
With these changes, the KUnit tests pass with:
kunit.py run --make_options LLVM=1 --kconfig_add CONFIG_RUST=y
--kconfig_add CONFIG_64BIT=n --kconfig_add CONFIG_FORTIFY_SOURCE=n
An earlier version of these changes was proposed on the Rust-for-Linux
github[2].
[1]: https://github.com/rust-lang/rust/issues/116972
[2]: https://github.com/Rust-for-Linux/linux/pull/966
Signed-off-by: David Gow <davidgow@google.com>
Link: https://patch.msgid.link/20240604224052.3138504-1-davidgow@google.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
2024-06-04 22:40:50 +00:00
|
|
|
ifneq ($(or $(CONFIG_X86_64),$(CONFIG_X86_32)),)
|
2023-10-20 15:50:55 +00:00
|
|
|
$(obj)/core.o: scripts/target.json
|
|
|
|
endif
|
2021-07-03 14:42:57 +00:00
|
|
|
|
|
|
|
$(obj)/compiler_builtins.o: private rustc_objcopy = -w -W '__*'
|
|
|
|
$(obj)/compiler_builtins.o: $(src)/compiler_builtins.rs $(obj)/core.o FORCE
|
2024-07-25 18:33:23 +00:00
|
|
|
+$(call if_changed_rule,rustc_library)
|
2021-07-03 14:42:57 +00:00
|
|
|
|
|
|
|
$(obj)/alloc.o: private skip_clippy = 1
|
rust: relax most deny-level lints to warnings
Since we are starting to support several Rust toolchains, lints (including
Clippy ones) now may behave differently and lint groups may include
new lints.
Therefore, to maximize the chances a given version works, relax some
deny-level lints to warnings. It may also make our lives a bit easier
while developing new code or refactoring.
To be clear, the requirements for in-tree code are still the same, since
Rust code still needs to be warning-free (patches should be clean under
`WERROR=y`) and the set of lints is not changed.
`unsafe_op_in_unsafe_fn` is left unmodified, i.e. as an error, since it is
becoming the default in the language (warn-by-default in Rust 2024 [1] and
ideally an error later on) and thus it should also be very well tested. In
addition, it is simple enough that it should not have false positives
(unlike e.g. `rust_2018_idioms`'s `explicit_outlives_requirements`).
`non_ascii_idents` is left unmodified as well, i.e. as an error, since
it is unlikely one gains any productivity during development if it
were a warning (in fact, it may be worse, since it is likely one made
a typo). In addition, it should not have false positives.
Finally, put the two `-D` ones at the top and take the chance to do one
per line.
Link: https://github.com/rust-lang/rust/pull/112038 [1]
Reviewed-by: Finn Behrens <me@kloenk.dev>
Tested-by: Benno Lossin <benno.lossin@proton.me>
Tested-by: Andreas Hindborg <a.hindborg@samsung.com>
Link: https://lore.kernel.org/r/20240709160615.998336-5-ojeda@kernel.org
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2024-07-09 16:05:59 +00:00
|
|
|
$(obj)/alloc.o: private skip_flags = -Wunreachable_pub
|
2021-07-03 14:42:57 +00:00
|
|
|
$(obj)/alloc.o: private rustc_target_flags = $(alloc-cfgs)
|
2024-03-28 01:35:56 +00:00
|
|
|
$(obj)/alloc.o: $(RUST_LIB_SRC)/alloc/src/lib.rs $(obj)/compiler_builtins.o FORCE
|
2024-07-25 18:33:23 +00:00
|
|
|
+$(call if_changed_rule,rustc_library)
|
2021-07-03 14:42:57 +00:00
|
|
|
|
2022-11-10 16:41:37 +00:00
|
|
|
$(obj)/build_error.o: $(src)/build_error.rs $(obj)/compiler_builtins.o FORCE
|
2024-07-25 18:33:23 +00:00
|
|
|
+$(call if_changed_rule,rustc_library)
|
2022-11-10 16:41:37 +00:00
|
|
|
|
2021-07-03 14:42:57 +00:00
|
|
|
$(obj)/bindings.o: $(src)/bindings/lib.rs \
|
|
|
|
$(obj)/compiler_builtins.o \
|
|
|
|
$(obj)/bindings/bindings_generated.rs \
|
|
|
|
$(obj)/bindings/bindings_helpers_generated.rs FORCE
|
2024-07-25 18:33:23 +00:00
|
|
|
+$(call if_changed_rule,rustc_library)
|
2021-07-03 14:42:57 +00:00
|
|
|
|
2023-04-03 09:33:52 +00:00
|
|
|
$(obj)/uapi.o: $(src)/uapi/lib.rs \
|
|
|
|
$(obj)/compiler_builtins.o \
|
|
|
|
$(obj)/uapi/uapi_generated.rs FORCE
|
2024-07-25 18:33:23 +00:00
|
|
|
+$(call if_changed_rule,rustc_library)
|
2023-04-03 09:33:52 +00:00
|
|
|
|
2021-07-03 14:42:57 +00:00
|
|
|
$(obj)/kernel.o: private rustc_target_flags = --extern alloc \
|
2023-04-03 09:33:52 +00:00
|
|
|
--extern build_error --extern macros --extern bindings --extern uapi
|
2022-11-10 16:41:37 +00:00
|
|
|
$(obj)/kernel.o: $(src)/kernel/lib.rs $(obj)/alloc.o $(obj)/build_error.o \
|
2023-04-03 09:33:52 +00:00
|
|
|
$(obj)/libmacros.so $(obj)/bindings.o $(obj)/uapi.o FORCE
|
2024-07-25 18:33:23 +00:00
|
|
|
+$(call if_changed_rule,rustc_library)
|
2021-07-03 14:42:57 +00:00
|
|
|
|
|
|
|
endif # CONFIG_RUST
|