diff mbox series

[bitbake-devel] toaster: support bitbake-setup

Message ID IA1PR11MB76771970C94C4B34878FBB64EAFBA@IA1PR11MB7677.namprd11.prod.outlook.com
State New
Headers show
Series [bitbake-devel] toaster: support bitbake-setup | expand

Commit Message

Reyna, David Oct. 30, 2025, 9:30 p.m. UTC
From c063178ab0971fe297a9e9bca6e6b04eafc5149c Mon Sep 17 00:00:00 2001
From: David Reyna <David.Reyna@windriver.com>
Date: Thu, 30 Oct 2025 14:03:35 -0700
Subject: [PATCH] toaster: support bitbake-setup

    This adds support for the new bitbake-setup:
      * Maintain backwards compatibility for poky-classic releases
      * Assume bitbake-setup for all releases 'master' and forward
      * When no ".templateconf" assume Poky and not OE
      * Generate and use "init-build-env" script instead of 'oe-init-build-env'
        directly, but "cd" to the clone and not the local installation.
      * Include "bblayers.conf" because "cookerdata.py" now explicitly
        required it, and let it be over-ridden by the usual "toaster-bblayers.conf".
      * Force the value "TOPDIR" in "toaster.conf" to the local project's directory.

    Normally "cookerdata.py" sets TOPDIR from getcwd(), but somehow in bitbake-setup
    mode the CWD at this point has become ".../layers/openembedded-core", so
    "bitbake.conf and all other files cannot be found. This non-obvious problem was
    hard to discover. Until this is understood, the forced value will make things work.

    [YOCTO #16012]

Signed-off-by: David Reyna <David.Reyna@windriver.com>
---
 bin/toaster                                   | 21 ++--
 .../bldcontrol/localhostbecontroller.py       | 99 ++++++++++++++-----
 2 files changed, 89 insertions(+), 31 deletions(-)
diff mbox series

Patch

diff --git a/bin/toaster b/bin/toaster
index f002c8c1590..d20cbe90ba8 100755
--- a/bin/toaster
+++ b/bin/toaster
@@ -164,14 +164,20 @@  fi
 # in the local layers that currently make using an arbitrary
 # toasterconf.json difficult.
 
-. $OE_ROOT/.templateconf
-if [ -n "$TEMPLATECONF" ]; then
-    if [ ! -d "$TEMPLATECONF" ]; then
-        # Allow TEMPLATECONF=meta-xyz/conf as a shortcut
-        if [ -d "$OE_ROOT/$TEMPLATECONF" ]; then
-            TEMPLATECONF="$OE_ROOT/$TEMPLATECONF"
+# BBSETUP no longer supports .templateconf
+if [ -f $OE_ROOT/.templateconf ] ; then 
+    . $OE_ROOT/.templateconf
+    if [ -n "$TEMPLATECONF" ]; then
+        if [ ! -d "$TEMPLATECONF" ]; then
+            # Allow TEMPLATECONF=meta-xyz/conf as a shortcut
+            if [ -d "$OE_ROOT/$TEMPLATECONF" ]; then
+                TEMPLATECONF="$OE_ROOT/$TEMPLATECONF"
+            fi
         fi
     fi
+else
+    # Force poky
+    TEMPLATECONF="layers/meta-yocto/meta-poky/conf/templates/default"
 fi
 
 unset OE_ROOT
@@ -255,7 +261,8 @@  fi
 # 2) the build dir (in build)
 # 3) the sqlite db if that is being used.
 # 4) pid's we need to clean up on exit/shutdown
-export TOASTER_DIR=$TOASTERDIR
+# By default we move this all into the Toaster's parent build directory
+export TOASTER_DIR=$BUILDDIR
 export BB_ENV_PASSTHROUGH_ADDITIONS="$BB_ENV_PASSTHROUGH_ADDITIONS TOASTER_DIR"
 
 # Determine the action. If specified by arguments, fine, if not, toggle it
diff --git a/lib/toaster/bldcontrol/localhostbecontroller.py b/lib/toaster/bldcontrol/localhostbecontroller.py
index 577e765f112..a7bc5722fad 100644
--- a/lib/toaster/bldcontrol/localhostbecontroller.py
+++ b/lib/toaster/bldcontrol/localhostbecontroller.py
@@ -6,6 +6,11 @@ 
 # SPDX-License-Identifier: GPL-2.0-only
 #
 
+# DEBUGGING NOTE: if you need to add debug statements into the files within a
+# Toaster-imported layer, you must disable the "git fetch ..." command after
+# the initial clone else any changes will be automatically replaced with the
+# original code
+
 import os
 import re
 import shutil
@@ -183,6 +188,8 @@  class LocalhostBEController(BuildEnvironmentController):
             if commit != "HEAD":
                 logger.debug("localhostbecontroller: checking out commit %s to %s " % (commit, localdirname))
                 ref = commit if re.match('^[a-fA-F0-9]+$', commit) else 'origin/%s' % commit
+                # DEBUGGING NOTE: this is the 'git fetch" to disable after the initial clone to
+                # prevent inserted debugging commands from being lost
                 self._shellcmd('git fetch && git reset --hard "%s"' % ref, localdirname,env=git_env)
 
             # take the localdirname as poky dir if we can find the oe-init-build-env
@@ -319,7 +326,28 @@  class LocalhostBEController(BuildEnvironmentController):
         layers = self.setLayers(bitbake, layers, targets)
         is_merged_attr = bitbake.req.project.merged_attr
 
+        # Is this build for a Bitbake Setup installation?
+        isBBSetup = False
+        release_description = bitbake.req.project.release.description
+        if 'master' in release_description:
+            # This release going forward is Bitbake Setup
+            isBBSetup = True
+        else:
+            try:
+                # Yocto Project 5.3 "Whinlatter"
+                params = release_description.split(' ')
+                # Work past YP "10.1"
+                release_params = params[2].split('.')
+                if int(release_params[0]) > 5:
+                    isBBSetup = True
+                if (release_params[0] == '5') and (int(release_params[1]) >= 3):
+                    isBBSetup = True
+            except:
+                # If release schema not recognized, then this release is in the future
+                isBBSetup = True
+
         git_env = os.environ.copy()
+        toaster_run_dir = git_env['BUILDDIR']
         # (note: add custom environment settings here)
         try:
             # insure that the project init/build uses the selected bitbake, and not Toaster's
@@ -335,28 +363,44 @@  class LocalhostBEController(BuildEnvironmentController):
         else:
             builddir = '%s-toaster-%d' % (self.be.builddir, bitbake.req.project.id)
         oe_init = os.path.join(self.pokydirname, 'oe-init-build-env')
-        # init build environment
+        setup_init = os.path.join(builddir, 'init-build-env')
+        # init build environment and build directory structure
         try:
             custom_script = ToasterSetting.objects.get(name="CUSTOM_BUILD_INIT_SCRIPT").value
             custom_script = custom_script.replace("%BUILDDIR%" ,builddir)
             self._shellcmd("bash -c 'source %s'" % (custom_script),env=git_env)
         except ToasterSetting.DoesNotExist:
-            self._shellcmd("bash -c 'source %s %s'" % (oe_init, builddir),
-                       self.be.sourcedir,env=git_env)
+            # Normal setup
+            if isBBSetup:
+                # Create an 'init-build-env' for the build directory that points to respective cloned bitbake
+                os.makedirs(builddir, exist_ok = True)
+                build_init_script = os.path.join(builddir,'init-build-env')
+                os.system(f"cp {os.path.join(toaster_run_dir,'init-build-env')} {build_init_script}")
+                os.system(f"sed -i -e 's|^cd .*$|cd {self.pokydirname}|g' {build_init_script}")
+                os.system(f"sed -i -e 's|^set .*$|set {builddir}|g' {build_init_script}")
+                # Execute the init
+                self._shellcmd(f"bash -c 'source {build_init_script}'", env=git_env)
+            else:
+                self._shellcmd("bash -c 'source %s %s'" % (oe_init, builddir),
+                           self.be.sourcedir,env=git_env)
 
         # update bblayers.conf
         if not is_merged_attr:
             bblconfpath = os.path.join(builddir, "conf/toaster-bblayers.conf")
             with open(bblconfpath, 'w') as bblayers:
                 bblayers.write('# line added by toaster build control\n'
-                               'BBLAYERS = "%s"' % ' '.join(layers))
+                               'BBLAYERS = "%s"\n' % ' '.join(layers))
 
             # write configuration file
             confpath = os.path.join(builddir, 'conf/toaster.conf')
             with open(confpath, 'w') as conf:
