toolchain/toolchain-external: introduce BR2_TOOLCHAIN_EXTERNAL_UPDATE_LINUX_HEADERS
PATCH v2 1/1 toolchain/toolchain-external: introduce BR2_TOOLCHAIN_EXTERNAL_UPDATE_LINUX_HEADERS
This change makes it possible to update kernel headers in the external toolchain with the headers from the current kernel.
It is important to have matching kernel headers when building packages that make use of kernel features such as seccomp, as they depend on system call definitions in linux/unistd.h. A typical example of this is openssh - building it with the official ARM GNU toolchain and kernel 6.x results in a non-working sshd.
Currently restricted to glibc-based toolchains as glibc is backward- and forward-compatible with different kernel versions while uClibc and musl are not.
---
Changes v1 -> v2:
- Restrict the option to glibc-based toolchains.
- Improve commit message.
- Restore the check-kernel-headers call in linux-headers.mk.
- Install the headers into the toolchain explicitly instead of copying over all staging headers.
- Remove the loose version check option as it doesn't seem necessary.
--- package/linux-headers/Config.in | 2 ++ package/linux-headers/linux-headers.mk | 3 ++- toolchain/Config.in | 4 ++++ toolchain/helpers.mk | 4 +--- toolchain/toolchain-buildroot/Config.in | 2 -- toolchain/toolchain-external/Config.in | 12 ++++++++++++ .../pkg-toolchain-external.mk | 19 ++++++++++++++++++- 7 files changed, 39 insertions(+), 7 deletions(-)
package/linux-headers/Config.in +2 -0
@@ -1,2 +1,4 @@ config BR2_PACKAGE_LINUX_HEADERS bool + # Can be selected by internal toolchains or external toolchains needing updated headers + default y if BR2_TOOLCHAIN_BUILDROOT
package/linux-headers/linux-headers.mk +2 -1
@@ -5,7 +5,8 @@ ################################################################################ # This package is used to provide Linux kernel headers for the -# internal toolchain backend. +# internal toolchain backend and for external toolchains that need +# updated kernel headers. # Set variables depending on whether we are using headers from a kernel # build or a standalone header package.
toolchain/Config.in +4 -0
@@ -68,6 +68,10 @@ source "toolchain/toolchain-external/Config.in" # so put it here instead source "package/gdb/Config.in.host" +# Linux headers can be used by both internal and external toolchains +source "package/linux-headers/Config.in.host" +source "package/linux-headers/Config.in" + comment "Toolchain Generic Options" # https://sourceware.org/bugzilla/show_bug.cgi?id=30730
toolchain/helpers.mk +1 -3
@@ -169,11 +169,9 @@ copy_toolchain_sysroot = \ # $2: sysroot directory # $3: kernel version string, in the form: X.Y # $4: test to do for the latest kernel version, 'strict' or 'loose' -# always 'strict' if this is not the latest version. # check_kernel_headers_version = \ - if ! support/scripts/check-kernel-headers.sh $(1) $(2) $(3) \ - $(if $(BR2_TOOLCHAIN_HEADERS_LATEST),$(4),strict); \ + if ! support/scripts/check-kernel-headers.sh $(1) $(2) $(3) $(4) ; \ then \ exit 1; \ fi
toolchain/toolchain-buildroot/Config.in +0 -2
@@ -108,8 +108,6 @@ config BR2_TOOLCHAIN_BUILDROOT_LIBC default "glibc" if BR2_TOOLCHAIN_BUILDROOT_GLIBC default "musl" if BR2_TOOLCHAIN_BUILDROOT_MUSL -source "package/linux-headers/Config.in.host" -source "package/linux-headers/Config.in" source "package/musl/Config.in" source "package/uclibc/Config.in" source "package/glibc/Config.in"
toolchain/toolchain-external/Config.in +12 -0
@@ -125,4 +125,16 @@ config BR2_TOOLCHAIN_EXTERNAL_GDB_SERVER_COPY Copy the gdbserver provided by the external toolchain to the target. +config BR2_TOOLCHAIN_EXTERNAL_UPDATE_LINUX_HEADERS + bool "Update kernel headers" + # Restrict this option to glibc, as uClibc and musl should probably + # be rebuilt when updating kernel headers. + depends on BR2_TOOLCHAIN_EXTERNAL_GLIBC + select BR2_PACKAGE_LINUX_HEADERS + help + Select this option to update the kernel headers in the + external toolchain with headers from the kernel being built. + This is useful when the external toolchain has older kernel + headers than the kernel being built. + endif # BR2_TOOLCHAIN_EXTERNAL
toolchain/toolchain-external/pkg-toolchain-external.mk +18 -1
@@ -542,6 +542,18 @@ define TOOLCHAIN_EXTERNAL_INSTALL_TARGET_LDD fi endef +define TOOLCHAIN_EXTERNAL_UPDATE_LINUX_HEADERS + echo "Updating kernel headers in the external toolchain..." ; \ + SYSROOT_DIR="$(call toolchain_find_sysroot,$(TOOLCHAIN_EXTERNAL_CC))" ; \ + (cd $(LINUX_HEADERS_DIR); $(TARGET_MAKE_ENV) $(BR2_MAKE) \ + ARCH=$(KERNEL_ARCH) \ + HOSTCC="$(HOSTCC)" \ + HOSTCFLAGS="$(HOSTCFLAGS)" \ + HOSTCXX="$(HOSTCXX)" \ + INSTALL_HDR_PATH=$${SYSROOT_DIR}/usr \ + headers_install) +endef + ################################################################################ # inner-toolchain-external-package -- defines the generic installation rules # for external toolchain packages
@@ -573,6 +585,11 @@ $(2)_POST_EXTRACT_HOOKS += \ TOOLCHAIN_EXTERNAL_MOVE endif +ifeq ($$(BR2_TOOLCHAIN_EXTERNAL_UPDATE_LINUX_HEADERS),y) +$(2)_DEPENDENCIES += linux-headers +$(2)_PRE_CONFIGURE_HOOKS += TOOLCHAIN_EXTERNAL_UPDATE_LINUX_HEADERS +endif + # Checks for an already installed toolchain: check the toolchain # location, check that it is usable, and then verify that it # matches the configuration provided in Buildroot: ABI, C++ support,
@@ -585,7 +602,7 @@ define $(2)_CONFIGURE_CMDS $$(BUILD_DIR),\ $$(call toolchain_find_sysroot,$$(TOOLCHAIN_EXTERNAL_CC)),\ $$(call qstrip,$$(BR2_TOOLCHAIN_HEADERS_AT_LEAST)),\ - $$(if $$(BR2_TOOLCHAIN_EXTERNAL_CUSTOM),loose,strict)); \ + $$(if $$(or $$(BR2_TOOLCHAIN_EXTERNAL_CUSTOM),$$(BR2_TOOLCHAIN_EXTERNAL_UPDATE_LINUX_HEADERS)),loose,strict)); \ $$(call check_gcc_version,$$(TOOLCHAIN_EXTERNAL_CC),\ $$(call qstrip,$$(BR2_TOOLCHAIN_GCC_AT_LEAST))); \ if test "$$(BR2_arm)" = "y" ; then \
Signature · 6 lines
2.39.5 _______________________________________________ buildroot mailing list [email protected] https://lists.buildroot.org/mailman/listinfo/buildroot
Hello Rustam,
Thanks for your patch!
Quoted 5 lines · On Sat, 27 Dec 2025 21:14:15 +0000 Rustam Abdullaev <[email protected]> wrote:
It is important to have matching kernel headers when building packages that make use of kernel features such as seccomp, as they depend on system call definitions in
linux/unistd.h. A typical example of this is openssh - building it with the official ARM GNU toolchain and kernel 6.x results in a non-working sshd.
Do you have more details on this? Which version of the ARM GNU toolchain? Which kernel header version do they use? Which kernel version are you running?
Indeed, there are two cases:
- The kernel headers in the toolchain are newer than the kernel you're running => you are doing it wrong, and updating the headers in the toolchain are not going to fix the fact that your C library is built with headers that are too recent for your kernel (even though I admit glibc has some tolerance on this)
- The kernel headers in the toolchain are older than the kernel you're running and you're seeing breakage => this is a kernel bug as it shouldn't happen.
In both cases, your proposed patch should therefore not be needed.
Could you clarify which situation you're in, so that we can understand better whether the use-case/issue you're having warrants this additional complexity?
Quoted 3 lines
Currently restricted to glibc-based toolchains as glibc is backward- and forward-compatible with different kernel versions while uClibc and musl are not.
Not sure why this matters here though. Could you clarify?
Thanks!
Thomas
Signature · 7 lines
Thomas Petazzoni, co-owner and CEO, Bootlin Embedded Linux and Kernel engineering and training https://bootlin.com _______________________________________________ buildroot mailing list [email protected] https://lists.buildroot.org/mailman/listinfo/buildroot
Quoted 2 lines · Thomas Petazzoni
Hello Rustam,
Hi Thomas,
Quoted 12 lines
Thanks for your patch!
Quoted 5 lines · On Sat, 27 Dec 2025 21:14:15 +0000 Rustam Abdullaev <[email protected]> wrote:
It is important to have matching kernel headers when building packages that make use of kernel features such as seccomp, as they depend on system call definitions in
linux/unistd.h. A typical example of this is openssh - building it with the official ARM GNU toolchain and kernel 6.x results in a non-working sshd.
Quoted 4 lines
Do you have more details on this? Which version of the ARM GNU toolchain? Which kernel header version do they use? Which kernel version are you running?
This applies to the official ARM GNU toolchain up to and including 14.3:
https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads
They come with kernel headers 4.20.
I'm running kernel 6.12. Though that doesn't matter, what matters is that it's virtually guaranteed that the actual kernel is going to be newer than 4.20.
Quoted 9 lines
Indeed, there are two cases:
- The kernel headers in the toolchain are newer than the kernel you're running => you are doing it wrong, and updating the headers in the toolchain are not going to fix the fact that your C library is built with headers that are too recent for your kernel (even though I admit glibc has some tolerance on this)
Yes, this wouldn't work at all, we're not planning to downgrade linux headers, only upgrade.
Quoted 5 lines
- The kernel headers in the toolchain are older than the kernel you're running and you're seeing breakage => this is a kernel bug as it shouldn't happen.
I think you're referring to the fact that linux kernel is backward-compatible. That is only true in theory. In practice not matching the actual kernel version can lead to various issues, among others, security issues with seccomp.
In both cases, your proposed patch should therefore not be needed.
Quoted 5 lines
Could you clarify which situation you're in, so that we can understand better whether the use-case/issue you're having warrants this additional complexity?
To give a concrete example, 64-bit time system calls that were added in 5.1 are automatically used by glibc (even if it was built against 4.20 kernel which didn't have these). Applications that set up a seccomp sandbox (e.g. sshd) won't be able to whitelist the needed system calls correctly because they don't exist in linux/unistd.h.
Here's a minimal repro:
cat <<EOM >>configs/qemu_arm_vexpress_defconfig
BR2_TOOLCHAIN_EXTERNAL=y
BR2_PACKAGE_OPENSSH=y
EOM
make distclean
make qemu_arm_vexpress_defconfig
make -j$(nproc)
output/images/start-qemu.sh
. . .
Welcome to Buildroot
buildroot login: root
#
# ssh localhost Connection reset by 127.0.0.1 port 22 #
^ notice sshd not working at all.
This is just an example, we had more issues elsewhere in our codebase. Another downside is performance as application are unable to use the latest kernel features for better efficiency and security (cgroups v2, new bpf features, etc).
So it's quite important to match the kernel headers to the actual kernel being used.
Regarding the complexity, I would say it's quite low - it's a fairly small addition that re-uses most of the existing mechanisms and simply installs the kernel headers into the external toolchain.
Quoted 6 lines
Currently restricted to glibc-based toolchains as glibc is backward- and
Quoted 2 lines
forward-compatible with different kernel versions while uClibc and musl are not.
Not sure why this matters here though. Could you clarify?
This is just a safeguard to prevent issues. From personal experience, uClibc and musl sometimes run into issues unless they are compiled for the specific linux version on which they run.
So this feature is only usable in combination with glibc.
Quoted 7 lines
Thanks!
Thomas
--
Thomas Petazzoni, co-owner and CEO, Bootlin Embedded Linux and Kernel engineering and training
https://bootlin.com
Hope this clarifies,
Regards,
Rustam
_______________________________________________
buildroot mailing list
[email protected]
https://lists.buildroot.org/mailman/listinfo/buildroot
Hi ALL,
Quoted 7 lines · Rustam
Quoted 2 lines · Thomas Petazzoni
Hello Rustam,
Hi Thomas,
[...]
Quoted 11 lines
Quoted 6 lines
Currently restricted to glibc-based toolchains as glibc is backward- and
Quoted 2 lines
forward-compatible with different kernel versions while uClibc and musl are not.
Not sure why this matters here though. Could you clarify?
This is just a safeguard to prevent issues. From personal experience, uClibc and musl sometimes run into issues unless they are compiled for the specific linux version on which they run.
So this feature is only usable in combination with glibc.
Actually this suggestion came from me. I have Buildroot build my toolchains, using uClibc and musl. I occasionally had problems when switching kernel versions and forgetting to rebuild everything. This might be a dependency issue, not directly related to the toolchain, but since Rustam only tested this using glibc, the restriction seems appropriate.
Quoted 9 lines
Quoted 8 lines
Thanks!
Thomas
--
Thomas Petazzoni, co-owner and CEO, Bootlin Embedded Linux and Kernel engineering and training
https://bootlin.com
Quoted 3 lines
Hope this clarifies,
Regards,
Rustam
Kind regards,
Andreas
_______________________________________________
buildroot mailing list
[email protected]
https://lists.buildroot.org/mailman/listinfo/buildroot
Hi Thomas, Rustam,
Quoted 35 lines · Thomas Petazzoni via buildroot
Hello Rustam,
Thanks for your patch!
Quoted 5 lines · On Sat, 27 Dec 2025 21:14:15 +0000 Rustam Abdullaev <[email protected]> wrote:
It is important to have matching kernel headers when building packages that make use of kernel features such as seccomp, as they depend on system call definitions in
linux/unistd.h. A typical example of this is openssh - building it with the official ARM GNU toolchain and kernel 6.x results in a non-working sshd.Do you have more details on this? Which version of the ARM GNU toolchain? Which kernel header version do they use? Which kernel version are you running?
Indeed, there are two cases:
- The kernel headers in the toolchain are newer than the kernel you're running => you are doing it wrong, and updating the headers in the toolchain are not going to fix the fact that your C library is built with headers that are too recent for your kernel (even though I admit glibc has some tolerance on this)
- The kernel headers in the toolchain are older than the kernel you're running and you're seeing breakage => this is a kernel bug as it shouldn't happen.
In both cases, your proposed patch should therefore not be needed.
Could you clarify which situation you're in, so that we can understand better whether the use-case/issue you're having warrants this additional complexity?
Quoted 5 lines
Quoted 3 lines
Currently restricted to glibc-based toolchains as glibc is backward- and forward-compatible with different kernel versions while uClibc and musl are not.
Not sure why this matters here though. Could you clarify?
We ran into the same issue with the pre-compiled toolchain from ARM. We needed the CAN J1939 socket support in python, and python enables this based on tests done on the installed kernel headers.
Since the J1939 support landed after Linux 4.20 we ended up spending some hours figuring out how python enabled the CAN J1939 socket support.
Having the ability to use kernel headers from the selected kernel would alleviate such problems where the project depends on the installed kernel headers to enable / disable features.
Unless the python package is broken instead and should bundle the necessary headers rather than depending on them being provided by the toolchain?
Best regards // John Ernberg
_______________________________________________
buildroot mailing list
[email protected]
https://lists.buildroot.org/mailman/listinfo/buildroot
Hello John, Rustam, All,
Le 02/02/2026 à 14:41, John Ernberg via buildroot a écrit :
Quoted 51 lines
Hi Thomas, Rustam,
Quoted 35 lines · Thomas Petazzoni via buildroot
Hello Rustam,
Thanks for your patch!
Quoted 5 lines · On Sat, 27 Dec 2025 21:14:15 +0000 Rustam Abdullaev <[email protected]> wrote:
It is important to have matching kernel headers when building packages that make use of kernel features such as seccomp, as they depend on system call definitions in
linux/unistd.h. A typical example of this is openssh - building it with the official ARM GNU toolchain and kernel 6.x results in a non-working sshd.Do you have more details on this? Which version of the ARM GNU toolchain? Which kernel header version do they use? Which kernel version are you running?
Indeed, there are two cases:
- The kernel headers in the toolchain are newer than the kernel you're running => you are doing it wrong, and updating the headers in the toolchain are not going to fix the fact that your C library is built with headers that are too recent for your kernel (even though I admit glibc has some tolerance on this)
- The kernel headers in the toolchain are older than the kernel you're running and you're seeing breakage => this is a kernel bug as it shouldn't happen.
In both cases, your proposed patch should therefore not be needed.
Could you clarify which situation you're in, so that we can understand better whether the use-case/issue you're having warrants this additional complexity?
Quoted 5 lines
Quoted 3 lines
Currently restricted to glibc-based toolchains as glibc is backward- and forward-compatible with different kernel versions while uClibc and musl are not.
Not sure why this matters here though. Could you clarify?
We ran into the same issue with the pre-compiled toolchain from ARM. We needed the CAN J1939 socket support in python, and python enables this based on tests done on the installed kernel headers.
Since the J1939 support landed after Linux 4.20 we ended up spending some hours figuring out how python enabled the CAN J1939 socket support.
Quoted 7 lines
Having the ability to use kernel headers from the selected kernel would alleviate such problems where the project depends on the installed kernel headers to enable / disable features.
Unless the python package is broken instead and should bundle the necessary headers rather than depending on them being provided by the toolchain?
It reminds me the issue with openssh with the ARM toolchains:
"TestOpenSsh needs a toolchain >= 5.x due to a openssh issue (Similar to: https://bugs.busybox.net/show_bug.cgi?id=13671)
Use the Bootlin toolchain bleeding-edge 2022.08-1 rhat provide kernel headers 5.4"
https://gitlab.com/buildroot.org/buildroot/-/commit/f89f52168fcb667a3e8e43f6f44d5b1ca3961a8c
Can you try with this newer ARM toolchain that uses 6.6 linux-headers?
https://patchwork.ozlabs.org/project/buildroot/list/?series=495567
Best regards,
Romain
Quoted 6 lines
Best regards // John Ernberg
_______________________________________________
buildroot mailing list
[email protected]
https://lists.buildroot.org/mailman/listinfo/buildroot
_______________________________________________
buildroot mailing list
[email protected]
https://lists.buildroot.org/mailman/listinfo/buildroot