Skip to content

Conversation

@iav
Copy link
Contributor

@iav iav commented Feb 10, 2026

Summary

Add kernel-rust extension that enables CONFIG_RUST in kernel builds, with automatic LLVM version matching across distros.

Core functionality:

  • Enables CONFIG_RUST in kernel menuconfig and configures the build environment
  • Passes tool paths via make params (RUSTC, RUSTFMT, BINDGEN) and env vars (RUST_LIB_SRC) to work with env -i in run_kernel_make_internal
  • Includes _find_rust_tool() helper with dpkg -L fallback for non-standard binary locations (versioned packages install to /usr/lib/rust-X.YY/bin/, not /usr/bin/)
  • Optional RUST_KERNEL_SAMPLES=yes builds sample Rust modules for toolchain smoke testing

LLVM/clang version matching (the tricky part):

bindgen links against a specific libclang version at build time. If the system clang differs from that libclang, the kernel emits a warning at make rustavailable and may produce incorrect bindings. The dependency chain is:

bindgen-0.71 → libclang-20-dev → needs clang-20/lld-20/llvm-20

However, on Ubuntu 24.04 (noble), the default unversioned clang package is version 18, while bindgen-0.71 (from noble-updates) pulls in libclang-20. This mismatch causes:

  1. Kernel warning: libclang version (20.1.2) does not match Clang's (18.1.3)
  2. When KERNEL_COMPILER=clang: kernel-make.sh sets explicit CC=ccache clang (18) which overrides CC derived from LLVM=-20 in the kernel Makefile

How the extension solves this:

  • _detect_llvm_version() auto-detects the required LLVM version by resolving bindgen's dependency chain to libclang-NN-dev
  • Installs versioned clang-20/lld-20/llvm-20 instead of unversioned clang/lld/llvm
  • For KERNEL_COMPILER=clang builds: replaces LLVM=1LLVM=-20 and CC=ccache clangCC=ccache clang-20 in make params
  • Overrides artifact hash _T key via artifact_kernel_version_parts hook (runs after kernel-version-toolchain alphabetically, does not modify that extension)

Cross-distro package availability:

Package naming differs significantly across distros — tested and handled:

Ubuntu 24.04 Debian Trixie Ubuntu 25.10 Ubuntu 26.04
rustc rustc-1.85 rustc (unversioned) rustc-1.85 rustc-1.85
bindgen bindgen-0.71 bindgen 0.71.1 bindgen 0.71.1 bindgen 0.72.1
libclang libclang-20-dev libclang-19-dev libclang-20-dev libclang-21-dev

_apt_pick() selects the first installable package from versioned/unversioned candidates, using apt-cache policy to filter out virtual packages (e.g. bindgen-0.71 on Trixie is a virtual package whose providers contain misleading libclang-16 in their names).

To update for new distros, only RUST_APT_VERSION and BINDGEN_APT_VERSION need manual adjustment — LLVM_APT_VERSION is auto-detected.

Usage

# Enable Rust in kernel config interactively
./compile.sh kernel-config BOARD=... BRANCH=edge ENABLE_EXTENSIONS="kernel-rust"

# Build kernel with Rust support
./compile.sh kernel BOARD=... BRANCH=edge ENABLE_EXTENSIONS="kernel-rust"

# Build kernel with Rust + clang
./compile.sh kernel BOARD=rock-5b ENABLE_EXTENSIONS="kernel-rust" KERNEL_COMPILER=clang

# Include sample Rust modules for smoke testing
./compile.sh kernel BOARD=... ENABLE_EXTENSIONS="kernel-rust" RUST_KERNEL_SAMPLES=yes

