Skip to content

extensions: skip DKMS modules on kernels built with clang - #10600

Open
igorpecovnik wants to merge 1 commit into
mainfrom
fix/no-dkms-on-clang-kernels
Open

igorpecovnik wants to merge 1 commit into
mainfrom
fix/no-dkms-on-clang-kernels

Conversation

@igorpecovnik

@igorpecovnik igorpecovnik commented Sep 2, 2026

Copy link
Copy Markdown
Member

TL;DR — Xiaomi-sheng images fail because DKMS can't build against a clang/ThinLTO kernel: the headers correctly advertise clang, DKMS invokes it, and clang isn't in the rootfs. Gate DKMS extensions on a new KERNEL_DKMS_BUILDABLE instead of failing the build.

The failure

armbian/ci run 33517020634, Xiaomi-sheng gnome + kde:

DKMS make.log for v4l2loopback/0.15.3 for kernel 7.1.8-edge-sm8550-sheng
# command: make ... v4l2loopback LLVM=1
The kernel was built by: Debian clang version 19.1.7
You are using:
/bin/sh: 1: clang: not found
make[4]: *** [v4l2loopback.o] Error 127

Cause

sm8550-sheng.conf sets KERNEL_COMPILER="clang", and kernel-debs.sh deliberately preserves CONFIG_CC_IS_CLANG in the headers package (the sidecar tarball added for #9425) so the headers describe the kernel as actually compiled. Both are correct — and together they mean DKMS selects LLVM=1, while clang is installed in no Armbian rootfs.

Note this is not the same bug as the one fixed in 3c077ad35. That scoped LLVM=1 to the kernel make so it stopped leaking into the linux-headers postinst. DKMS reaches the identical wall by a different route: it reads the shipped headers rather than inheriting the environment.

And nothing about it is specific to v4l2loopback — any of the ten DKMS extensions hits it on such a kernel.

Change

A gate, KERNEL_DKMS_BUILDABLE, computed once in config_post_main and consulted by all ten DKMS extensions next to the KERNEL_HAS_WORKING_HEADERS check they already share.

Why a separate variable. The headers package here is genuinely fine. Folding this into KERNEL_HAS_WORKING_HEADERS would also stop the linux-headers deb being built and change the kernel artifact package map — hence the artifact hash — invalidating caches and removing headers from users who might install clang themselves.

Why skip rather than ship the toolchain. gcc is not a fallback: these kernels set CONFIG_LTO_CLANG/CONFIG_LTO_CLANG_THIN, and gcc-built modules cannot link against a ThinLTO kernel. Installing the toolchain would cost ~270 MB (libllvm19 122, llvm-19 69, libclang-cpp19 66, lld-19 5) and would still have to keep matching the kernel's clang major on every future kernel upgrade. Skipping mirrors the kernel ≥ 7.2 cutoff v4l2loopback-dkms already carries.

The visible effect is that sheng images lose v4l2loopback (virtual camera). They currently build no image at all.

Verification

compile.sh configdump against real boards:

Board Branch KERNEL_COMPILER KERNEL_DKMS_BUILDABLE KERNEL_HAS_WORKING_HEADERS
xiaomi-sheng edge 7.1 clang no yes (unchanged)
orangepi5-max edge 7.2 aarch64-linux-gnu- yes yes (unchanged)

So gcc-built boards are untouched and the headers deb still ships on sheng. bash -n clean across all extensions.

Related

The other failures in that run are Orange Pi 5 Max / bcmdhd on 7.2, fixed separately and released as bcmdhd-dkms 101.10.591.52.27-8, which extensions/bcmdhd.sh picks up automatically.

Summary by CodeRabbit

  • Bug Fixes
    • DKMS-based driver and module extensions now detect kernels that cannot build DKMS modules and skip incompatible installation steps.
    • Added clear warnings explaining why DKMS components were not installed.
    • Prevented failed driver builds and related package installation attempts on clang/LLVM-built kernels.
    • Existing header and kernel capability checks continue to be honored across supported extensions.

@coderabbitai

coderabbitai Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Team

Run ID: 057f2266-aade-4724-8cd5-a9370264b47e

📥 Commits

Reviewing files that changed from the base of the PR and between 48d9f40 and 7ef7e52.

📒 Files selected for processing (11)
  • extensions/bcmdhd-spacemit.sh
  • extensions/bcmdhd.sh
  • extensions/brostrend-aic8800-dkms.sh
  • extensions/nvidia.sh
  • extensions/photonicat-pm.sh
  • extensions/r8125-dkms.sh
  • extensions/radxa-aic8800.sh
  • extensions/v4l2loopback-dkms.sh
  • extensions/yt6801.sh
  • extensions/zfs.sh
  • lib/functions/main/config-prepare.sh
🚧 Files skipped from review as they are similar to previous changes (11)
  • extensions/nvidia.sh
  • lib/functions/main/config-prepare.sh
  • extensions/r8125-dkms.sh
  • extensions/brostrend-aic8800-dkms.sh
  • extensions/radxa-aic8800.sh
  • extensions/zfs.sh
  • extensions/yt6801.sh
  • extensions/photonicat-pm.sh
  • extensions/v4l2loopback-dkms.sh
  • extensions/bcmdhd-spacemit.sh
  • extensions/bcmdhd.sh

Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review.


📝 Walkthrough

Walkthrough

The build configuration now marks clang-built kernels as unable to build DKMS modules. Ten DKMS extensions use this state to skip header preparation, package installation, module builds, and autodetection when required.

Changes

DKMS buildability gating

Layer / File(s) Summary
Kernel DKMS buildability state
lib/functions/main/config-prepare.sh
config_post_main initializes KERNEL_DKMS_BUILDABLE and KERNEL_DKMS_UNBUILDABLE_REASON. Clang-built kernels receive an unbuildable state and reason.
DKMS extension installation gates
extensions/bcmdhd*.sh, extensions/brostrend-aic8800-dkms.sh, extensions/nvidia.sh, extensions/photonicat-pm.sh, extensions/r8125-dkms.sh, extensions/radxa-aic8800.sh, extensions/v4l2loopback-dkms.sh, extensions/yt6801.sh, extensions/zfs.sh
Configuration and post-install hooks now require KERNEL_DKMS_BUILDABLE=yes. Skipped paths report KERNEL_DKMS_UNBUILDABLE_REASON where applicable, and affected descriptions document the clang/LLVM condition.

Estimated code review effort: 2 (Simple) | ~15 minutes

Merge Risk: ⚪ Minimal · up to 7ef7e

The change skips DKMS extensions for kernels that cannot build them with the available toolchain while preserving kernel headers; no actionable merge-blocking risk remains beyond normal checks and review.

Sequence Diagram(s)

sequenceDiagram
  participant config_post_main
  participant DKMSExtensionHooks
  participant KernelPackageInstallation
  config_post_main->>DKMSExtensionHooks: Publish DKMS buildability state
  DKMSExtensionHooks->>KernelPackageInstallation: Skip unsupported DKMS operations
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 22 functions across 11 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: skipping DKMS modules for kernels built with clang.
  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/no-dkms-on-clang-kernels

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.

@github-actions github-actions Bot added size/medium PR with more then 50 and less then 250 lines 11 Milestone: Fourth quarter release Needs review Seeking for review Hardware Hardware related like kernel, U-Boot, ... Framework Framework components Patches Patches related to kernel, U-Boot, ... labels Sep 2, 2026
Xiaomi-sheng desktop images fail to build. v4l2loopback's DKMS build dies
immediately:

    DKMS make.log for v4l2loopback/0.15.3 for kernel 7.1.8-edge-sm8550-sheng
    # command: make ... v4l2loopback LLVM=1
    The kernel was built by: Debian clang version 19.1.7
    /bin/sh: 1: clang: not found
    make[4]: *** [v4l2loopback.o] Error 127

sm8550-sheng sets KERNEL_COMPILER="clang", and kernel-debs.sh deliberately
preserves CONFIG_CC_IS_CLANG in the headers package (via the sidecar tarball
added for #9425) so the headers describe the kernel as actually compiled. That
is correct, and it is also why DKMS then selects LLVM=1 -- but clang is not
installed in any Armbian rootfs, so no out-of-tree module can be built.

Nothing here is specific to v4l2loopback: any DKMS extension hits the same wall
on such a kernel. Add a gate, KERNEL_DKMS_BUILDABLE, computed once in
config_post_main and consulted by all ten DKMS extensions alongside the
KERNEL_HAS_WORKING_HEADERS check they already share.

Deliberately a separate variable rather than folding this into
KERNEL_HAS_WORKING_HEADERS. The headers package is genuinely fine here -- the
postinst clang leak was already fixed in 3c077ad -- and flipping that flag
would also stop the linux-headers deb being built and change the kernel
artifact package map, hence the artifact hash, invalidating caches and dropping
headers for users who may want to install clang themselves.

Skipping rather than shipping the toolchain: gcc is not a fallback, because
these kernels set CONFIG_LTO_CLANG/CONFIG_LTO_CLANG_THIN and gcc-built modules
cannot link against a ThinLTO kernel. Installing clang/lld/llvm in the image
would cost ~270MB (libllvm19 122MB, llvm-19 69MB, libclang-cpp19 66MB, lld-19
5MB) and would still have to keep matching the kernel's clang major across
future kernel upgrades. This mirrors the kernel >= 7.2 cutoff v4l2loopback-dkms
already carries.

Verified with `compile.sh configdump` on real boards:

  xiaomi-sheng   edge 7.1  KERNEL_COMPILER=clang
                           KERNEL_DKMS_BUILDABLE=no
                           KERNEL_HAS_WORKING_HEADERS=yes   (unchanged)
  orangepi5-max  edge 7.2  KERNEL_COMPILER=aarch64-linux-gnu-
                           KERNEL_DKMS_BUILDABLE=yes
                           KERNEL_HAS_WORKING_HEADERS=yes   (unchanged)

so gcc-built boards are untouched and the headers deb still ships on sheng.
Descriptions updated on the five extensions whose @description already
enumerates skip conditions. bash -n clean across all extensions.

Signed-off-by: Igor Pecovnik <igor@armbian.com>
@igorpecovnik
igorpecovnik force-pushed the fix/no-dkms-on-clang-kernels branch from 4570b31 to 7ef7e52 Compare September 2, 2026 07:39
@rpardini

rpardini commented Sep 2, 2026

Copy link
Copy Markdown
Member

Hmm. Avoiding it could be, but it seems to me the clang stuff needs to be able to modify the linux-headers debian/control to depend on clang instead of build-essential -- way more intricate, but that would allow clang-built headers to work everywhere. Or would it?

@iav for awareness

@igorpecovnik

Copy link
Copy Markdown
Member Author

You're right that the Depends line is the actual problem — kernel-debs.sh hardcodes gcc for every kernel, clang-built ones included.

But sheng is the only kernel we build with clang, and I don't think fixing the dependency gets us "works everywhere". clang is distro-defined and we ship the same kernel across several distros; it's not just needing clang, it's needing a matching major (this one is Debian clang 19.1.7), plus lld and LLVM binutils because of ThinLTO. Where the distro's clang doesn't line up, DKMS breaks on the user's device rather than in CI. And it's ~270 MB in every image for something most users never use. Recommends: would soften that, but not the version problem.

So I'd rather skip DKMS on clang kernels for now. The two aren't exclusive: even with proper clang deps you'd want the skip as a fallback where the toolchain doesn't match.

@iav

iav commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

The gcc dep is a single flat literal at kernel-debs.sh:557 (the linux-headers control). KERNEL_COMPILER is already known at packaging time and kernel-make.sh (:40, :129) branches on == "clang", and a conditional-Depends idiom already exists at armbian-bsp-cli-deb.sh:288 (${EXTRA_BSPDEPS:+, …}). So swapping the literal gcc for a KERNEL_COMPILER-derived token (gcc, or clang+lld+llvm) is cheap. It doesn't replace the skip gate — it composes with it: on its own it won't "work everywhere" (clang major match, lld, ThinLTO), but it stops dragging gcc onto a clang kernel. Suggestion: keep the skip and additionally make the headers compiler-dependency conditional.

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

Labels

11 Milestone: Fourth quarter release Framework Framework components Hardware Hardware related like kernel, U-Boot, ... Needs review Seeking for review Patches Patches related to kernel, U-Boot, ... size/medium PR with more then 50 and less then 250 lines

Development

Successfully merging this pull request may close these issues.

3 participants