@@ -979,6 +979,10 @@ def copydebugsources(debugsrcdir, sources, d):
sdir = d.getVar("S")
cflags = d.expand("${CFLAGS}")
+ # prefixmap maps a host directory to a (match, dest) pair: "match" is
+ # the DWARF-recorded path prefix to select from debugsources.list,
+ # "dest" is the subdirectory under PKGD to copy matches to. For plain
+ # ${CFLAGS}-derived entries these are the same string.
prefixmap = {}
for flag in cflags.split():
if not flag.startswith("-ffile-prefix-map"):
@@ -986,7 +990,20 @@ def copydebugsources(debugsrcdir, sources, d):
if "recipe-sysroot" in flag:
continue
flag = flag.split("=")
- prefixmap[flag[1]] = flag[2]
+ prefixmap[flag[1]] = (flag[2], flag[2])
+
+ # kernel-arch.bbclass's KERNEL_CC remaps STAGING_KERNEL_DIR and
+ # STAGING_KERNEL_BUILDDIR to KERNEL_SRC_PATH ("/usr/src/kernel"),
+ # overriding CFLAGS' own mapping for the kernel, so its source files
+ # need a dedicated prefixmap entry to be found, still destined for
+ # TARGET_DBGSRC_DIR like everything else.
+ if bb.data.inherits_class('kernel-arch', d):
+ kernel_src_path = d.getVar('KERNEL_SRC_PATH')
+ target_dbgsrc_dir = d.getVar('TARGET_DBGSRC_DIR')
+ for kernel_dir_var in ('STAGING_KERNEL_DIR', 'STAGING_KERNEL_BUILDDIR'):
+ kernel_dir = d.getVar(kernel_dir_var)
+ if kernel_dir and kernel_src_path and target_dbgsrc_dir:
+ prefixmap[kernel_dir] = (kernel_src_path, target_dbgsrc_dir)
nosuchdir = []
basepath = dvar
@@ -1008,9 +1025,9 @@ def copydebugsources(debugsrcdir, sources, d):
and not path.endswith((b"<internal>", b"<built-in>"))
and b"recipe-sysroot" not in os.path.dirname(path)}
- for pmap, prefix in prefixmap.items():
- dstroot = dvar + prefix
- prefix_slash = os.fsencode(prefix) + b"/"
+ for pmap, (match, dest) in prefixmap.items():
+ dstroot = dvar + dest
+ prefix_slash = os.fsencode(match) + b"/"
relpaths = [path.removeprefix(prefix_slash) for path in sourcepaths
if path.startswith(prefix_slash)]
@@ -17,12 +17,13 @@ class FakeDataStore:
def __init__(self, values):
self.values = values
- def getVar(self, name):
+ def getVar(self, name, expand=True):
return self.values.get(name)
def expand(self, value):
for name, replacement in self.values.items():
- value = value.replace("${%s}" % name, replacement)
+ if isinstance(replacement, str):
+ value = value.replace("${%s}" % name, replacement)
return value
@@ -270,3 +271,72 @@ class TestCopyDebugSources(TestCase):
with open(copied_source) as f:
self.assertEqual(f.read(), "real\n")
self.assertFalse(os.path.exists(relocation))
+
+ def test_copydebugsources_recovers_kernel_source_files(self):
+ """Recovers kernel-arch source files recorded outside debugsrcdir.
+
+ kernel-arch recipes remap STAGING_KERNEL_DIR/BUILDDIR to
+ KERNEL_SRC_PATH (typically "/usr/src/kernel") via KERNEL_CC, bypassing
+ CFLAGS entirely, so debugsources.list records kernel files under
+ KERNEL_SRC_PATH rather than under debugsrcdir (typically
+ "/usr/src/debug/...") like every other CFLAGS-derived entry.
+
+ Simulates a kernel-arch recipe with one file coming from each of the
+ two remapped directories (a source file under STAGING_KERNEL_DIR and a
+ generated header under STAGING_KERNEL_BUILDDIR) and asserts
+ copydebugsources() recovers both into the normal debugsrcdir, proving
+ the dedicated kernel-arch prefixmap entries are used instead of (or in
+ addition to) the plain CFLAGS-derived ones.
+ """
+ with tempfile.TemporaryDirectory(prefix="oe-test-package-") as tmpdir:
+ kernel_src_dir = os.path.join(tmpdir, "kernel-source")
+ kernel_build_dir = os.path.join(tmpdir, "kernel-build-artifacts")
+ workdir = os.path.join(tmpdir, "work")
+ pkgd = os.path.join(tmpdir, "pkgd")
+ debugsrcdir = "/usr/src/debug/kernel/1.0"
+ kernel_src_path = "/usr/src/kernel"
+
+ src_rel = os.path.join("arch", "main.c")
+ build_rel = os.path.join("include", "generated", "autoconf.h")
+
+ os.makedirs(os.path.dirname(os.path.join(kernel_src_dir, src_rel)))
+ os.makedirs(os.path.dirname(os.path.join(kernel_build_dir, build_rel)))
+ os.makedirs(workdir)
+ os.makedirs(pkgd)
+
+ src_file = os.path.join(kernel_src_dir, src_rel)
+ build_file = os.path.join(kernel_build_dir, build_rel)
+ with open(src_file, "w") as f:
+ f.write("main\n")
+ with open(build_file, "w") as f:
+ f.write("autoconf\n")
+
+ sources = [
+ os.path.join(kernel_src_path, src_rel),
+ os.path.join(kernel_src_path, build_rel),
+ ]
+ d = FakeDataStore({
+ "WORKDIR": workdir,
+ "PKGD": pkgd,
+ "STRIP": "strip",
+ "OBJCOPY": "objcopy",
+ "S": kernel_src_dir,
+ # KERNEL_CC's own -ffile-prefix-map overrides this for the
+ # kernel, so CFLAGS carries no entry for kernel_src_path.
+ "CFLAGS": "",
+ "__inherit_cache": ["/layer/classes-recipe/kernel-arch.bbclass"],
+ "STAGING_KERNEL_DIR": kernel_src_dir,
+ "STAGING_KERNEL_BUILDDIR": kernel_build_dir,
+ "KERNEL_SRC_PATH": kernel_src_path,
+ "TARGET_DBGSRC_DIR": debugsrcdir,
+ })
+
+ copydebugsources(debugsrcdir, sources, d)
+
+ copied_src = oe.path.join(pkgd, debugsrcdir, src_rel)
+ copied_build = oe.path.join(pkgd, debugsrcdir, build_rel)
+
+ with open(copied_src) as f:
+ self.assertEqual(f.read(), "main\n")
+ with open(copied_build) as f:
+ self.assertEqual(f.read(), "autoconf\n")