Implementation details

  • APT packages: rustc-1.85 (noble-security), bindgen-0.71 (noble-updates since 2026-02-02). Base bindgen 0.66.1 panics on kernel >= 6.19 headers (FromBytesWithNulError).
  • Tool discovery: versioned binaries install to non-standard paths (/usr/lib/rust-1.85/bin/rustfmt), so _find_rust_tool() tries: versioned name in PATH → dpkg -L lookup → unversioned fallback.
  • env -i passthrough: run_kernel_make_internal() clears environment; Rust paths are passed via common_make_params_quoted (RUSTC, RUSTFMT, BINDGEN) and common_make_envs (RUST_LIB_SRC).
  • ccache + Rust: ccache does not support rustc (won't fix since 2019). The kernel has no RUSTC_WRAPPER mechanism, so Rust code is always compiled from scratch. Only C compilation benefits from ccache.

Test plan

  • Kernel 6.19 build for rockchip64 on aarch64 with Docker (GCC)
  • Kernel 6.19 build for rockchip64 on aarch64 without Docker (GCC)
  • Kernel 6.19 build with KERNEL_COMPILER=clang — Rust compiles, LLVM=-20 applied
  • LLVM version auto-detection tested in Docker: Ubuntu 24.04, Debian Trixie, Ubuntu 25.10, Ubuntu 26.04
  • Verify sample modules load: modprobe rust_minimal
  • Full clang build to completion (interrupted by SIGINT in test runs)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Comprehensive Rust toolchain support for kernel builds, including APT-based install path (rustup notes commented).
    • LLVM/libclang version detection to align toolchain selection.
    • Multi-step discovery of Rust tools with explicit propagation of tool paths into kernel build parameters.
    • Host readiness checks with clear alerts and a fail-fast path for missing tools.
    • Optional enabling of Rust kernel sample modules.

@iav iav requested a review from igorpecovnik as a code owner February 10, 2026 04:05
@github-actions github-actions bot added 02 Milestone: First quarter release size/medium PR with more then 50 and less then 250 lines labels Feb 10, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 10, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a new extension script that integrates Rust toolchains into the kernel build flow: apt-based dependency selection (rustup flow commented), multi-step tool discovery, LLVM/libclang version detection and toolchain override, host readiness checks, kernel config/make hooks, and propagation of explicit Rust tool paths and options. (≤50 words)

Changes

Cohort / File(s) Summary
Rust Kernel Build Support
extensions/kernel-rust.sh
New file adding end-to-end Rust integration: apt-based dependency selection (rustup flow commented), multi-tier tool discovery (_find_rust_tool, _apt_pick), host dependency registration (add_host_dependencies__add_rust_compiler), readiness checks (host_dependencies_ready__add_rust_compiler), kernel config and make hooks (custom_kernel_config__add_rust_compiler, custom_kernel_make_params__add_rust_compiler), toolchain version override (artifact_kernel_version_parts__override_toolchain_version), utility helpers (_show_dpkg_bins, _missing_rust_tool_abort), and new globals (RUST_APT_VERSION, BINDGEN_APT_VERSION, LLVM_APT_VERSION, RUST_KERNEL_SAMPLES, RUST_TOOL_*).

Sequence Diagram(s)

sequenceDiagram
    participant Build as Build System
    participant Ext as Rust Extension
    participant Apt as APT/Package Manager
    participant Finder as Tool Discoverer
    participant Kernel as Kernel Build

    Build->>Ext: Request Rust capability
    Ext->>Apt: Select/install Rust/LLVM/bindgen packages (apt flow)
    Apt-->>Ext: Packages installed / available
    Ext->>Finder: _find_rust_tool (versioned PATH, dpkg lists, unversioned PATH)
    Finder-->>Ext: rustc, rustfmt, bindgen paths
    Ext->>Ext: detect libclang/LLVM version -> override toolchain version
    Ext->>Kernel: Inject RUST config flags and make params (RUSTC, RUSTFMT, BINDGEN, RUST_LIB_SRC, LLVM/CC)
    Kernel-->>Build: Kernel config and make params updated
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 I hopped through apt and dpkg lanes,
I sniffed for rustc, bindgen gains,
I matched LLVM to clang's tune,
I tucked tool paths under the moon,
A kernel burrow — ready to run!

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically summarizes the main change: adding a Rust support extension (kernel-rust) for kernel builds.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions bot added Needs review Seeking for review Framework Framework components labels Feb 10, 2026
@iav iav marked this pull request as draft February 10, 2026 22:02
@github-actions github-actions bot added size/large PR with 250 lines or more and removed size/medium PR with more then 50 and less then 250 lines labels Feb 10, 2026
@iav iav marked this pull request as ready for review February 11, 2026 00:11
@armbian armbian deleted a comment from coderabbitai bot Feb 11, 2026
@armbian armbian deleted a comment from coderabbitai bot Feb 11, 2026
@EvilOlaf
Copy link
Member

tested against #9381 just for fun. Seems to work: https://paste.armbian.com/javugatico
The only thing I've noticed was

   ***
   *** Rust bindings generator '/usr/bin/bindgen' versions 0.66.0 and 0.66.1 may not
   *** work due to a bug (https://github.com/rust-lang/rust-bindgen/pull/2567),
   *** unless patched (like Debian's).
   ***   Your version:     0.66.1
   ***
   ***
   *** Please see Documentation/rust/quick-start.rst for details
   *** on how to set up the Rust support.
   ***

No clue if this is an issue.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@extensions/kernel-rust.sh`:
- Around line 314-319: The element added to common_make_envs sets RUST_LIB_SRC
with embedded single quotes which will be preserved when passed to env -i;
update the construction so quoting is consistent by either removing the embedded
single quotes in the value added to common_make_envs (i.e., push
RUST_LIB_SRC=${rust_lib_src} instead) or ensure the caller that expands
common_make_envs uses the bash array expansion with the `@Q` operator
(common_make_envs[@]@Q) like common_make_params_quoted does; modify the code
that builds/expands common_make_envs or the element insertion for RUST_LIB_SRC
so the final env invocation receives a properly quoted value rather than literal
single quotes.
🧹 Nitpick comments (5)
extensions/kernel-rust.sh (5)

124-131: Loose grep pattern may match unintended binaries from dpkg file list.

grep "/bin/${base}" is a substring match. For base="rustc", it would also match paths like /usr/lib/rust-1.85/bin/rustc-wrapper or /usr/lib/rust-1.85/bin/rustc-demangler. Combined with head -1, the result depends on dpkg -L output order, which could non-deterministically pick the wrong binary.

Anchor the grep to match the exact binary name:

Proposed fix
-		tool_path="$(dpkg -L "${versioned}" 2> /dev/null | grep "/bin/${base}" | head -1 || true)"
+		tool_path="$(dpkg -L "${versioned}" 2> /dev/null | grep -E "/bin/${base}\$" | head -1 || true)"

265-279: CC glob pattern could be tightened slightly.

CC=*clang) matches any value ending in clang, including hypothetical CC=somethingclang. A more precise pattern like CC=*[[:space:]]clang|CC=clang would be safer. However, in practice the only values set upstream are CC=ccache clang or CC=clang, so this is a minor robustness nit.


296-304: Consider a fallback for RUST_LIB_SRC discovery.

The path /usr/src/rustc-${rustc_full_version}/library is the only APT convention checked. If a future Debian/Ubuntu ships rust-src with a different layout (e.g., rust-src instead of rust-X.YY-src), this silently falls through to the warning on line 318. A secondary glob or dpkg -L lookup on the rust-src package could improve robustness.


156-196: Large commented-out block adds noise.

~40 lines of commented-out rustup code. While it's useful as documentation of the alternative method, consider moving it to a separate file or a doc comment/README section to keep the active code clean.


75-89: LLVM packages don't use _apt_pick fallback, unlike Rust/bindgen packages.

Lines 82–85 use _apt_pick for graceful fallback, but line 88 hardcodes versioned clang-${LLVM_APT_VERSION} / lld-${LLVM_APT_VERSION} / llvm-${LLVM_APT_VERSION} without fallback to unversioned. If auto-detection returns a version that isn't packaged, apt will fail with a less helpful error. This is likely intentional since the version is auto-detected, but worth noting for cross-distro robustness.

@iav
Copy link
Contributor Author

iav commented Feb 11, 2026

Rust bindings generator '/usr/bin/bindgen' versions 0.66.0 and 0.66.1

This is strange. Ubuntu 24.04 noble bindgen-0.71 is in the noble-updates repository.
(available since 2026-02-02).
@EvilOlaf, are updates disabled on your builder? Or is the noble-updates repository disabled?
You not use docker?
Whether this is a problem or not, I don’t know yet: I solve problems as they arise :)

@iav
Copy link
Contributor Author

iav commented Feb 11, 2026

@coderabbitai Regarding the "Actionable" comment about RUST_LIB_SRC quoting in common_make_envs:

This is not a bug — it's the established pattern used throughout the framework. All elements in common_make_envs use embedded single quotes:

common_make_envs=(
    "CCACHE_BASEDIR='$(pwd)'"                   # line 21
    "CCACHE_TEMPDIR='${CCACHE_TEMPDIR:?}'"      # line 22
    "CCACHE_DIR='${CCACHE_DIR}'"                # line 34
    "RUST_LIB_SRC='${rust_lib_src}'"            # our addition - same format
)

Why this works correctly:

  1. Framework convention — this quoting style is used consistently in lib/functions/compilation/kernel-make.sh for all environment variables
  2. Expansion is correct — when "${common_make_envs[@]}" expands in the env -i command (line 87), each array element becomes a separate argument to env, which correctly parses VAR='value' syntax
  3. Proven by build success — the build log shows Rust compilation succeeded. If RUST_LIB_SRC contained literal quotes as part of the value, the kernel build would fail with "rust-src not found" because it wouldn't find /usr/src/rustc-1.85.1/library

Why changing it would be wrong:

  • Removing quotes only from RUST_LIB_SRC creates inconsistency with the rest of common_make_envs
  • The current implementation handles paths with spaces correctly (though /usr/src/rustc-*/library never contains spaces in practice)
  • @Q operator suggestion doesn't apply here — that's for common_make_params_quoted, not common_make_envs

The logged command output (RUST_LIB_SRC='/usr/src/...') is just string representation for display — the actual environment variable is set correctly without literal quotes.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 11, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify the quoting pattern in common_make_envs array in kernel-make.sh
cat lib/functions/compilation/kernel-make.sh | grep -A 20 "common_make_envs=(" | head -40

Length of output: 1289


@iav, you're absolutely correct—thank you for the detailed explanation and for taking the time to clarify this!

I've now verified lib/functions/compilation/kernel-make.sh and can confirm that the "VAR='${value}'" pattern is indeed the established convention used consistently throughout the common_make_envs array. My previous comment was incorrect, and I apologize for the confusion.

Your implementation of "RUST_LIB_SRC='${rust_lib_src}'" follows the exact same pattern as all the other environment variables (CCACHE_BASEDIR, CCACHE_TEMPDIR, PATH, etc.), and as you noted, the successful build logs prove it works correctly with the env -i command.

I appreciate you providing this context—it helps me better understand the framework's conventions going forward.


✏️ Learnings added
Learnt from: iav
URL: https://github.com/armbian/build/pull/9386

Timestamp: 2026-02-11T07:41:11.846Z
Learning: In lib/functions/compilation/kernel-make.sh, the common_make_envs array uses a consistent quoting pattern where each element is formatted as "VAR='${value}'" with embedded single quotes. This pattern works correctly with the `env -i` command and should be maintained for consistency across all environment variables added to common_make_envs, including RUST_LIB_SRC.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: rpardini
Repo: armbian/build PR: 9159
File: config/sources/families/genio.conf:201-201
Timestamp: 2026-01-03T20:44:12.559Z
Learning: In the Armbian build system, when calling run_host_command_logged with arrays containing arguments that have shell metacharacters (e.g., semicolons, pipes), use "${array[*]Q}" instead of "${array[@]}". This is because run_host_command_logged executes via `bash -c "$*"`, and the Q operator shell-quotes each element to prevent bash from interpreting special characters as command separators or other shell syntax.

Learnt from: tabrisnet
Repo: armbian/build PR: 0
File: :0-0
Timestamp: 2025-08-30T06:48:09.091Z
Learning: In lib/functions/compilation/armbian-kernel.sh, the user prefers flexible grep patterns over anchored ones for BTRFS configuration checks, but agrees to use quiet grep (-q) to avoid polluting build logs.

Learnt from: tabrisnet
Repo: armbian/build PR: 8661
File: lib/functions/compilation/armbian-kernel.sh:194-199
Timestamp: 2025-09-25T18:37:00.330Z
Learning: In PR armbian/build#8661, line 235 of lib/functions/compilation/armbian-kernel.sh already contains the corrected comment "BPF link support for netfilter hooks" for NETFILTER_BPF_LINK, not the misleading "BPF_SYSCALL" comment that was flagged during review.

Learnt from: tabrisnet
Repo: armbian/build PR: 8661
File: lib/functions/compilation/armbian-kernel.sh:194-199
Timestamp: 2025-09-25T18:37:00.330Z
Learning: In PR armbian/build#8661, line 235 of lib/functions/compilation/armbian-kernel.sh already contains the corrected comment "BPF link support for netfilter hooks" for NETFILTER_BPF_LINK, not the misleading "BPF_SYSCALL" comment that was flagged during review.

Learnt from: EvilOlaf
Repo: armbian/build PR: 0
File: :0-0
Timestamp: 2025-07-21T04:12:02.439Z
Learning: In the Armbian build system, for recurring maintenance tasks like kernel version bumping, TODO comments should use generic version formats (e.g., "MAJOR.MINOR-rc1") rather than specific version numbers (e.g., "6.17-rc1") to avoid the need for frequent comment updates that would create unnecessary maintenance overhead.

Learnt from: djurny
Repo: armbian/build PR: 8315
File: lib/functions/rootfs/distro-agnostic.sh:54-68
Timestamp: 2025-06-22T00:45:26.182Z
Learning: In Armbian build system, external command dependencies like envsubst are handled by adding the required packages (e.g., gettext for envsubst) to host_dependencies in adaptative_prepare_host_dependencies function in lib/functions/host/prepare-host.sh, rather than checking command availability at runtime.

Learnt from: tabrisnet
Repo: armbian/build PR: 0
File: :0-0
Timestamp: 2025-10-24T04:46:22.901Z
Learning: In lib/functions/rootfs/rootfs-create.sh, the FIXME comment about mmdebstrap usage with --aptopt is a future note related to PR `#8785`, which hasn't been merged yet.

Learnt from: glneo
Repo: armbian/build PR: 8913
File: config/sources/families/include/k3_common.inc:57-60
Timestamp: 2025-11-11T20:56:20.303Z
Learning: In config/sources/families/include/k3_common.inc, the OP-TEE build command at line 59 should be updated in a future PR to explicitly set CROSS_COMPILE64=aarch64-linux-gnu- and CROSS_COMPILE32=arm-linux-gnueabihf- instead of relying on OP-TEE's internal defaults, for better clarity and maintainability. User glneo agreed to address this in a separate PR.

Learnt from: amazingfate
Repo: armbian/build PR: 8419
File: lib/functions/host/prepare-host.sh:272-275
Timestamp: 2025-07-23T10:01:41.310Z
Learning: In the Armbian build system, the design philosophy is to fail fast when host dependencies are not met rather than gracefully skipping unsupported architectures. This ensures build environment consistency and prevents silent failures. Host dependency checks should be explicit and non-negotiable.

Learnt from: igorpecovnik
Repo: armbian/build PR: 9087
File: .github/workflows/pr-check-pictures.yml:138-146
Timestamp: 2025-12-16T13:40:07.649Z
Learning: In the Armbian build repository, when introducing new requirements or checks (like the board assets verification workflow), the project prefers an initial educational-only period where violations post helpful PR comments and warnings but don't block merges. This allows contributors to become familiar with new requirements before enforcement is enabled (typically after ~6 months).

@EvilOlaf
Copy link
Member

Noble-updates is present and used. packages were mostly up to date before trying. Nothing rust-related after updating.
before the build there were no rust-related packages installed, the extension did this.

# Rust version for APT method. Available in noble-security/noble-updates.
# Kernel >= 6.12 requires rustc >= 1.78. See:
# https://launchpad.net/ubuntu/noble/+package/cargo-1.85
RUST_APT_VERSION="1.85"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these will need to [be able to] be overridden in LINUXFAMILY [unless we start having config files per LINUX_MAJOR_MINOR]
at which point we may also need a build-distro check vs these versions.
@coderabbitai

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash

# Search for how family.conf files set version-related variables
echo "=== Searching for version variables in family configs ==="
rg -n -C2 'APT_VERSION|KERNEL_MAJOR_MINOR|VERSION=' --type=sh config/sources/families/ | head -80

echo -e "\n=== Searching for examples of variables overridden in family configs ==="
rg -n -C2 'LINUXFAMILY.*override|family.*override' --type=sh lib/ | head -40

echo -e "\n=== Check how extensions access LINUXFAMILY or kernel version ==="
rg -n -C2 '\$LINUXFAMILY|\$KERNEL_MAJOR_MINOR' --type=sh extensions/ | head -60

echo -e "\n=== Look for distro-dependent package selection patterns ==="
rg -n -C3 'DISTRIB|distro.*version|release.*version' --type=sh lib/functions/host/ | head -60

Length of output: 3209


🏁 Script executed:

#!/bin/bash

# Find KERNEL_MAJOR_MINOR definition and usage
echo "=== KERNEL_MAJOR_MINOR definition and usage ==="
rg -n -C3 'KERNEL_MAJOR_MINOR=' --type=sh lib/ | head -80

echo -e "\n=== Check the full kernel-rust.sh extension to see all version variables ==="
fd -t f 'kernel-rust.sh' extensions/ --exec cat {} | head -100

echo -e "\n=== Look for how extensions can access board/family variables ==="
rg -n -C3 'declare.*BOARD|declare.*FAMILY' --type=sh extensions/ | head -60

echo -e "\n=== Search for patterns of conditional version handling ==="
rg -n -C2 'if.*version|case.*version' --type=sh extensions/*.sh | head -80

Length of output: 12299


🏁 Script executed:

#!/bin/bash

# Check extension initialization order and how they interact with family configs
echo "=== Extension hook execution order and family config interaction ==="
rg -n -C5 'extension.*hook|call_extension' --type=sh lib/functions/configuration/main-config.sh | head -100

echo -e "\n=== Search for family.conf examples that might set extension-related variables ==="
rg -n -C3 'ENABLE_EXTENSIONS|extension' --type=sh config/sources/families/*.conf config/sources/families/*.inc 2>/dev/null | head -80

echo -e "\n=== Check if extensions can be conditionally configured based on variables ==="
rg -n -C5 'KERNEL_MAJOR_MINOR|if.*BRANCH|if.*FAMILY' --type=sh extensions/*.sh | head -100

echo -e "\n=== Look for examples of variable defaults that can be overridden ==="
rg -n -C2 ':-.*}.*#.*override|:=.*}.*#.*override|\${.*:-' --type=sh extensions/*.sh | head -80

Length of output: 15687


🏁 Script executed:

#!/bin/bash

# Fixed regex: Look for variable defaults that can be overridden
echo "=== Variable defaults in extensions (:-) pattern ==="
rg -n '\$\{[A-Z_]+:-' --type=sh extensions/ | head -80

echo -e "\n=== Check extension_prepare_config hooks for variable handling ==="
rg -n -A10 'function extension_prepare_config' --type=sh extensions/ | head -100

echo -e "\n=== Look for how variables are preserved if pre-set ==="
rg -n -C3 'preserve|pre-set|override' --type=sh extensions/ | head -80

echo -e "\n=== Check the kernel-rust.sh extension fully to see all variable declarations ==="
cat extensions/kernel-rust.sh | grep -n -E '^[A-Z_]+=' | head -30

Length of output: 19955


@tabrisnet, you're absolutely right to flag this. The hardcoded RUST_APT_VERSION and BINDGEN_APT_VERSION values would prevent family-specific or kernel-version-specific overrides.

Looking at the code, I can see that:

  1. LLVM_APT_VERSION already uses the override pattern (line 62):

    LLVM_APT_VERSION="${LLVM_APT_VERSION:-20}"

    This allows it to be pre-set before the extension runs.

  2. RUST_APT_VERSION and BINDGEN_APT_VERSION are hardcoded (lines 21, 27), which prevents overriding.

  3. Extensions run AFTER family configs are sourced, so family configs can set variables that extensions will see.

  4. Other extensions already handle version-dependent requirements - for example, v4l2loopback-dkms and radxa-aic8800 check KERNEL_MAJOR_MINOR and skip installation for incompatible kernel versions.

Suggested changes:

# Lines 21 and 27 should become:
RUST_APT_VERSION="${RUST_APT_VERSION:-1.85}"
BINDGEN_APT_VERSION="${BINDGEN_APT_VERSION:-0.71}"

This would allow:

  • Family-level overrides: Family configs could set these before the extension runs
  • Build-distro checks: The extension could conditionally set defaults based on HOSTRELEASE
  • Kernel-version-specific logic: Could add checks like if linux-version compare "${KERNEL_MAJOR_MINOR}" ge 6.19 to adjust versions

For build-distro compatibility, the extension could also add logic similar to what exists in lib/functions/host/prepare-host.sh to handle distro-specific package availability.


🧠 Learnings used
Learnt from: EvilOlaf
Repo: armbian/build PR: 0
File: :0-0
Timestamp: 2025-08-02T05:46:10.664Z
Learning: In the Armbian build system, the modern recommended approach for kernel configuration is to use the kernel-config command via "./compile.sh BOARD=boardname BRANCH=branchname kernel-config" instead of the deprecated KERNEL_CONFIGURE=yes flag. This provides a two-step workflow: configure using menuconfig, then build, with better transparency and control over configuration changes.

Learnt from: Grippy98
Repo: armbian/build PR: 8152
File: lib/functions/configuration/interactive.sh:209-266
Timestamp: 2025-05-05T12:35:07.143Z
Learning: For the interactive kernel selection in Armbian, KERNEL_MAJOR_MINOR and KERNEL_DESCRIPTION are parsed from family.conf but deliberately not set as environment variables to avoid potential interference with other parts of the build system.

Learnt from: EvilOlaf
Repo: armbian/build PR: 0
File: :0-0
Timestamp: 2025-07-21T04:12:02.439Z
Learning: In the Armbian build system, for recurring maintenance tasks like kernel version bumping, TODO comments should use generic version formats (e.g., "MAJOR.MINOR-rc1") rather than specific version numbers (e.g., "6.17-rc1") to avoid the need for frequent comment updates that would create unnecessary maintenance overhead.

Learnt from: tabrisnet
Repo: armbian/build PR: 8913
File: config/sources/families/k3-beagle.conf:16-16
Timestamp: 2025-11-10T22:05:40.490Z
Learning: In the Armbian build system, kernel branches using non-mainline/vendor forks (like BeagleBoard's linux repository) should be named "vendor" or "vendor-rt" rather than "current" or "edge". The "current" and "edge" naming is reserved for mainline kernel branches. This affects both the case statement in family config files (e.g., `vendor | vendor-rt)` instead of `current | current-rt)`) and the corresponding KERNEL_TARGET declarations in board config files.

Learnt from: EvilOlaf
Repo: armbian/build PR: 8330
File: config/sources/families/sun55iw3.conf:32-36
Timestamp: 2025-06-25T03:40:52.109Z
Learning: In Armbian build system configuration files like config/sources/families/*.conf, when KERNELSOURCE is not explicitly declared in a case branch, the system falls back to a default KERNELSOURCE value, so missing KERNELSOURCE declarations are not critical issues.

Learnt from: igorpecovnik
Repo: armbian/build PR: 8849
File: config/boards/radxa-e54c.csc:14-28
Timestamp: 2025-11-02T20:49:56.719Z
Learning: In Armbian board configuration files (config/boards/*.conf, *.csc, etc.), do not use kernel_config_set, kernel_config_set_m, kernel_config_set_y, or custom_kernel_config__* functions to modify kernel configuration. Kernel configuration is associated with LINUXFAMILY/BOARDFAMILY, not individual BOARD. Board-specific kernel modifications cause inconsistency in kernel packages published to the apt repository because boards within a family share the same kernel packages. Kernel configuration changes must be made in the appropriate kernel config file (e.g., config/kernel/linux-*-*.config) or in family configuration files (config/sources/families/*.conf, *.inc) instead.

Learnt from: EvilOlaf
Repo: armbian/build PR: 8330
File: config/sources/families/sun55iw3.conf:32-36
Timestamp: 2025-06-25T03:42:09.086Z
Learning: In Armbian build system configuration files like config/sources/families/*.conf, KERNELSOURCE is explicitly declared when using unofficial or 3rd party kernel repositories (like the "dev" branch using https://github.com/apritzel/linux), but can be omitted when using the standard mainline kernel (like the "edge" branch) since it will fall back to the default mainline source.

@rpardini
Copy link
Member

We all knew this was coming, but I wonder if it's too soon for Rust stuff. We've enough on our plates without it. Any practical use-case already? (Otherwise it's a lot of work, which will invariably change, for little benefit). I don't oppose, just wonder.

@iav
Copy link
Contributor Author

iav commented Feb 11, 2026

No, there was no immediate, specific goal; it was an attempt to "prepare for the future." Well, and I wanted to see what it would be like there, in the future.
It turned out to be a great example of how getting something that works is 15%. And then 85% is making it work reliably.

You're probably right. Nothing bad will happen if we wait another 2-3 months, but there will almost certainly be more certainty and clarity.
What really sparked my enthusiasm was the introduction bindgen in Ubuntu LTS, specifically for the current kernel. And, of course, the official announcement that Rust will stay in the kernel.

@rpardini
Copy link
Member

Yeah, maybe the "exciting" Rust stuff is still out of tree (eg tyr)?

Ref the complexity, maybe it is more related to clang + rust than gcc + rust? We could for now just say "you wanna Rust then use gcc") is that decreases the complexity...

@iav
Copy link
Contributor Author

iav commented Feb 11, 2026

tyr there, I build it already. But have no way to run it.
tyr-gpu.sh

@iav
Copy link
Contributor Author

iav commented Feb 12, 2026

During the implementation of this extension, almost all the complexity was related to coordinating rustc versions, packages, and libraries, taking into account what could be installed from the repositories available on the build machine. And even then, in the end, everything fell into place in the correct chain for me, but for some reason for you it didn’t.
Installing simply by downloading from the rust and cargo homepages requires just a few commands and no checks.
But then this is done at every launch, since we have no way to add such a script to the build container creation script, and I did not dare to introduce a mechanism for such a hook.

iav and others added 2 commits February 13, 2026 00:57
Add extension that enables CONFIG_RUST in kernel menuconfig and
configures the build environment (rustc, rustfmt, bindgen, rust-src)
using versioned APT packages from noble-security/noble-updates.

Handles env -i in run_kernel_make_internal by passing tool paths
via RUSTC, RUSTFMT, BINDGEN make params and RUST_LIB_SRC env var.

Includes optional RUST_KERNEL_SAMPLES=yes for building sample
Rust modules (rust_minimal, rust_print, rust_driver_faux) as a
toolchain smoke test.

Tested: kernel 6.19 build for rockchip64 on aarch64, both with
and without Docker.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
bindgen-0.71 links against libclang-20, but the extension was
installing unversioned clang (18 on noble). This caused:
- kernel "libclang version does not match Clang's" warning
- CC=ccache clang (18) overriding LLVM=-20 on make command line

Changes:
- Auto-detect LLVM version from bindgen's dependency chain,
  resolving versioned (bindgen-0.71 → libclang-20-dev) and
  unversioned (bindgen → libclang-dev → libclang-NN-dev) paths.
  Tested on Ubuntu 24.04, Debian Trixie, Ubuntu 25.10, 26.04.
- Install clang-VER/lld-VER/llvm-VER instead of unversioned.
- Replace LLVM=1 → LLVM=-VER and CC=ccache clang → CC=ccache
  clang-VER in make params so the entire toolchain is consistent.
- Use _apt_pick() to prefer versioned packages (rustc-1.85) on
  noble, falling back to unversioned (rustc) on Debian/newer Ubuntu.
- Override artifact hash _T key with actual clang version, without
  modifying kernel-version-toolchain extension.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@iav
Copy link
Contributor Author

iav commented Feb 12, 2026

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

02 Milestone: First quarter release Framework Framework components Needs review Seeking for review size/large PR with 250 lines or more

Development

Successfully merging this pull request may close these issues.

4 participants