Re: [meta-virtualization] [PATCH 2/2] image-oci: drop *-initial sysroot deps in do_image_oci to avoid libgcc collision
Bruce Ashfield <[email protected]> Tue, 28 Jul 2026 20:17:17 -0700 (PDT)
| Newsgroups | org.yoctoproject.lists.meta-virtualization |
|---|---|
| Message-ID | <[email protected]> |
Reviewed but holding this one for a bit. Two things:
First, on the fix mechanism: the analysis in the commit message is
convincing and matches what oe-core already does for do_sdk_depends
and do_populate_sdk_ext at staging.bbclass:457 (same "*-initial" skip,
same reason).
If that list of tasks was extendible, we could add do_image_oci to it,
but Richard wouldn't think it was a good idea if I tried to bury a
meta-virt task into that list :)
BitBake's python-function :prepend/:append doesn't help either -- the
mid-loop condition operates on setscenedeps built inside the function,
not on anything we could pre-filter via a prepend body. Prefunc +
BB_TASKDEPDATA mutation looks like the only path that won't need to
be updated as bitbake/oe-core change.
I'm testing a smaller-footprint variant of the same approach -- same
idea, same event-handler attachment, roughly 15 lines without the
deep-copy (setVar with a fresh dict is enough since
extend_recipe_sysroot re-reads BB_TASKDEPDATA on each entry).
Body/mechanism identical to yours; the trim is stylistic.
Second, and this is what's actually blocking: I haven't managed
to reproduce the raw abort locally. From your cover letter, it
doesn't sound like you are there yet either ? Without a repro that
fails on stock and passes with the fix, all we've got is "the code
path runs and does what the comment says it does" -- which is true
but doesn't prove the payoff. Eventually that might be enough, but
I'd like to try a bit more.
Two questions to unblock:
1) Can you share the specific recipe (or the DEPENDS shape) from
the downstream build where you hit this deterministically?
Something along the lines of a multilayer packages: layer
pulling a from-source-compiled library with a boost-ish
DEPENDS, if I'm reading your cover right, but I'd rather work
from your actual trigger than guess.
2) Was there anything else in that build environment worth
knowing -- IMAGE_PKGTYPE pin, non-default MACHINE, a specific
PACKAGECONFIG that pulled in one of the *-initial-adjacent
recipes? Anything that narrows the search.
I'll try a boost-multilayer-packages recipe over several clean-sstate
cycles in the meantime and report back either way. Once we have that,
merging this (in whichever variant) is easy.
Below is the shortened variant I mentioned -- meant to fully replace
the two python blocks + the comment header in your 2/2, drop-in on the
same insertion point in image-oci.bbclass. Same mechanism as yours:
event handler on RecipeTaskPreProcess attaches a prefunc to
do_image_oci that filters *-initial do_populate_sysroot nodes out of
BB_TASKDEPDATA before extend_recipe_sysroot walks it. Differences are
stylistic -- no deep-copy (dict comprehension builds a fresh dict
directly), set comprehension for the drop set, comment made smaller.
Not requesting a v2 on this; posting so you can try it against your
downstream trigger and see if it holds up the same way your original
does.
# =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D
# Work around libgcc vs libgcc-initial sysroot collision in do_image_oci
# =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D
#
# do_image_oci[depends] contains "...:do_populate_sysroot" entries, so
# oe-core's staging_taskhandler auto-attaches extend_recipe_sysroot as a
# prefunc. That walk exposes the full transitive populate_sysroot closure
# into this recipe's private sysroot -- including both libgcc and
# libgcc-initial, which collide on crtbegin.o.
#
# oe-core's SSTATE_EXCLUDEDEPS_SYSROOT (".*->.*-initial.*") is gated on
# the consuming task being do_populate_sysroot (see setscene_depvalid()
# in sstate.bbclass); for do_image_oci that gate is False and the
# exclusion is skipped. extend_recipe_sysroot itself has a hardcoded
# "*-initial" skip but only for do_sdk_depends / do_populate_sdk_ext
# (staging.bbclass:457) -- an oe-core task allow-list we can't cleanly
# extend from a downstream layer.
#
# Filter *-initial do_populate_sysroot nodes out of BB_TASKDEPDATA before
# extend_recipe_sysroot walks it. extend_recipe_sysroot re-reads
# BB_TASKDEPDATA on each entry, so a setVar with the filtered dict is
# sufficient.
python oci_strip_initial_taskdepdata () {
tdd =3D d.getVar("BB_TASKDEPDATA", False)
if not tdd:
return
drop =3D {k for k, v in tdd.items()
if v[1] =3D=3D "do_populate_sysroot" and v[0].endswith("-initial"=
)}
if not drop:
return
filtered =3D {k: v for k, v in tdd.items() if k not in drop}
for v in filtered.values():
v[3].difference_update(drop)
d.setVar("BB_TASKDEPDATA", filtered)
bb.note("OCI: dropped %d *-initial node(s) to avoid libgcc collision" % l=
en(drop))
}
oci_strip_initial_taskdepdata[vardepsexclude] +=3D "BB_TASKDEPDATA"
python oci_attach_strip_prefunc () {
task =3D "do_image_oci"
if task in e.tasklist:
deps =3D d.getVarFlag(task, "depends")
if deps and "populate_sysroot" in deps:
d.prependVarFlag(task, "prefuncs", "oci_strip_initial_taskdepdata=
")
}
oci_attach_strip_prefunc[eventmask] =3D "bb.event.RecipeTaskPreProcess"
addhandler oci_attach_strip_prefunc
Bruce