diff mbox series

[RFC,1/4] kernel-yocto.bbclass: Add integrated support for Rust-for-Linux

Message ID 20251104171611.2227798-2-elmehdi.younes@smile.fr
State New
Headers show
Series Add rust-for-linux option for linux-yocto | expand

Commit Message

El Mehdi YOUNES Nov. 4, 2025, 5:16 p.m. UTC
This change introduces a comprehensive solution to build Rust-enabled
kernels cleanly, controlled by a new DISTRO_FEATURE named 'rust-kernel'.

When this feature is enabled, the class performs the following actions:

1.  Appends the necessary native toolchain dependencies (rust-native,
    bindgen-native, etc.) to the kernel recipe's DEPENDS.

2.  Implements a solution for reproducible builds to fix the [buildpaths]
    QA failures.
    To solve this, the rustc flag --remap-path-prefix is used. This
    flag instructs the compiler to replace build-specific path prefixes
    with generic ones in all output, including debug metadata. The official
    documentation for this flag is here:
    https://doc.rust-lang.org/nightly/rustc/remap-source-paths.html

    To apply this flag cleanly, the rust-common class is inherited to
    use its RUST_DEBUG_REMAP variable. This commit extends
    RUST_DEBUG_REMAP with the specific paths for the kernel source (${S}),
    the build directory (${B}), and the native sysroot (${STAGING_DIR_NATIVE}).
    The resulting flags are then passed to the kernel's Makefile via the
    KRUSTFLAGS variable.

Signed-off-by: El Mehdi YOUNES <elmehdi.younes@smile.fr>
---
 meta/classes-recipe/kernel-yocto.bbclass | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

Comments

Bruce Ashfield Nov. 5, 2025, 1:22 p.m. UTC | #1
On Tue, Nov 4, 2025 at 12:15 PM El Mehdi YOUNES via lists.openembedded.org
<elmehdi.younes=smile.fr@lists.openembedded.org> wrote:

