diff mbox series

parse/ast: Add support for BB_RECIPE_VIRTUAL_PROVIDERS

Message ID 20250121152836.1829193-1-richard.purdie@linuxfoundation.org
State Accepted, archived
Commit fb119c7888ae8a749aa824f8c51780176af077f9
Headers show
Series parse/ast: Add support for BB_RECIPE_VIRTUAL_PROVIDERS | expand

Commit Message

Richard Purdie Jan. 21, 2025, 3:28 p.m. UTC
Currently, providers are set on a global config basis. This change allows
for a select set of providers configured in BB_RECIPE_VIRTUAL_PROVIDERS to
be selected on a per recipe basis. This would allow for the selection of
virtual/cross-cc as gcc or clang for example in OE-Core.

DEPENDS and task flag [depends] values are processed.

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
---
 lib/bb/parse/ast.py | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

Comments

Antonin Godard March 14, 2025, 8:11 a.m. UTC | #1
Hi,

On Tue Jan 21, 2025 at 4:28 PM CET, Richard Purdie via lists.openembedded.org wrote:
> Currently, providers are set on a global config basis. This change allows
> for a select set of providers configured in BB_RECIPE_VIRTUAL_PROVIDERS to
> be selected on a per recipe basis. This would allow for the selection of
> virtual/cross-cc as gcc or clang for example in OE-Core.
>
> DEPENDS and task flag [depends] values are processed.

I need to know if I understand this variable correctly (to document it).

I understand this as a list of virtual providers that are _allowed_ be
overridden from a recipe. So the default definition would only allow overriding
the cross compiler / binutils. Correct?

It only makes sense to set this variable globally, right?

Does it make sense to override this variable, or should the default definition
cover most use cases? I'm trying to think of other use-cases than overriding the
cross compiler / binutils, but don't see any... Not feeling very creative
though. I'm trying to get a sense of the original intent for this variable.

Thanks,
Antonin
diff mbox series

Patch

diff --git a/lib/bb/parse/ast.py b/lib/bb/parse/ast.py
index 30ede008d7..290ed45048 100644
--- a/lib/bb/parse/ast.py
+++ b/lib/bb/parse/ast.py
@@ -440,6 +440,30 @@  def runAnonFuncs(d):
         code.append("%s(d)" % funcname)
     bb.utils.better_exec("\n".join(code), {"d": d})
 
+# Handle recipe level PREFERRED_PROVIDERs
+def handleVirtRecipeProviders(tasklist, d):
+    depends = (d.getVar("DEPENDS") or "").split()
+    virtprovs = (d.getVar("BB_RECIPE_VIRTUAL_PROVIDERS") or "").split()
+    newdeps = []
+    for dep in depends:
+        if dep in virtprovs:
+            newdep = d.getVar("PREFERRED_PROVIDER_" + dep)
+            if not newdep:
+                 bb.fatal("Error, recipe virtual provider PREFERRED_PROVIDER_%s not set" % dep)
+            newdeps.append(newdep)
+        else:
+            newdeps.append(dep)
+    d.setVar("DEPENDS", " ".join(newdeps))
+    for task in tasklist:
+        taskdeps = (d.getVarFlag(task, "depends") or "").split()
+        remapped = []
+        for entry in taskdeps:
+            r, t = entry.split(":")
+            if r in virtprovs:
+                r = d.getVar("PREFERRED_PROVIDER_" + r)
+            remapped.append("%s:%s" % (r, t))
+        d.setVarFlag(task, "depends", " ".join(remapped))
+
 def finalize(fn, d, variant = None):
     saved_handlers = bb.event.get_handlers().copy()
     try:
@@ -465,6 +489,7 @@  def finalize(fn, d, variant = None):
 
         tasklist = d.getVar('__BBTASKS', False) or []
         bb.event.fire(bb.event.RecipeTaskPreProcess(fn, list(tasklist)), d)
+        handleVirtRecipeProviders(tasklist, d)
         bb.build.add_tasks(tasklist, d)
 
         bb.parse.siggen.finalise(fn, d, variant)