[RFC,1/2] Add build-config-snippet class

Message ID 20210809102645.17414-2-Quirin.Gylstorff@siemens.com
State RFC
Headers show
Series Add bbclass to generate build configuration from snippets | expand

Commit Message

Quirin Gylstorff Aug. 9, 2021, 2:26 a.m. UTC
From: Quirin Gylstorff <quirin.gylstorff@siemens.com>

This class allows to generate a build configuration with debian
dependencies.

Signed-off-by: Quirin Gylstorff <quirin.gylstorff@siemens.com>
---
 doc/technical_overview.md                  | 33 ++++++++
 meta/classes/build-config-snippets.bbclass | 87 ++++++++++++++++++++++
 2 files changed, 120 insertions(+)
 create mode 100644 meta/classes/build-config-snippets.bbclass

Patch

diff --git a/doc/technical_overview.md b/doc/technical_overview.md
index bbd22b6..fdfec0c 100644
--- a/doc/technical_overview.md
+++ b/doc/technical_overview.md
@@ -308,3 +308,36 @@  to the end.
 Only template files from the `WORKDIR` are accepted. Either specify relative
 paths based on the recipes `WORKDIR` or absolute paths containing the `WORKDIR`
 in the `TEMPLATE_FILES` variable.
+
+### 3.9.2 Build configuration snippets
+
+A build configuration can be created from multiple snippets files.
+
+This system is implemented in the `build-config-snippets.bbclass` and defines
+a `do_generate_build_configuration` task.
+
+To define a feature set, the user has to define the following
+variable to an empty string:
+
+```
+BUILD_FEATURE_featurename = ""
+```
+
+Then, required additions to the variables can be defined:
+
+```
+BUILD_FEATURE_featurename[BUILD_CONFIG_SNIPPETS] = "file://snippet-file-name.snippet"
+BUILD_FEATURE_featurename[SRC_URI] = "file://required-file.txt"
+BUILD_FEATURE_featurename[DEPENDS] = "deb-pkg1 deb-pkg2 deb-pkg3"
+BUILD_FEATURE_featurename[DEBIAN_DEPENDS] = "deb-pkg1"
+BUILD_FEATURE_featurename[DEBIAN_BUILD_DEPENDS] = "deb-pkg1,deb-pkg2,deb-pkg3"
+```
+
+The `BUILD_CONFIG_SNIPPETS` flag gives a list of URI entries, where only
+file:// is supported. These snippets are appended to the BUILD_CONFIG file.
+
+Features can depend on other features via the following mechanism:
+
+```
+BUILD_FEATURE_DEPS[feature1] = "feature2"
+```
diff --git a/meta/classes/build-config-snippets.bbclass b/meta/classes/build-config-snippets.bbclass
new file mode 100644
index 0000000..1d1054d
--- /dev/null
+++ b/meta/classes/build-config-snippets.bbclass
@@ -0,0 +1,87 @@ 
+# This software is a part of ISAR.
+# Copyright (C) 2021 Siemens AG
+#
+# SPDX-License-Identifier: MIT
+
+
+BUILD_CONFIG_SNIPPETS = ""
+
+# The following function defines the build config snippet system
+# with automatich debian dependency injection
+#
+# To define a feature set, the user has to define the following
+# variable to an empty string:
+#
+# BUILD_FEATURE_featurename = ""
+#
+# Then, required additions to the variables can be defined:
+#
+# BUILD_FEATURE_featurename[BUILD_CONFIG_SNIPPETS] = "file://snippet-file-name.snippet"
+# BUILD_FEATURE_featurename[SRC_URI] = "file://required-file.txt"
+# BUILD_FEATURE_featurename[DEPENDS] = "deb-pkg1 deb-pkg2 deb-pkg3"
+# BUILD_FEATURE_featurename[DEBIAN_DEPENDS] = "deb-pkg1"
+# BUILD_FEATURE_featurename[DEBIAN_BUILD_DEPENDS] = "deb-pkg1,deb-pkg2,deb-pkg3"
+
+# The 'BUILD_CONFIG_SNIPPETS' flag gives a list of URI entries, where only
+# file:// is supported. These snippets are appended to the BUILD_CONFIG file.
+#
+# Features can depend on other features via the following mechanism:
+#
+# BUILD_FEATURE_DEPS[feature1] = "feature2"
+
+KOMMA_SEPERATED_ELEMENTS ?= "DEBIAN_BUILD_DEPENDS DEBIAN_DEPENDS"
+
+python () {
+    requested_features = d.getVar("BUILD_FEATURES", True) or ""
+
+    features = set(requested_features.split())
+    old_features = set()
+    feature_deps = d.getVarFlags("BUILD_FEATURE_DEPS") or {}
+    while old_features != features:
+        diff_features = old_features.symmetric_difference(features)
+        old_features = features.copy()
+        for i in diff_features:
+            features.update(feature_deps.get(i, "").split())
+
+    for f in sorted(features):
+        bb.debug(2, "Feature: " + f)
+        varname = "BUILD_FEATURE_" + f
+        dummyvar = d.getVar(varname, False)
+        if dummyvar == None:
+            bb.error("Feature var " + f + " must be defined with needed flags.")
+        else:
+            feature_flags = d.getVarFlags(varname)
+            for feature_varname in sorted(feature_flags):
+                if feature_flags.get(feature_varname, "") != "":
+                    sep = " "
+
+                    # Required to add BUILD_CONFIG_SNIPPETS to SRC_URI here,
+                    # because 'SRC_URI += "${BUILD_CONFIG_SNIPPETS}"' would
+                    # conflict with SRC_APT feature.
+                    if feature_varname == "BUILD_CONFIG_SNIPPETS":
+                        d.appendVar('SRC_URI',
+                            " " + feature_flags[feature_varname].strip())
+
+                    # BUILD_DEP_DEPENDS and DEBIAN_DEPENDS is ',' separated
+                    # Only add ',' if there is already something there
+                    if feature_varname in (d.getVar("KOMMA_SEPERATED_ELEMENTS", True) or "").split():
+                        sep = "," if d.getVar(feature_varname) else ""
+
+                    d.appendVar(feature_varname,
+                        sep + feature_flags[feature_varname].strip())
+}
+
+# BUILD_CONFIG must be a predefined bitbake variable and the corresponding file
+# must exist in the WORKDIR.
+# The resulting generated config is the same file suffixed with ".gen"
+
+do_generate_build_configuration() {
+        GENCONFIG="${WORKDIR}/${BUILD_CONFIG}".gen
+        rm -f "$GENCONFIG"
+        cp "${WORKDIR}/${BUILD_CONFIG}" "$GENCONFIG"
+        for CONFIG_SNIPPET in $(echo "${BUILD_CONFIG_SNIPPETS}" | sed 's#file://##g')
+        do
+                cat ${WORKDIR}/$CONFIG_SNIPPET >> "$GENCONFIG"
+        done
+}
+addtask generate_build_configuration before do_prepare_build after do_patch