diff mbox series

[1/5] base: Add deferred class event handler

Message ID 20250612135955.1413300-1-richard.purdie@linuxfoundation.org
State New
Headers show
Series [1/5] base: Add deferred class event handler | expand

Commit Message

Richard Purdie June 12, 2025, 1:59 p.m. UTC
Use the new deferred class event to set the class overrides earlier.
This improves interaction of the override with PACKAGECONFIG values
that control conditional inherits (such as python support).

This also allows toolchain configuration in an easier and more user
friendly way.

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
---
 meta/classes-global/base.bbclass | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

Comments

Richard Purdie June 13, 2025, 10:16 a.m. UTC | #1
On Thu, 2025-06-12 at 14:59 +0100, Richard Purdie via lists.openembedded.org wrote:
> This implements a toolchain selection mechanism, defaulting to gcc
> as per the existing defaults.
> 
> Introduce a variable called TOOLCHAIN, which denotes the familiar
> name for toolchain e.g. "gcc" which selects GNU compiler + binutils
> as default C/C++ toolchain or "clang" which will use LLVM/Clang Compiler
> 
> TOOLCHAIN variable has a global fallback to "gcc" in configuration
> metadata. A distro can switch to using say "clang" as default system
> compiler by defining
> 
> TOOLCHAIN ?= "clang"
> 
> In local.conf or other distro specific global configuration metadata
> 
> It is also selectable at recipe scope, since not all packages are
> buildable with either clang or gcc, a recipe can explicitly demand
> a given toolchain e.g. glibc can not be built with clang therefore
> glibc recipe sets.
> 
> TOOLCHAIN = "gcc"

We have a problem with this patch. Initially, Khem was reporting
problems along the lines of setting:

TOOLCHAIN ?= "clang"

in local.conf and then gdb-cross-XXX reporting clang in OVERRIDES but
CC being set to gcc. The reason for that is that cross sets CC to
BUILD_CC and we don't change BUILD_CC to match TOOLCHAIN, at least not
yet.

The fix is to force cross recipes to "gcc", at least for now. That
works in most cases with the change in this patch:

>  inherit metadata_scm
>  
> +TOOLCHAIN ??= "gcc"
> +TOOLCHAIN:class-native ??= "gcc"
> +TOOLCHAIN:class-cross ??= "gcc"
> +TOOLCHAIN:class-crosssdk ??= "gcc"
> +TOOLCHAIN:class-nativesdk ??= "gcc"
> +
> +inherit toolchain/gcc-native
> +inherit_defer toolchain/${TOOLCHAIN}

except of course that clang-cross sets TOOLCHAIN = "clang". With this patch, 

$ bitbake-getvar -r clang-cross-x86_64 TOOLCHAIN

shows "gcc". This is because the class-cross override above wins.

I can't see an easy way to keep recipe level TOOLCHAIN overriding
working whilst allowing the user to say "only target recipes", or "only
sdk recipes" or "only native recipes", which are all things we need to
support now, or in the future.

After much thought, I wondered about changing this to:

"""
PREFERRED_TOOLCHAIN_TARGET ??= "gcc"
PREFERRED_TOOLCHAIN_NATIVE ??= "gcc"
PREFERRED_TOOLCHAIN_SDK ??= "gcc"

PREFERRED_TOOLCHAIN = "${PREFERRED_TOOLCHAIN_TARGET}"
PREFERRED_TOOLCHAIN:class-native = "${PREFERRED_TOOLCHAIN_NATIVE}"
PREFERRED_TOOLCHAIN:class-cross = "${PREFERRED_TOOLCHAIN_NATIVE}"
PREFERRED_TOOLCHAIN:class-crosssdk = "${PREFERRED_TOOLCHAIN_SDK}"
PREFERRED_TOOLCHAIN:class-nativesdk = "${PREFERRED_TOOLCHAIN_SDK}"

TOOLCHAIN ??= "${PREFERRED_TOOLCHAIN}"
"""

which is pretty ugly and not an ideal interface, but should at least
allow the user to control the things they want to control.

I'd like to get this code in for M1 so we can start real world
usage/testing and find the issues we no doubt haven't spotted. The
advantage of the above is that it is contained and we can rework it if
we need to, at the cost of changing the user interface.

I guess I'm open to concerns with the above and feedback on whether we
should get this in for M1 or not. We are close, we just need to get the
detail right. I'm not 100% sure we can finish this without more real
world usage/feedback anyway though...

Cheers,

Richard
diff mbox series

Patch

diff --git a/meta/classes-global/base.bbclass b/meta/classes-global/base.bbclass
index 8215969c7bb..4ac3b83eb5c 100644
--- a/meta/classes-global/base.bbclass
+++ b/meta/classes-global/base.bbclass
@@ -267,10 +267,19 @@  def buildcfg_neededvars(d):
         bb.fatal('The following variable(s) were not set: %s\nPlease set them directly, or choose a MACHINE or DISTRO that sets them.' % ', '.join(pesteruser))
 
 addhandler base_eventhandler
-base_eventhandler[eventmask] = "bb.event.ConfigParsed bb.event.MultiConfigParsed bb.event.BuildStarted bb.event.RecipePreFinalise bb.event.RecipeParsed"
+base_eventhandler[eventmask] = "bb.event.ConfigParsed bb.event.MultiConfigParsed bb.event.BuildStarted bb.event.RecipePreFinalise bb.event.RecipeParsed bb.event.RecipePreDeferredInherits"
 python base_eventhandler() {
     import bb.runqueue
 
+    if isinstance(e, bb.event.RecipePreDeferredInherits):
+        # Use this to snoop on class extensions and set these up before the deferred inherits
+        # are processed which allows overrides on conditional variables.
+        for c in ['native', 'nativesdk', 'crosssdk', 'cross']:
+            if c in e.inherits:
+                d.setVar('CLASSOVERRIDE', 'class-' + c)
+                break
+        return
+
     if isinstance(e, bb.event.ConfigParsed):
         if not d.getVar("NATIVELSBSTRING", False):
             d.setVar("NATIVELSBSTRING", lsb_distro_identifier(d))