All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH RFC] parse/ast: add support for additive built-in fragments
@ 2026-09-01  7:52 Antonin Godard
  2026-09-01 12:15 ` [bitbake-devel] " Richard Purdie
  0 siblings, 1 reply; 5+ messages in thread
From: Antonin Godard @ 2026-09-01  7:52 UTC (permalink / raw)
  To: bitbake-devel; +Cc: Thomas Petazzoni, Antonin Godard

Add support for the following syntax specified in a fragment list
definition:

  fragmentname:VARIABLE:add

Setting this fragment appends to VARIABLE instead of setting its value.
This does not break pre-existing fragments which still set a variable's
value entirely.

For example, in OE-Core consider the following definition:

  OE_FRAGMENTS_BUILTIN = "class:INHERIT:add"

Then one could specify the following:

  OE_FRAGMENTS = "class/buildstats class/rm_work"

Which would result in appending " buildstats rm_work" to the INHERIT
variable.

This would also allow bitbake-setup configurations to come with a list
of pre-enabled classes, for example.

Note: The "add" suffix was chosen in the definition to avoid confusion
with the existing "append" usage in Bitbake.

Signed-off-by: Antonin Godard <antonin.godard@bootlin.com>
---
Note: The bitbake-config-build OE-Core utility would require adaptations
as it currently removes any pre-existing built-in fragment with the
same suffix. I can also send the associated OE-Core patches.

Note 2: We could also have these fragments specified as:

  OE_FRAGMENTS = "class/add/buildstats class/add/retain"

To avoid confusing them with original built-in fragments. While I
agree it disambiguates them from original built-ins, I also think from a
user point of view, being able to set:

  OE_FRAGMENTS = "machine/qemuarm distro/poky class/buildstats class/retain"

feels a bit more natural. Discussion is open :)
---
 lib/bb/parse/ast.py | 25 +++++++++++++++++++------
 1 file changed, 19 insertions(+), 6 deletions(-)

diff --git a/lib/bb/parse/ast.py b/lib/bb/parse/ast.py
index a372b3534e4..a828c49c937 100644
--- a/lib/bb/parse/ast.py
+++ b/lib/bb/parse/ast.py
@@ -367,12 +367,13 @@ class AddFragmentsNode(AstNode):
         def check_and_set_builtin_fragment(fragment, data, builtin_fragments):
             prefix, value = fragment.split('/', 1)
             if prefix in builtin_fragments.keys():
-                if data.getVar(builtin_fragments[prefix], noweakdefault=True) != None:
+                fragment_var, fragment_type = builtin_fragments[prefix][0], builtin_fragments[prefix][1]
+                if fragment_type == "set" and data.getVar(fragment_var, noweakdefault=True) is not None:
                     bb.fatal(
                         ("A builtin fragment '%s' is used while %s has already got an assignment.\n"
                          "Please either disable the fragment or remove the value assignment.\n"
                          "To disable the fragment, use 'bitbake-config-build disable-fragment %s'."
-                         ) % (fragment, builtin_fragments[prefix], fragment))
+                         ) % (fragment, fragment_var, fragment))
                 fragment_history = data.varhistory.variable(self.fragments_variable)
                 loginfo={}
                 for fh in fragment_history[::-1]:
@@ -381,15 +382,27 @@ class AddFragmentsNode(AstNode):
                         loginfo["line"]   = fh["line"]
                         loginfo["detail"] = f"{value} ({self.fragments_variable} contains \"{fragment}\")"
                         break
-                # parsing=True since we want to emulate X=Y and allow X:override=Z to continue to exist
-                data.setVar(builtin_fragments[prefix], value, parsing=True, **loginfo)
+                if fragment_type == "set":
+                    # parsing=True since we want to emulate X=Y and allow X:override=Z to continue to exist
+                    data.setVar(fragment_var, value, parsing=True, **loginfo)
+                elif fragment_type == "add":
+                    data.appendVar(fragment_var, f" {value.strip()}", **loginfo)
+                else:
+                    bb.fatal(f"Unknown fragment type '{fragment_type}' "
+                             f"(from '{prefix}:{fragment_var}:{fragment_type}' in {self.builtin_fragments_variable})")
                 return True
             return False
 
         fragments = data.getVar(self.fragments_variable)
         layers = data.getVar('BBLAYERS')
         flagged_variables = data.getVar(self.flagged_variables_list_variable).split()
-        builtin_fragments = {f[0]:f[1] for f in [f.split(':') for f in data.getVar(self.builtin_fragments_variable).split()] }
+        builtin_fragments = {}
+        for fragment in data.getVar(self.builtin_fragments_variable).split():
+            fragment = fragment.split(':')
+            builtin_fragments[fragment[0]] = (
+                fragment[1],
+                "set" if len(fragment) < 3 else fragment[2],
+            )
 
         if not fragments:
             return
@@ -402,7 +415,7 @@ class AddFragmentsNode(AstNode):
                     fragments.split(),
                 )
             )
-            if len(builtin_fragments_list) > 1:
+            if len(builtin_fragments_list) > 1 and not builtin_fragments[builtin_fragment_key][1] == "add":
                 bb.warn(
                     ("Multiple builtin fragments are enabled for %s via variable %s: %s. "
                      "This likely points to a mis-configuration in the metadata, as only "

---
base-commit: 18cca50ba3da5ce27bc674478957bb08e7536b9a
change-id: 20260827-appending-fragments-8a308ebdb633



^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-09-02  7:56 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-01  7:52 [PATCH RFC] parse/ast: add support for additive built-in fragments Antonin Godard
2026-09-01 12:15 ` [bitbake-devel] " Richard Purdie
2026-09-01 18:28   ` Alexander Kanavin
2026-09-01 19:22     ` Richard Purdie
2026-09-02  7:56       ` Antonin Godard

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.