Re: [bitbake-devel] [PATCH 1/1] data_smart: fix operations lost when an override name contains a variable
Richard Purdie <[email protected]> Sun, 26 Jul 2026 13:21:44 +0100
| Newsgroups | org.openembedded.lists.bitbake-devel |
|---|---|
| Message-ID | <dd3a79ae52d3d42959ee98c1b6e1d3df4c0a2dee.camel@linuxfoundation.org> |
On Sat, 2026-07-25 at 21:30 +0700, Zk47T via lists.openembedded.org wrote:
> An operation whose override name needs key expansion is silently dropped:
>=20
> =C2=A0=C2=A0=C2=A0 RDEPENDS:${PN}:append:pn-foo-${MACHINE} =3D " bar"
>=20
> renameVar() rebuilds the dependent override keys with a plain string
> replace, so renaming RDEPENDS:${PN} leaves the append attached to
> RDEPENDS:foo:append:pn-foo-${MACHINE}, which never matches an active
> override. expandKeys() cannot fix that up afterwards either, as it works
> from a list of keys collected before any renaming happened.
>=20
> Expand the derived name before renaming it. Only do so once newkey is
> itself expanded, otherwise expandKeys() has still to rename newkey and
> handles the dependent keys along with it.
>=20
> Add regression tests for both cases.
>=20
> Fixes [YOCTO #14867]
>=20
> Signed-off-by: Nguyen Minh Tien <[email protected]>
> ---
> =C2=A0lib/bb/data_smart.py | 11 +++++++++--
> =C2=A0lib/bb/tests/data.py | 25 +++++++++++++++++++++++++
> =C2=A02 files changed, 34 insertions(+), 2 deletions(-)
>=20
> diff --git a/lib/bb/data_smart.py b/lib/bb/data_smart.py
> index 9961269a3..5738aff95 100644
> --- a/lib/bb/data_smart.py
> +++ b/lib/bb/data_smart.py
> @@ -697,8 +697,15 @@ class DataSmart(MutableMapping):
> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 =
found =3D True
> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 =
self.overridedata[newkey] =3D []
> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 =
for (v, o) in self.overridedata[key]:
> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 self.overridedata[newkey].append([v.replace(key, newkey)=
, o])
> -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 self.renameVar(v, v.replace(key, newkey))
> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 newv =3D v.replace(key, newkey)
> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 # The derived name may still hold a variable reference w=
hich
> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 # expandKeys() will never revisit, so expand it here. On=
ly once
> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 # newkey is expanded though, otherwise expandKeys() has =
still to
> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 # rename newkey and handles the dependent keys along wit=
h it.
> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 if '${' in newv and '${' not in newkey:
> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 newv =3D self.expand(newv)
> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 self.overridedata[newkey].append([newv, o])
> +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 self.renameVar(v, newv)
> =C2=A0
Thanks for the patch and the test cases. I had a deeper look at this as
I was a bit puzzled how this would work without your patch:
XYZ =3D "yocto"
ABC =3D "123"
ABC:append:pn-linux-${XYZ} =3D " 456"
$ bitbake-getvar -r linux-yocto ABC
ABC=3D"123 456"
as if the code can handle that, it should be able to handle the other
case too. I think this is because expandKeys() calls renameVar and then
renameVar itself also calls renameVar() on the same element, which
breaks things. That means that if you do:
diff --git a/lib/bb/data.py b/lib/bb/data.py
index 5fdcdb04a..e3af12a35 100644
--- a/lib/bb/data.py
+++ b/lib/bb/data.py
@@ -94,7 +94,7 @@ def expandKeys(alterdata, readdata =3D None):
val =3D alterdata.getVar(key, False)
if val is not None:
bb.warn("Variable key %s (%s) replaces original key %s (%s=
)." % (key, val, ekey, newval))
- alterdata.renameVar(key, ekey)
+ alterdata.renameVar(key, ekey, recurse=3DFalse)
=20
def inheritFromOS(d, savedenv, permitted):
"""Inherit variables from the initial environment."""
diff --git a/lib/bb/data_smart.py b/lib/bb/data_smart.py
index 110dfa111..78ff9b961 100644
--- a/lib/bb/data_smart.py
+++ b/lib/bb/data_smart.py
@@ -661,7 +661,7 @@ class DataSmart(MutableMapping):
def getVar(self, var, expand=3DTrue, noweakdefault=3DFalse, parsing=3D=
False):
return self.getVarFlag(var, "_content", expand, noweakdefault, par=
sing)
=20
- def renameVar(self, key, newkey, **loginfo):
+ def renameVar(self, key, newkey, recurse=3DTrue, **loginfo):
"""
Rename the variable key to newkey
"""
@@ -693,7 +693,8 @@ class DataSmart(MutableMapping):
self.overridedata[newkey] =3D []
for (v, o) in self.overridedata[key]:
self.overridedata[newkey].append([v.replace(key, newkey), =
o])
- self.renameVar(v, v.replace(key, newkey))
+ if recurse:
+ self.renameVar(v, v.replace(key, newkey))
=20
if ':' in newkey and val is None:
self._setvar_update_overrides(newkey, **loginfo)
then I think that resolve the issue? It would also perhaps resolve an
issue where a variable with three different key expansions in it might
not work! I'm less sure that three different key variables would work
with plain renameVar, that may also need to set the "no recurse"
option, I'm not sure.
Could you see if this makes sense to you?
Cheers,
Richard