diff mbox series

[3/5] devtool: Isolate multiconfig workspace entries

Message ID 20261023102215.4043005-4-anusmita.duttamazumder@arm.com
State Under Review
Headers show
Series devtool: Support multiconfig workflows and fix kernel extraction | expand

Commit Message

Anusmita Dutta Mazumder Oct. 23, 2026, 10:22 a.m. UTC
Store workspace appends in multiconfig-specific directories
and select them using BB_CURRENT_MC to prevent changes from
affecting same-named recipes in other configurations.

Fixes [YOCTO #13933]

Signed-off-by: Anusmita Dutta Mazumder <anusmita.duttamazumder@arm.com>
---
 scripts/devtool                 | 24 ++++++++++++++++++++++--
 scripts/lib/devtool/__init__.py |  8 ++++++--
 scripts/lib/devtool/standard.py |  7 ++++---
 3 files changed, 32 insertions(+), 7 deletions(-)
diff mbox series

Patch

diff --git a/scripts/devtool b/scripts/devtool
index 39cebec0d8..bae7c8bbe4 100755
--- a/scripts/devtool
+++ b/scripts/devtool
@@ -28,6 +28,11 @@  import scriptutils
 import argparse_oe
 logger = scriptutils.logger_create('devtool')
 
+# Only expose workspace appends belonging to the current configuration.
+workspace_append_pattern = ("${LAYERDIR}/appends/"
+                            "${@'multiconfig/%s/' % d.getVar('BB_CURRENT_MC') "
+                            "if d.getVar('BB_CURRENT_MC') else ''}*.bbappend")
+
 
 class ConfigHandler:
     basepath = None
@@ -99,9 +104,21 @@  def read_workspace(basepath, context):
     if not context.fixed_setup:
         _enable_workspace_layer(context.config.workspace_path, context.config, basepath)
 
+    # Upgrade existing workspace layers as well as newly created ones.
+    layerconf = os.path.join(context.config.workspace_path, 'conf', 'layer.conf')
+    with open(layerconf) as f:
+        contents = f.read()
+    updated = contents.replace('${LAYERDIR}/appends/*.bbappend', workspace_append_pattern)
+    if updated != contents:
+        with open(layerconf, 'w') as f:
+            f.write(updated)
+
     logger.debug('Reading workspace in %s' % context.config.workspace_path)
     externalsrc_re = re.compile(r'^EXTERNALSRC(:pn-([^ =]+))? *= *"([^"]*)"$')
-    for fn in glob.glob(os.path.join(context.config.workspace_path, 'appends', '*.bbappend')):
+    appenddir = os.path.join(context.config.workspace_path, 'appends')
+    appendfiles = glob.glob(os.path.join(appenddir, '*.bbappend'))
+    appendfiles += glob.glob(os.path.join(appenddir, 'multiconfig', '*', '*.bbappend'))
+    for fn in appendfiles:
         with open(fn, 'r') as f:
             pnvalues = {}
             pn = None
@@ -130,6 +147,9 @@  def read_workspace(basepath, context):
                 if not pnvalues.get('srctreebase', None):
                     pnvalues['srctreebase'] = pnvalues['srctree']
                 logger.debug('Found recipe %s' % pnvalues)
+                if pn in workspace:
+                    raise DevtoolError("Multiple workspace appends found for recipe '%s'; "
+                                       "only one configuration can be modified at a time" % pn)
                 workspace[pn] = pnvalues
 
     return workspace
@@ -166,7 +186,7 @@  def _create_workspace(workspacedir, basepath, layerseries=None):
             f.write('# ### workspace layer auto-generated by devtool ###\n')
             f.write('BBPATH =. "$' + '{LAYERDIR}:"\n')
             f.write('BBFILES += "$' + '{LAYERDIR}/recipes/*/*.bb \\\n')
-            f.write('            $' + '{LAYERDIR}/appends/*.bbappend"\n')
+            f.write('            %s"\n' % workspace_append_pattern)
             f.write('BBFILE_COLLECTIONS += "workspacelayer"\n')
             f.write('BBFILE_PATTERN_workspacelayer = "^$' + '{LAYERDIR}/"\n')
             f.write('BBFILE_PATTERN_IGNORE_EMPTY_workspacelayer = "1"\n')
diff --git a/scripts/lib/devtool/__init__.py b/scripts/lib/devtool/__init__.py
index 9d227e2032..f728f7ada0 100644
--- a/scripts/lib/devtool/__init__.py
+++ b/scripts/lib/devtool/__init__.py
@@ -133,13 +133,15 @@  def setup_tinfoil(config_only=False, basepath=None, tracking=False):
 def parse_recipe(config, tinfoil, pn, appends, filter_workspace=True):
     """Parse the specified recipe"""
     import bb.providers
+    import bb.runqueue
     try:
         recipefile = tinfoil.get_recipe_file(pn)
     except bb.providers.NoProvider as e:
         logger.error(str(e))
         return None
     if appends:
-        append_files = tinfoil.get_file_appends(recipefile)
+        mc, _ = bb.runqueue.split_mc(pn)
+        append_files = tinfoil.get_file_appends(recipefile, mc)
         if filter_workspace:
             # Filter out appends from the workspace
             append_files = [path for path in append_files if
@@ -276,7 +278,7 @@  def setup_git_repo(repodir, version, devbranch, basetag='devtool-base', d=None):
     if os.path.exists(os.path.join(repodir, '.gitmodules')):
         bb.process.run('git submodule foreach --recursive  "git tag -f --no-sign %s"' % basetag, cwd=repodir)
 
-def recipe_to_append(recipefile, config, wildcard=False):
+def recipe_to_append(recipefile, config, wildcard=False, mc=''):
     """
     Convert a recipe file to a bbappend file path within the workspace.
     NOTE: if the bbappend already exists, you should be using
@@ -287,6 +289,8 @@  def recipe_to_append(recipefile, config, wildcard=False):
     if wildcard:
         appendname = re.sub(r'_.*', '_%', appendname)
     appendpath = os.path.join(config.workspace_path, 'appends')
+    if mc:
+        appendpath = os.path.join(appendpath, 'multiconfig', mc)
     appendfile = os.path.join(appendpath, appendname + '.bbappend')
     return appendfile
 
diff --git a/scripts/lib/devtool/standard.py b/scripts/lib/devtool/standard.py
index 1f6ae1d931..0f7cfe132f 100644
--- a/scripts/lib/devtool/standard.py
+++ b/scripts/lib/devtool/standard.py
@@ -540,7 +540,7 @@  def _extract_source(srctree, keep_temp, devbranch, sync, config, basepath, works
     initial_rev = None
 
     recipefile = d.getVar('FILE')
-    appendfile = recipe_to_append(recipefile, config)
+    appendfile = recipe_to_append(recipefile, config, mc=d.getVar('BB_CURRENT_MC'))
     is_kernel_yocto = bb.data.inherits_class('kernel-yocto', d)
 
     # We need to redirect WORKDIR, STAMPS_DIR etc. under a temporary
@@ -804,7 +804,8 @@  def modify(args, config, basepath, workspace):
                             srctree)
 
         recipefile = rd.getVar('FILE')
-        appendfile = recipe_to_append(recipefile, config, args.wildcard)
+        appendfile = recipe_to_append(recipefile, config, args.wildcard,
+                                      mc=rd.getVar('BB_CURRENT_MC'))
         if os.path.exists(appendfile):
             raise DevtoolError("Another variant of recipe %s is already in your "
                             "workspace (only one variant of a recipe can "
@@ -2076,7 +2077,7 @@  def _reset(recipes, no_clean, remove_work, config, basepath, workspace,
             # This should always be true if recipefile is set, but just in case
             preservedir(os.path.dirname(recipefile))
         # We don't automatically create this dir next to appends, but the user can
-        preservedir(os.path.join(config.workspace_path, 'appends', pn))
+        preservedir(os.path.join(os.path.dirname(appendfile), pn))
 
         srctreebase = workspace[pn]['srctreebase']
         if os.path.isdir(srctreebase):