meta: kernel: Make specifying KERNEL_CONFIG_FRAGMENTS more flexible

Message ID f8937fee-2491-49ed-9086-7be1f481a60a@siemens.com
State Under Review
Headers show
Series meta: kernel: Make specifying KERNEL_CONFIG_FRAGMENTS more flexible | expand

Commit Message

Jan Kiszka March 23, 2026, 7:03 a.m. UTC
From: Jan Kiszka <jan.kiszka@siemens.com>

This allows to add kernel config fragments from other sources than just
individual files in SRC_URI.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---

isar-cip-core will first use this, currently externalizing part of its 
in-tree fragments to the cip-kernel-config repo.

 RECIPE-API-CHANGELOG.md                       |  9 +++++
 meta/classes-recipe/linux-kernel.bbclass      | 37 ++++++++++++-------
 .../linux/files/debian/isar/configure.tmpl    |  2 +-
 3 files changed, 33 insertions(+), 15 deletions(-)

Patch

diff --git a/RECIPE-API-CHANGELOG.md b/RECIPE-API-CHANGELOG.md
index e44b4b9d..2eff4fc3 100644
--- a/RECIPE-API-CHANGELOG.md
+++ b/RECIPE-API-CHANGELOG.md
@@ -972,3 +972,12 @@  we introduce the variables ``MMAPTOPT_NOEXPKEYSIGN`` and ``DISTRO_MM_OPTS``.
 While the former provides an argument to disable the key expiry checking, the
 latter allows users to inject custom options into ``mmdebstrap``. For details,
 see ``man mmdebstrap``. Use with care!
+
+### Provide additional fragments via KERNEL_CONFIG_FRAGMENTS
+
+Custom kernel builds can now inject config fragments into the build which were
+not provided via individual SRC_URI entries. If a kernel source tree contains a
+fragment, this can be specified via adding `${S}/path/to/fragment.cfg` to
+`KERNEL_CONFIG_FRAGMENTS`. If a fragment was checked out into ${WORKDIR} as
+part of a repository, a tarball, or some other directory structure, just
+specify it relative to ${WORKDIR} in `KERNEL_CONFIG_FRAGMENTS`.
diff --git a/meta/classes-recipe/linux-kernel.bbclass b/meta/classes-recipe/linux-kernel.bbclass
index 6e383408..9429996f 100644
--- a/meta/classes-recipe/linux-kernel.bbclass
+++ b/meta/classes-recipe/linux-kernel.bbclass
@@ -83,7 +83,7 @@  TEMPLATE_VARS += "                \
     KERNEL_LIBC_DEV_ARCH          \
     LINUX_VERSION_EXTENSION       \
     KERNEL_NAME_PROVIDED          \
-    KERNEL_CONFIG_FRAGMENTS       \
+    KCONFIG_FRAGMENTS             \
     KCFLAGS                       \
     KAFLAGS                       \
     DISTRIBUTOR                   \
@@ -214,8 +214,10 @@  KERNEL_ARCH ??= "${@get_kernel_arch(d)}"
 # set KERNEL_FILE without depending on package arch used in bitbake.conf
 KERNEL_FILE:forcevariable = "${@ 'vmlinux' if d.getVar('KERNEL_ARCH') in ['mipsel', 'riscv', 'arm64'] else 'vmlinuz'}"
 
+KERNEL_CONFIG_FRAGMENTS ?= ""
+
 def config_fragments(d):
-    fragments = []
+    fragments = d.getVar('KERNEL_CONFIG_FRAGMENTS').split()
     sources = d.getVar("SRC_URI").split()
     for s in sources:
         _, _, local, _, _, parm = bb.fetch.decodeurl(s)
@@ -284,17 +286,21 @@  def get_kernel_config_target(d):
 
     return config_target
 
-def get_kernel_config_fragments(d):
-    src_frags = " ".join(config_fragments(d))
-    out_frags = " ".join(map(lambda frag: 'debian/fragments/' + frag, config_fragments(d)))
-
-    linux_version_extension = d.getVar('LINUX_VERSION_EXTENSION')
-    if linux_version_extension:
-        out_frags += " debian/isar/version.cfg"
+KERNEL_CONFIG_FRAGMENTS:append = " \
+    ${@'${S}/debian/isar/version.cfg' if d.getVar('LINUX_VERSION_EXTENSION') else ''}"
 
-    return out_frags
+def get_kernel_config_fragments(d):
+    out_frags = ""
+    S = d.getVar('S') + '/'
+    for frag in config_fragments(d):
+        if frag.startswith(S):
+            out_frags += ' ' + frag[len(S):]
+        else:
+            out_frags += ' debian/fragments/' + frag
+    return out_frags.strip()
 
-KERNEL_CONFIG_FRAGMENTS = "${@get_kernel_config_fragments(d)}"
+# internal list of config fragments
+KCONFIG_FRAGMENTS = "${@get_kernel_config_fragments(d)}"
 
 dpkg_configure_kernel() {
 	grep -q "KERNEL_CONFIG_TARGET=" ${S}/debian/isar/configure ||
@@ -313,9 +319,12 @@  EOF
 	src_frags="${@ " ".join(config_fragments(d)) }"
 	rm -rf ${S}/debian/fragments
 	for frag in ${src_frags}; do
-		basedir=$(dirname ${frag})
-		mkdir -p ${S}/debian/fragments/${basedir}
-		cp ${WORKDIR}/${frag} ${S}/debian/fragments/${basedir}/
+		# skip frag if it starts with ${S}, thus is part of the sources
+		if [ "${frag#${S}}" = "$frag" ]; then
+			basedir=$(dirname ${frag})
+			mkdir -p ${S}/debian/fragments/${basedir}
+			cp ${WORKDIR}/${frag} ${S}/debian/fragments/${basedir}/
+		fi
 	done
 }
 
diff --git a/meta/recipes-kernel/linux/files/debian/isar/configure.tmpl b/meta/recipes-kernel/linux/files/debian/isar/configure.tmpl
index 73f554ed..75c920b8 100644
--- a/meta/recipes-kernel/linux/files/debian/isar/configure.tmpl
+++ b/meta/recipes-kernel/linux/files/debian/isar/configure.tmpl
@@ -26,7 +26,7 @@  do_configure() {
         # Process kernel config target and fragments
         ${MAKE} O=${KERNEL_BUILD_DIR} ${KERNEL_CONFIG_TARGET}
         ./scripts/kconfig/merge_config.sh -O ${KERNEL_BUILD_DIR}/ \
-            ${KERNEL_BUILD_DIR}/.config ${KERNEL_CONFIG_FRAGMENTS}
+            ${KERNEL_BUILD_DIR}/.config ${KCONFIG_FRAGMENTS}
     fi
 
     # Stop tracing