> This change introduces a comprehensive solution to build Rust-enabled
> kernels cleanly, controlled by a new DISTRO_FEATURE named 'rust-kernel'.
>
> When this feature is enabled, the class performs the following actions:
>
> 1.  Appends the necessary native toolchain dependencies (rust-native,
>     bindgen-native, etc.) to the kernel recipe's DEPENDS.
>
> 2.  Implements a solution for reproducible builds to fix the [buildpaths]
>     QA failures.
>     To solve this, the rustc flag --remap-path-prefix is used. This
>     flag instructs the compiler to replace build-specific path prefixes
>     with generic ones in all output, including debug metadata. The official
>     documentation for this flag is here:
>     https://doc.rust-lang.org/nightly/rustc/remap-source-paths.html
>
>     To apply this flag cleanly, the rust-common class is inherited to
>     use its RUST_DEBUG_REMAP variable. This commit extends
>     RUST_DEBUG_REMAP with the specific paths for the kernel source (${S}),
>     the build directory (${B}), and the native sysroot
> (${STAGING_DIR_NATIVE}).
>     The resulting flags are then passed to the kernel's Makefile via the
>     KRUSTFLAGS variable.
>
> Signed-off-by: El Mehdi YOUNES <elmehdi.younes@smile.fr>
> ---
>  meta/classes-recipe/kernel-yocto.bbclass | 19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)
>
> diff --git a/meta/classes-recipe/kernel-yocto.bbclass
> b/meta/classes-recipe/kernel-yocto.bbclass
> index e53bf15194..e722a7a81d 100644
> --- a/meta/classes-recipe/kernel-yocto.bbclass
> +++ b/meta/classes-recipe/kernel-yocto.bbclass
> @@ -463,6 +463,7 @@ do_kernel_configme[depends] +=
> "virtual/cross-binutils:do_populate_sysroot"
>  do_kernel_configme[depends] += "virtual/cross-cc:do_populate_sysroot"
>  do_kernel_configme[depends] += "bc-native:do_populate_sysroot
> bison-native:do_populate_sysroot"
>  do_kernel_configme[depends] += "kern-tools-native:do_populate_sysroot"
> +do_kernel_configme[depends] += "${@bb.utils.contains('DISTRO_FEATURES',
> 'rust-kernel', ' rust-native:do_populate_sysroot
> clang-native:do_populate_sysroot bindgen-cli-native:do_populate_sysroot',
> '', d)}"
>  do_kernel_configme[dirs] += "${S} ${B}"
>  do_kernel_configme() {
>         do_kernel_metadata config
> @@ -491,6 +492,16 @@ do_kernel_configme() {
>                 bberror "${configs}"
>                 bbfatal_log "Could not find configuration queue
> (${meta_dir}/config.queue)"
>         fi
> +        # Run the kernel's 'make rustavailable' check.
> +        # This is a critical step for getting a clear error message.
> +        # Without this check, if the Rust toolchain is incomplete
> +        # (e.g., missing sources), Kbuild just silently disables
> +        # CONFIG_RUST=y. The build would then succeed *without* Rust
> +        # support, which is very difficult to debug.
> +        # This command forces an explicit failure if the toolchain is not
> ready.
> +        if ${@bb.utils.contains('DISTRO_FEATURES', 'rust-kernel', 'true',
> 'false', d)}; then
> +            oe_runmake -C ${S} O=${B} rustavailable
> +        fi
>
>         CFLAGS="${CFLAGS} ${TOOLCHAIN_OPTIONS}" HOSTCC="${BUILD_CC}
> ${BUILD_CFLAGS} ${BUILD_LDFLAGS}" HOSTCPP="${BUILD_CPP}" CC="${KERNEL_CC}"
> LD="${KERNEL_LD}" OBJCOPY="${KERNEL_OBJCOPY}" STRIP="${KERNEL_STRIP}"
> ARCH=${ARCH} merge_config.sh -O ${B} ${config_flags} ${configs} >
> ${meta_dir}/cfg/merge_config_build.log 2>&1
>         if [ $? -ne 0 -o ! -f ${B}/.config ]; then
> @@ -776,3 +787,11 @@ python () {
>  addtask kernel_version_sanity_check after do_kernel_metadata
> do_kernel_checkout before do_compile
>  addtask validate_branches before do_patch after do_kernel_checkout
>  addtask kernel_configcheck after do_configure before do_compile
> +
> +INHERIT:append = " ${@bb.utils.contains('DISTRO_FEATURES', 'rust-kernel',
> ' rust-common', '', d)}"
> +KERNEL_EXTRA_DEPENDS_RUST = "rust-native cargo-native clang-native
> llvm-native bindgen-cli-native"
>

There's limited value in assigning this to a variable without using ?= in
that assignment, since
there's no "clean" way to override it from a bbappend.


> +DEPENDS:append = " ${@bb.utils.contains('DISTRO_FEATURES', 'rust-kernel',
> ' ${KERNEL_EXTRA_DEPENDS_RUST}', '', d)}"
> +RUST_KERNEL_OEMAKE_VARS = "KRUSTFLAGS=\"${RUST_DEBUG_REMAP}\""
>

Same here, should be ?=


> +EXTRA_OEMAKE:append = " ${@bb.utils.contains('DISTRO_FEATURES',
> 'rust-kernel', ' ${RUST_KERNEL_OEMAKE_VARS}', '', d)}"
> +RUST_DEBUG_REMAP:append = "${@bb.utils.contains('DISTRO_FEATURES',
> 'rust-kernel', ' --remap-path-prefix=${S}=${TARGET_DBGSRC_DIR}/kernel
> --remap-path-prefix=${STAGING_DIR_NATIVE}=${TARGET_DBGSRC_DIR}/rustc
> --remap-path-prefix=${B}=${TARGET_DBGSRC_DIR}/build', '', d)}"
> +
>

To keep everything consistent, those rust debug flags should be assigned to
a variable, versus
being inlined in the python.

Bruce