+                if isBBSetup:
+                    # Force TOPDIR
+                    conf.write(f'# Force TOPDIR\n')
+                    conf.write(f'TOPDIR = "{builddir}"\n\n')
                 for var in variables:
-                    conf.write('%s="%s"\n' % (var.name, var.value))
-                conf.write('INHERIT+="toaster buildhistory"')
+                    conf.write('%s = "%s"\n' % (var.name, var.value))
+                conf.write('INHERIT += "toaster buildhistory"\n')
         else:
             # Append the Toaster-specific values directly to the bblayers.conf
             bblconfpath = os.path.join(builddir, "conf/bblayers.conf")
@@ -443,15 +487,25 @@  class LocalhostBEController(BuildEnvironmentController):
             else:
                 logger.error("Looks like Bitbake is not available, please fix your environment")
 
+        # NOTE: BB SETUP requires a 'bblayers.conf' even though Toaster immediately overrides it with 'toaster-bblayers.conf'
+        bblayers = os.path.join(builddir,"conf/bblayers.conf")
         toasterlayers = os.path.join(builddir,"conf/toaster-bblayers.conf")
-        if not is_merged_attr:
-            self._shellcmd('%s bash -c \"source %s %s; BITBAKE_UI="knotty" %s --read %s --read %s '
-                           '--server-only -B 0.0.0.0:0\"' % (env_clean, oe_init,
-                           builddir, bitbake, confpath, toasterlayers), self.be.sourcedir)
+        if isBBSetup:
+            # Use 'init-build-env' model
+            if not is_merged_attr:
+                self._shellcmd(f'{env_clean} bash -c \"source {setup_init}; BITBAKE_UI="knotty" {bitbake} --read {confpath} --read {bblayers} --read {toasterlayers} '
+                               '--server-only -B 0.0.0.0:0\"', self.be.sourcedir)
+            else:
+                self._shellcmd(f'{env_clean} bash -c \"source {setup_init}; BITBAKE_UI="knotty" {bitbake} '
+                           '--server-only -B 0.0.0.0:0\"', self.be.sourcedir)
         else:
