diff mbox series

[RFC,02/08] kernel.bbclass: stage a manifest of the source files the build read

Message ID 20261106173235.4155305-3-bruce.ashfield@gmail.com
State New
Headers show
Series enhance kernel -devsrc output options | expand

Commit Message

Bruce Ashfield Nov. 6, 2026, 5:32 p.m. UTC
From: Bruce Ashfield <bruce.ashfield@gmail.com>

kernel-devsrc packages from the shared work directories and can't see the
kernel's ${B}, so it has no way to know which parts of the tree the
kernel for a given MACHINE was built from. kbuild already records that:
every .cmd file lists the source and headers the compiler read for its
object.

Collect those paths (relative to ${S}) in do_shared_workdir, after the
build, into kernel-source-files in STAGING_KERNEL_BUILDDIR. kernel-devsrc
can then package the source needed to debug a kernel built for a specific
MACHINE, without copying the whole tree.

The new kernel_source_manifest function does it in three steps, and leaves
each intermediate list in the recipe's temporary directory, so a wrong
manifest can be traced back:

  - the .cmd files whose savedcmd starts with ${HOST_PREFIX} (the target
    compiler, optionally through ccache). Host programs (scripts/mod,
    scripts/kconfig, objtool) are built with the host compiler, and are
    not part of the kernel.
  - every path under ${S} those files name.
  - the paths normalized with realpath, since some sources are included
    with ../ (kernel/bpf includes tools/lib/bpf), and kept only if they
    are regular files in ${S}.

Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
---
 meta/classes-recipe/kernel.bbclass | 41 ++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)
diff mbox series

Patch

diff --git a/meta/classes-recipe/kernel.bbclass b/meta/classes-recipe/kernel.bbclass
index ab064bb085..f7910fbdee 100644
--- a/meta/classes-recipe/kernel.bbclass
+++ b/meta/classes-recipe/kernel.bbclass
@@ -538,6 +538,44 @@  emit_depmod_pkgdata() {
 
 PACKAGEFUNCS += "emit_depmod_pkgdata"
 
+# Print, relative to ${S}, the source files the target compiler read, from
+# kbuild's .cmd files. The intermediate lists are left in ${T}.
+kernel_source_manifest() {
+	(
+		cd ${B}
+		# The .cmd files hold millions of lines: a UTF-8 locale is ~40x slower
+		export LC_ALL=C
+
+		cmds=${T}/kernel-source-cmds
+		paths=${T}/kernel-source-paths
+
+		# The .cmd files of objects built with the target compiler, matching:
+		#   savedcmd_kernel/fork.o := x86_64-poky-linux-gcc -fuse-ld=bfd ...
+		#   savedcmd_kernel/fork.o := ccache x86_64-poky-linux-gcc ...
+		target_cc="^savedcmd_[^ ]+ := ([^ ]*ccache )?${HOST_PREFIX}"
+		find . -name '.*.cmd' -exec grep -l -E "$target_cc" {} + > $cmds
+
+		# Every path under ${S} they name, matching (dedup before the regex):
+		#   source_kernel/fork.o := ${S}/kernel/fork.c
+		#     ${S}/include/linux/types.h
+		#   ... -I${S}/include -include ${S}/include/linux/kconfig.h ...
+		# Directories and other non-files are dropped below.
+		xargs -r grep -hF "${S}/" < $cmds | sort -u | \
+			grep -o "${S}/[^ ]*" | sort -u > $paths
+
+		# Normalized relative to ${S}, for example:
+		#   ${S}/arch/x86/boot/compressed/../../../../lib/ctype.c -> lib/ctype.c
+		# and kept only if they are regular files inside ${S}.
+		xargs -r realpath -m --relative-to=${S} < $paths | \
+			grep -v '^\.\./' | sort -u | \
+			while read f; do
+				if [ -f "${S}/$f" ]; then
+					echo "$f"
+				fi
+			done
+	)
+}
+
 do_shared_workdir[cleandirs] += " ${STAGING_KERNEL_BUILDDIR}"
 do_shared_workdir () {
 	cd ${B}
@@ -605,6 +643,9 @@  do_shared_workdir () {
 		fi
 	fi
 
+	# The source files this kernel was built from, for kernel-devsrc
+	kernel_source_manifest > $kerneldir/kernel-source-files
+
 	# When building with CONFIG_MODVERSIONS=y and CONFIG_RANDSTRUCT=y we need
 	# to copy the build assets generated for the randstruct seed to
 	# STAGING_KERNEL_BUILDDIR, otherwise the out-of-tree modules build will