>
> -=-=-=-=-=-=-=-=-=-=-=-
> Links: You receive all messages sent to this group.
> View/Reply Online (#225737):
> https://lists.openembedded.org/g/openembedded-core/message/225737
> Mute This Topic: https://lists.openembedded.org/mt/116120516/1050810
> Group Owner: openembedded-core+owner@lists.openembedded.org
> Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [
> bruce.ashfield@gmail.com]
> -=-=-=-=-=-=-=-=-=-=-=-
>
>
diff mbox series

Patch

diff --git a/meta/classes-recipe/kernel-yocto.bbclass b/meta/classes-recipe/kernel-yocto.bbclass
index e53bf15194..e722a7a81d 100644
--- a/meta/classes-recipe/kernel-yocto.bbclass
+++ b/meta/classes-recipe/kernel-yocto.bbclass
@@ -463,6 +463,7 @@  do_kernel_configme[depends] += "virtual/cross-binutils:do_populate_sysroot"
 do_kernel_configme[depends] += "virtual/cross-cc:do_populate_sysroot"
 do_kernel_configme[depends] += "bc-native:do_populate_sysroot bison-native:do_populate_sysroot"
 do_kernel_configme[depends] += "kern-tools-native:do_populate_sysroot"
+do_kernel_configme[depends] += "${@bb.utils.contains('DISTRO_FEATURES', 'rust-kernel', ' rust-native:do_populate_sysroot clang-native:do_populate_sysroot bindgen-cli-native:do_populate_sysroot', '', d)}"
 do_kernel_configme[dirs] += "${S} ${B}"
 do_kernel_configme() {
 	do_kernel_metadata config
@@ -491,6 +492,16 @@  do_kernel_configme() {
 		bberror "${configs}"
 		bbfatal_log "Could not find configuration queue (${meta_dir}/config.queue)"
 	fi
+        # Run the kernel's 'make rustavailable' check.
+        # This is a critical step for getting a clear error message.
+        # Without this check, if the Rust toolchain is incomplete
+        # (e.g., missing sources), Kbuild just silently disables
+        # CONFIG_RUST=y. The build would then succeed *without* Rust
+        # support, which is very difficult to debug.
+        # This command forces an explicit failure if the toolchain is not ready.
+        if ${@bb.utils.contains('DISTRO_FEATURES', 'rust-kernel', 'true', 'false', d)}; then
+            oe_runmake -C ${S} O=${B} rustavailable
+        fi
 
 	CFLAGS="${CFLAGS} ${TOOLCHAIN_OPTIONS}" HOSTCC="${BUILD_CC} ${BUILD_CFLAGS} ${BUILD_LDFLAGS}" HOSTCPP="${BUILD_CPP}" CC="${KERNEL_CC}" LD="${KERNEL_LD}" OBJCOPY="${KERNEL_OBJCOPY}" STRIP="${KERNEL_STRIP}" ARCH=${ARCH} merge_config.sh -O ${B} ${config_flags} ${configs} > ${meta_dir}/cfg/merge_config_build.log 2>&1
 	if [ $? -ne 0 -o ! -f ${B}/.config ]; then
@@ -776,3 +787,11 @@  python () {
 addtask kernel_version_sanity_check after do_kernel_metadata do_kernel_checkout before do_compile
 addtask validate_branches before do_patch after do_kernel_checkout
 addtask kernel_configcheck after do_configure before do_compile
+
+INHERIT:append = " ${@bb.utils.contains('DISTRO_FEATURES', 'rust-kernel', ' rust-common', '', d)}"
+KERNEL_EXTRA_DEPENDS_RUST = "rust-native cargo-native clang-native llvm-native bindgen-cli-native"
+DEPENDS:append = " ${@bb.utils.contains('DISTRO_FEATURES', 'rust-kernel', ' ${KERNEL_EXTRA_DEPENDS_RUST}', '', d)}"
+RUST_KERNEL_OEMAKE_VARS = "KRUSTFLAGS=\"${RUST_DEBUG_REMAP}\""
+EXTRA_OEMAKE:append = " ${@bb.utils.contains('DISTRO_FEATURES', 'rust-kernel', ' ${RUST_KERNEL_OEMAKE_VARS}', '', d)}"
+RUST_DEBUG_REMAP:append = "${@bb.utils.contains('DISTRO_FEATURES', 'rust-kernel', ' --remap-path-prefix=${S}=${TARGET_DBGSRC_DIR}/kernel --remap-path-prefix=${STAGING_DIR_NATIVE}=${TARGET_DBGSRC_DIR}/rustc --remap-path-prefix=${B}=${TARGET_DBGSRC_DIR}/build', '', d)}"
+