-            self._shellcmd('%s bash -c \"source %s %s; BITBAKE_UI="knotty" %s '
-                           '--server-only -B 0.0.0.0:0\"' % (env_clean, oe_init,
-                           builddir, bitbake), self.be.sourcedir)
+            # Use 'oe-init-build-env' model
+            if not is_merged_attr:
+                self._shellcmd(f'{env_clean} bash -c \"source {oe_init} {builddir}; BITBAKE_UI="knotty" {bitbake} --read {confpath} --read {bblayers} --read {toasterlayers} '
+                               '--server-only -B 0.0.0.0:0\"', self.be.sourcedir)
+            else:
+                self._shellcmd(f'{env_clean} bash -c \"source {oe_init} {builddir}; BITBAKE_UI="knotty" {bitbake} '
+                           '--server-only -B 0.0.0.0:0\"', self.be.sourcedir)
 
         # read port number from bitbake.lock
         self.be.bbport = -1
@@ -497,20 +551,17 @@  class LocalhostBEController(BuildEnvironmentController):
         log = os.path.join(builddir, 'toaster_ui.log')
         local_bitbake = os.path.join(os.path.dirname(os.getenv('BBBASEDIR')),
                                      'bitbake')
+
         if not is_merged_attr:
-            self._shellcmd(['%s bash -c \"(TOASTER_BRBE="%s" BBSERVER="0.0.0.0:%s" '
-                        '%s %s -u toasterui  --read %s --read %s --token="" >>%s 2>&1;'
-                        'BITBAKE_UI="knotty" BBSERVER=0.0.0.0:%s %s -m)&\"' \
-                        % (env_clean, brbe, self.be.bbport, local_bitbake, bbtargets, confpath, toasterlayers, log,
-                        self.be.bbport, bitbake,)],
+            self._shellcmd([f'{env_clean} bash -c \"(TOASTER_BRBE="{brbe}" BBSERVER="0.0.0.0:{self.be.bbport}" '
+                        f'{bitbake} {bbtargets} -u toasterui  --read {confpath} --read {bblayers} --read {toasterlayers} --token="" >>{log} 2>&1;'
+                        f'BITBAKE_UI="knotty" BBSERVER=0.0.0.0:{self.be.bbport} {bitbake} -m)&\"'],
                         builddir, nowait=True)
         else:
-            self._shellcmd(['%s bash -c \"(TOASTER_BRBE="%s" BBSERVER="0.0.0.0:%s" '
-                        '%s %s -u toasterui  --token="" >>%s 2>&1;'
-                        'BITBAKE_UI="knotty" BBSERVER=0.0.0.0:%s %s -m)&\"' \
-                        % (env_clean, brbe, self.be.bbport, local_bitbake, bbtargets, log,
-                        self.be.bbport, bitbake,)],
+            self._shellcmd([f'{env_clean} bash -c \"(TOASTER_BRBE="{brbe}" BBSERVER="0.0.0.0:{self.be.bbport}" '
+                        f'{local_bitbake} {bbtargets} -u toasterui  --token="" >>{log} 2>&1;'
+                        f'BITBAKE_UI="knotty" BBSERVER=0.0.0.0:{self.be.bbport} {bitbake} -m)&\"'],
                         builddir, nowait=True)
 
         logger.debug('localhostbecontroller: Build launched, exiting. '
-                     'Follow build logs at %s' % log)
+                     f'Follow build logs at {log}')