diff mbox series

[5/7] bitbake-setup: allow using {THISDIR}/my-layer

Message ID 20251002100929.1054540-5-alex.kanavin@gmail.com
State New
Headers show
Series [1/7] bitbake-setup: suggest "." instead of "source" | expand

Commit Message

Alexander Kanavin Oct. 2, 2025, 10:09 a.m. UTC
From: Yoann Congal <yoann.congal@smile.fr>

This implement the ability to use "{THISDIR}/my-layer" in the
"bb-layers" list. "{THISDIR}" is remplaced by the directory containing
the configuration file.

In small projects, we try to keep the setup a simple as possible: a
single git repo containing both the build confguration (e.g.
a bitbake-setup configuration file) and the meta layer with project
recipes/machine/distro.

This change allows this kind of setup:
├── meta-my-project/ # the project layer
└── my-project.conf.json   # the bb-setup configuration file

by writing, in my-project.conf.json:
  "bitbake-setup": {
    "configurations": [{
      "bb-layers": [
        "{THISDIR}/meta-my-project"

Note: in this case meta-my-project is not present as a "source", so, not
handled by bb-setup update/status. It is expected of the user to handle
this on their own (is our case, a simple git workflow).

Signed-off-by: Yoann Congal <yoann.congal@smile.fr>
---
 bin/bitbake-setup     | 20 +++++++++++++++++---
 lib/bb/tests/setup.py | 17 +++++++++++++++--
 2 files changed, 32 insertions(+), 5 deletions(-)
diff mbox series

Patch

diff --git a/bin/bitbake-setup b/bin/bitbake-setup
index 36a1bbd91..de83d780b 100755
--- a/bin/bitbake-setup
+++ b/bin/bitbake-setup
@@ -114,10 +114,23 @@  def checkout_layers(layers, layerdir, d):
                 os.remove(symlink)
             os.symlink(os.path.relpath(t,layerdir),symlink)
 
-def setup_bitbake_build(bitbake_config, layerdir, builddir):
+def setup_bitbake_build(bitbake_config, layerdir, builddir, thisdir):
     def _setup_build_conf(layers, build_conf_dir):
         os.makedirs(build_conf_dir)
-        layers_s = "\n".join(["  {} \\".format(os.path.join(layerdir,l)) for l in layers])
+        layers_s = []
+        for l in layers:
+            if l.startswith("{THISDIR}/"):
+                if thisdir:
+                    l = l.format(THISDIR=thisdir)
+                else:
+                    raise Exception("Configuration is using {THISDIR} to specify " \
+                    "a layer path relative to itself. This can be done only " \
+                    "when the configuration is specified by its path on local " \
+                    "disk, not when it's in a registry or is fetched over http.")
+            if not os.path.isabs(l):
+                l = os.path.join(layerdir, l)
+            layers_s.append("  {} \\".format(l))
+        layers_s = "\n".join(layers_s)
         bblayers_conf = """BBLAYERS ?= " \\
 {}
   "
@@ -237,7 +250,8 @@  def update_build(config, confdir, builddir, layerdir, d):
             layer_config[k]["git-remote"] = v["git-remote"]
     checkout_layers(layer_config, layerdir, d)
     bitbake_config = config["bitbake-config"]
-    setup_bitbake_build(bitbake_config, layerdir, builddir)
+    thisdir = os.path.dirname(config["path"]) if config["type"] == 'local' else None
+    setup_bitbake_build(bitbake_config, layerdir, builddir, thisdir)
 
 def int_input(allowed_values):
     n = None
diff --git a/lib/bb/tests/setup.py b/lib/bb/tests/setup.py
index 2076613d9..747a9b733 100644
--- a/lib/bb/tests/setup.py
+++ b/lib/bb/tests/setup.py
@@ -130,6 +130,12 @@  print("BBPATH is {{}}".format(os.environ["BBPATH"]))
                 "description": "Gizmo notemplate build configuration",
                 "bb-layers": ["layerC","layerD/meta-layer"],
                 "oe-fragments": ["test-fragment-2"]
+            },
+            {
+                "name": "gizmo-notemplate-with-thisdir",
+                "description": "Gizmo notemplate build configuration using THISDIR",
+                "bb-layers": ["layerC","layerD/meta-layer","{THISDIR}/layerE/meta-layer"],
+                "oe-fragments": ["test-fragment-2"]
             }
         ]
     },
@@ -174,7 +180,14 @@  print("BBPATH is {{}}".format(os.environ["BBPATH"]))
             with open(os.path.join(bb_conf_path, 'bblayers.conf')) as f:
                 bblayers = f.read()
                 for l in bitbake_config["bb-layers"]:
-                    self.assertIn(os.path.join(buildpath, 'layers', l), bblayers)
+                    if l.startswith('{THISDIR}/'):
+                        thisdir_layer = os.path.join(
+                            os.path.dirname(json_config["path"]),
+                            l.removeprefix("{THISDIR}/"),
+                        )
+                        self.assertIn(thisdir_layer, bblayers)
+                    else:
+                        self.assertIn(os.path.join(buildpath, "layers", l), bblayers)
 
         for f in bitbake_config["oe-fragments"]:
             self.assertTrue(os.path.exists(os.path.join(bb_conf_path, f)))
@@ -235,7 +248,7 @@  print("BBPATH is {{}}".format(os.environ["BBPATH"]))
 
         # test-config-1 is tested as a registry config, test-config-2 as a local file
         test_configurations = {'test-config-1': {'cmdline': 'test-config-1', 'buildconfigs':('gadget','gizmo','gadget-notemplate','gizmo-notemplate')},
-                               'test-config-2': {'cmdline': os.path.join(self.registrypath,'config-2/test-config-2.conf.json'), 'buildconfigs': ('gadget','gizmo','gadget-notemplate','gizmo-notemplate') } }
+                               'test-config-2': {'cmdline': os.path.join(self.registrypath,'config-2/test-config-2.conf.json'), 'buildconfigs': ('gadget','gizmo','gadget-notemplate','gizmo-notemplate', 'gizmo-notemplate-with-thisdir') } }
         for cf, v in test_configurations.items():
             for c in v['buildconfigs']:
                 out = self.runbbsetup("init --non-interactive {} {}".format(v['cmdline'], c))