* [PATCH v4 00/10] wic: ship its tools, and add an SDK_FEATURES lever
@ 2026-07-24 9:01 Trevor Woerner
2026-07-24 9:01 ` [PATCH v4 01/10] wic-tools: move bootloader firmware staging into the wic oe-selftest Trevor Woerner
` (9 more replies)
0 siblings, 10 replies; 12+ messages in thread
From: Trevor Woerner @ 2026-07-24 9:01 UTC (permalink / raw)
To: openembedded-core
wic shells out to a range of host-side tools but does not declare them,
so wherever it is installed as a package (rather than run from the
bitbake do_image_wic task, which has the wic-tools native sysroot on
PATH) it works only by chance depending on what the host has installed.
Patch 1 is a cleanup of wic-tools: it moves the target bootloader
firmware (syslinux, grub-efi, systemd-boot) out of wic-tools and into the
wic oe-selftest that actually needs it, leaving wic-tools to stage only
the host tools wic runs.
Patch 2 then makes wic declare those host tools directly: wic gains
RDEPENDS on the tools it runs, so they are installed alongside it in
every variant that packages it.
Patches 3 and 4 are follow-on cleanups of the wic oe-selftest now that
wic and its tools all resolve from the wic-tools native sysroot: drop a
dead in-tree wic lookup, and drop the redundant per-test PATH overrides
that duplicated what the test setup already establishes.
The rest of the series turns "what optional tools go into the SDK" into
an explicit, self-documenting choice built around SDK_FEATURES, a list in
the same spirit as DISTRO_FEATURES / MACHINE_FEATURES / IMAGE_FEATURES: a
developer reads the setting and knows exactly what their SDK contains.
- patch 5 adds the SDK_FEATURES variable and documents it (default
empty), with no features wired to it yet;
- patch 6 adds an opt-in "wic" feature;
- patch 7 adds an opt-in "sbom" feature (SPDX + SBOM/CVE tooling);
- patch 8 adds an opt-in "lldb" feature;
- patch 9 moves the existing (unconditional, arch-gated) qemu addition
behind a "qemu" feature, on by default so nothing regresses;
- patch 10 moves the cross-canadian gdb behind a "gdb" feature, on by
default; binutils and gcc stay unconditional since a cross-compiler
is intrinsic to an SDK.
The opt-in features come first, then the two that default on. After the
whole series the default SDK_FEATURES is "gdb qemu", so an unmodified
configuration produces the same SDK as before. The intent is to present
the full range of knobs and let review settle which belong on by default;
the split across separate patches is deliberate so each can be debated on
its own. SDK_FEATURES is a plain list, so downstream layers can define
their own features (for example a cgdb feature in meta-openembedded) the
same way.
changes in v4:
- new patch 1: move the target bootloader firmware out of wic-tools and
stage it from the wic oe-selftest instead, so wic-tools carries only
the host tools wic runs. Ordered first so the wic RDEPENDS patch no
longer needs to describe firmware that is about to leave wic-tools.
- wic RDEPENDS patch: gate the grub RDEPENDS to x86 and aarch64. grub is
not in COMPATIBLE_HOST on arm hard-float, so the unconditional
dependency in v3 made wic unbuildable there and broke "bitbake world"
(Nothing RPROVIDES 'grub'), which in turn failed the sstate samesigs
oe-selftests that build world under a qemuarm config. syslinux moves
into the same arch-gated appends.
- new patches 3 and 4: oe-selftest cleanups enabled by the above (drop
the dead COREBASE/scripts wic lookup and the redundant per-test PATH
overrides).
- SDK_FEATURES: split the v3 "add wic via a new SDK_FEATURES lever" patch
into a variable-only patch (patch 5) plus a wic feature patch (patch
6), and reorder so the opt-in features (wic, sbom, lldb) come before
the default-on ones (qemu, gdb).
changes in v3:
- replace the SDK_INCLUDE_WIC yes/no knob with the general SDK_FEATURES
lever, and use it for qemu, sbom, gdb and lldb as well as wic
- the v2 "buildtools-extended-tarball: drop wic helper tools" patch was
merged already and is dropped from the series
changes in v2:
- dropped the wic-tools.inc refactor; folded the tool list into the wic
recipe
- reworked the buildtools-extended-tarball change into a plain removal
- gated wic in the SDK behind a knob instead of adding it unconditionally
Trevor Woerner (10):
wic-tools: move bootloader firmware staging into the wic oe-selftest
wic: add runtime dependencies on the tools it invokes
oeqa/selftest/wic: drop dead COREBASE/scripts wic lookup
oeqa/selftest/wic: drop redundant per-test PATH overrides
nativesdk-packagegroup-sdk-host: add an SDK_FEATURES lever
nativesdk-packagegroup-sdk-host: add wic to SDK_FEATURES
nativesdk-packagegroup-sdk-host: add an sbom SDK feature
nativesdk-packagegroup-sdk-host: add an lldb SDK feature
nativesdk-packagegroup-sdk-host: gate qemu behind SDK_FEATURES
packagegroup-cross-canadian: gate gdb behind SDK_FEATURES
meta/conf/bitbake.conf | 1 +
meta/conf/documentation.conf | 1 +
meta/lib/oeqa/selftest/cases/wic.py | 853 +++++++++---------
meta/recipes-core/meta/wic-tools.bb | 11 +-
.../nativesdk-packagegroup-sdk-host.bb | 5 +-
.../packagegroup-cross-canadian.bb | 2 +-
meta/recipes-support/wic/wic_0.3.1.bb | 30 +
7 files changed, 448 insertions(+), 455 deletions(-)
--
2.50.0.173.g8b6f19ccfc3a
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v4 01/10] wic-tools: move bootloader firmware staging into the wic oe-selftest
2026-07-24 9:01 [PATCH v4 00/10] wic: ship its tools, and add an SDK_FEATURES lever Trevor Woerner
@ 2026-07-24 9:01 ` Trevor Woerner
2026-07-24 9:01 ` [PATCH v4 02/10] wic: add runtime dependencies on the tools it invokes Trevor Woerner
` (8 subsequent siblings)
9 siblings, 0 replies; 12+ messages in thread
From: Trevor Woerner @ 2026-07-24 9:01 UTC (permalink / raw)
To: openembedded-core
wic-tools is a meta-recipe whose DEPENDS assemble a native sysroot of the
host tools wic runs. Over time it also accumulated target bootloader
firmware (syslinux, grub-efi, systemd-boot), which is a different kind of
thing: wic copies those artifacts into the images it builds, reading
grub-efi and systemd-boot from DEPLOY_DIR_IMAGE and syslinux from the
sysroot. They were listed in wic-tools only so that building wic-tools
would force the firmware to be built and deployed before the wic
oe-selftest ran.
That coupling makes wic-tools carry target recipes for the sole benefit
of the test suite. Move the firmware out of wic-tools and have the wic
oe-selftest build it directly in its setup, gated to the host
architectures where each loader is available, matching the arch
decorators already on the individual tests. wic-tools keeps
syslinux-native, which is the isohybrid host tool wic invokes rather
than firmware.
No image or SDK builds relied on wic-tools pulling in the firmware; only
the oe-selftest did, so this narrows wic-tools to its original purpose of
staging wic's host tools.
AI-Generated: codex/claude-opus 4.8 (xhigh)
Signed-off-by: Trevor Woerner <twoerner@gmail.com>
---
changes in v4:
- new in v4
- update test_build_artifacts and test_rootfs_artifacts to build
syslinux into the image and take the bootimg dir from there, since
wic-tools no longer stages target syslinux
---
meta/lib/oeqa/selftest/cases/wic.py | 44 ++++++++++++++++++++++++-----
meta/recipes-core/meta/wic-tools.bb | 11 +++++---
2 files changed, 44 insertions(+), 11 deletions(-)
diff --git a/meta/lib/oeqa/selftest/cases/wic.py b/meta/lib/oeqa/selftest/cases/wic.py
index 4e94f4d39abd..c4a1c7241bbc 100644
--- a/meta/lib/oeqa/selftest/cases/wic.py
+++ b/meta/lib/oeqa/selftest/cases/wic.py
@@ -72,12 +72,30 @@ class WicTestCase(OESelftestTestCase):
if self.td['USE_NLS'] != 'yes':
self.skipTest('wic-tools needs USE_NLS=yes')
- bitbake('wic-tools core-image-minimal core-image-minimal-mtdutils')
+ targets = 'wic-tools core-image-minimal core-image-minimal-mtdutils'
+ # wic copies target bootloader firmware into the images it builds:
+ # grub-efi and systemd-boot from DEPLOY_DIR_IMAGE and syslinux from
+ # the sysroot. Deploy/stage whatever is available on this host arch
+ # so the bootimg_efi / isoimage / pcbios plugins can find it. This
+ # used to be pulled in via wic-tools' DEPENDS, but firmware is a
+ # target artifact rather than a wic host tool, so it is built here.
+ targets += ' ' + ' '.join(self._firmware_recipes())
+ bitbake(targets)
WicTestCase.image_is_ready = True
os.environ['PATH'] = self._get_wic_path()
rmtree(self.resultdir, ignore_errors=True)
+ def _firmware_recipes(self):
+ """Target bootloader firmware wic may copy into images, per host arch."""
+ arch = self.td['HOST_ARCH']
+ recipes = []
+ if arch in ('i586', 'i686', 'x86_64', 'x86-64'):
+ recipes += ['syslinux', 'grub-efi', 'systemd-boot']
+ elif arch == 'aarch64':
+ recipes += ['grub-efi', 'systemd-boot']
+ return recipes
+
def tearDownLocal(self):
"""Remove resultdir as it may contain images."""
if self._old_path is None:
@@ -391,9 +409,15 @@ class Wic(WicTestCase):
@skipIfNotArch(['i586', 'i686', 'x86_64'])
def test_build_artifacts(self):
"""Test wic create directdisk providing all artifacts."""
- bb_vars = get_bb_vars(['STAGING_DATADIR', 'RECIPE_SYSROOT_NATIVE'],
- 'wic-tools')
- bb_vars.update(get_bb_vars(['DEPLOY_DIR_IMAGE', 'IMAGE_ROOTFS'],
+ # syslinux (the target bootloader data the bootimg_pcbios plugin
+ # copies from --bootimg-dir) is not staged by wic-tools; build it
+ # into the image and take the bootimg dir from there.
+ config = 'DEPENDS:pn-core-image-minimal += "syslinux"\n'
+ self.append_config(config)
+ bitbake('core-image-minimal')
+ self.remove_config(config)
+ bb_vars = get_bb_vars(['RECIPE_SYSROOT_NATIVE'], 'wic-tools')
+ bb_vars.update(get_bb_vars(['STAGING_DATADIR', 'DEPLOY_DIR_IMAGE', 'IMAGE_ROOTFS'],
'core-image-minimal'))
bbvars = {key.lower(): value for key, value in bb_vars.items()}
bbvars['resultdir'] = self.resultdir
@@ -494,9 +518,15 @@ class Wic(WicTestCase):
@skipIfNotArch(['i586', 'i686', 'x86_64'])
def test_rootfs_artifacts(self):
"""Test usage of rootfs plugin with rootfs paths"""
- bb_vars = get_bb_vars(['STAGING_DATADIR', 'RECIPE_SYSROOT_NATIVE'],
- 'wic-tools')
- bb_vars.update(get_bb_vars(['DEPLOY_DIR_IMAGE', 'IMAGE_ROOTFS'],
+ # syslinux (the target bootloader data the bootimg_pcbios plugin
+ # copies from --bootimg-dir) is not staged by wic-tools; build it
+ # into the image and take the bootimg dir from there.
+ config = 'DEPENDS:pn-core-image-minimal += "syslinux"\n'
+ self.append_config(config)
+ bitbake('core-image-minimal')
+ self.remove_config(config)
+ bb_vars = get_bb_vars(['RECIPE_SYSROOT_NATIVE'], 'wic-tools')
+ bb_vars.update(get_bb_vars(['STAGING_DATADIR', 'DEPLOY_DIR_IMAGE', 'IMAGE_ROOTFS'],
'core-image-minimal'))
bbvars = {key.lower(): value for key, value in bb_vars.items()}
bbvars['wks'] = "directdisk-multi-rootfs"
diff --git a/meta/recipes-core/meta/wic-tools.bb b/meta/recipes-core/meta/wic-tools.bb
index 823dbe6db643..c1da1739777e 100644
--- a/meta/recipes-core/meta/wic-tools.bb
+++ b/meta/recipes-core/meta/wic-tools.bb
@@ -10,10 +10,13 @@ DEPENDS = "\
e2fsprogs-native util-linux-native tar-native erofs-utils-native \
virtual/cross-binutils \
"
-DEPENDS:append:x86 = " syslinux-native syslinux grub-efi systemd-boot"
-DEPENDS:append:x86-64 = " syslinux-native syslinux grub-efi systemd-boot"
-DEPENDS:append:x86-x32 = " syslinux-native syslinux grub-efi"
-DEPENDS:append:aarch64 = " grub-efi systemd-boot"
+# syslinux-native provides the isohybrid host tool that wic runs; it is only
+# available on x86. The target bootloader firmware (syslinux, grub-efi,
+# systemd-boot) that wic copies into an image is deployed by the wic selftest
+# instead, so it is not staged here.
+DEPENDS:append:x86 = " syslinux-native"
+DEPENDS:append:x86-64 = " syslinux-native"
+DEPENDS:append:x86-x32 = " syslinux-native"
INHIBIT_DEFAULT_DEPS = "1"
--
2.50.0.173.g8b6f19ccfc3a
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v4 02/10] wic: add runtime dependencies on the tools it invokes
2026-07-24 9:01 [PATCH v4 00/10] wic: ship its tools, and add an SDK_FEATURES lever Trevor Woerner
2026-07-24 9:01 ` [PATCH v4 01/10] wic-tools: move bootloader firmware staging into the wic oe-selftest Trevor Woerner
@ 2026-07-24 9:01 ` Trevor Woerner
2026-07-24 9:01 ` [PATCH v4 03/10] oeqa/selftest/wic: drop dead COREBASE/scripts wic lookup Trevor Woerner
` (7 subsequent siblings)
9 siblings, 0 replies; 12+ messages in thread
From: Trevor Woerner @ 2026-07-24 9:01 UTC (permalink / raw)
To: openembedded-core
wic shells out to a number of host-side tools to do its work: parted,
mkdosfs, mcopy, the mkfs.* family, sfdisk, e2fsck, resize2fs, debugfs,
blkid and more, depending on the operation and on the partition types
in the image.
None of these are declared as dependencies of wic. For the bitbake
do_image_wic task this is handled by the wic-tools recipe, which builds
the tools into a native sysroot. Wherever else wic is installed as a
package it gets none of them, and its offline lookup (wic ls/cp/write)
resolves each tool over a search path that falls back to the host PATH,
so on a machine that happens to have the tool installed system-wide wic
succeeds while on a machine without it wic fails:
wic.WicError: Can't find executable 'mcopy'
Falling back to the host is unreliable even when the tool is found: wic
depends on specific minimum versions of some of these tools, and an
arbitrary host copy may be too old, so wic can pick up a tool that does
not behave as it needs. Declaring the tools as dependencies pins
known-good versions instead of trusting whatever the host provides.
Add the tools wic runs as RDEPENDS so they are installed alongside it.
resize2fs is listed on its own because e2fsprogs packages it separately
as e2fsprogs-resize2fs, which e2fsprogs does not pull in, and wic needs
it for the cp/write resize path.
grub (grub-mkimage) is used to assemble EFI boot images, and is only
compatible with, and only used by wic on, x86 and aarch64. In particular
grub is not in COMPATIBLE_HOST on arm hard-float, so an unconditional
dependency makes wic unbuildable there and breaks "bitbake world"
(Nothing RPROVIDES 'grub'). Gate grub to the hosts that can build and
use it.
syslinux is only available on x86, so it is gated to those hosts too.
Its bits are split across packages: the syslinux package provides the
isohybrid helper wic runs, syslinux-misc carries the ldlinux.sys,
isohdpfx.bin and ldlinux.c32 data files, and syslinux-isolinux carries
isolinux.bin; wic copies all of these into a hybrid ISO, so all three
are listed. cdrtools (mkisofs) is native-only with no nativesdk variant
and is only needed for ISO images, so it is not listed here.
AI-Generated: codex/claude-opus 4.8 (xhigh)
Signed-off-by: Trevor Woerner <twoerner@gmail.com>
---
changes in v4:
- gate grub to x86 and aarch64 (it is not in COMPATIBLE_HOST on arm
hard-float, which made wic unbuildable and broke bitbake world); move
syslinux into the same arch-gated appends
- also depend on syslinux-isolinux, which carries isolinux.bin that wic
copies into a hybrid ISO; the syslinux/syslinux-misc pair alone missed
it
changes in v3:
- list the tools on all variants rather than only the nativesdk variant
changes in v2:
- merge the tool list from the v1 "wic-tools.inc: add" patch into this
recipe as RDEPENDS; the separate .inc is dropped
- list the tools inline rather than via a shared WIC_TOOLS variable
- note in the commit log that a host tool may also be the wrong version,
not merely absent
---
meta/recipes-support/wic/wic_0.3.1.bb | 30 +++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/meta/recipes-support/wic/wic_0.3.1.bb b/meta/recipes-support/wic/wic_0.3.1.bb
index d9b4cc05c4bd..75fa734a9761 100644
--- a/meta/recipes-support/wic/wic_0.3.1.bb
+++ b/meta/recipes-support/wic/wic_0.3.1.bb
@@ -17,4 +17,34 @@ RDEPENDS:${PN} += " \
python3-misc \
"
+# wic shells out to these host-side tools when it runs, so they must be
+# installed alongside it.
+RDEPENDS:${PN} += " \
+ parted \
+ gptfdisk \
+ dosfstools \
+ mtools \
+ bmaptool \
+ btrfs-tools \
+ squashfs-tools \
+ e2fsprogs \
+ e2fsprogs-resize2fs \
+ util-linux \
+ tar \
+ erofs-utils \
+"
+
+# grub (grub-mkimage) assembles EFI boot images; it is only compatible
+# with, and only used by wic on, x86 and aarch64, so gate it to those
+# hosts. In particular grub is not compatible with arm hard-float, so an
+# unconditional dependency makes wic unbuildable there. syslinux is only
+# available on x86: its installer provides the isohybrid helper wic runs,
+# syslinux-misc carries ldlinux.sys/isohdpfx.bin/ldlinux.c32 and
+# syslinux-isolinux carries isolinux.bin, all of which wic copies into a
+# hybrid ISO.
+RDEPENDS:${PN}:append:x86 = " grub syslinux syslinux-misc syslinux-isolinux"
+RDEPENDS:${PN}:append:x86-64 = " grub syslinux syslinux-misc syslinux-isolinux"
+RDEPENDS:${PN}:append:x86-x32 = " grub syslinux syslinux-misc syslinux-isolinux"
+RDEPENDS:${PN}:append:aarch64 = " grub"
+
BBCLASSEXTEND = "native nativesdk"
--
2.50.0.173.g8b6f19ccfc3a
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v4 03/10] oeqa/selftest/wic: drop dead COREBASE/scripts wic lookup
2026-07-24 9:01 [PATCH v4 00/10] wic: ship its tools, and add an SDK_FEATURES lever Trevor Woerner
2026-07-24 9:01 ` [PATCH v4 01/10] wic-tools: move bootloader firmware staging into the wic oe-selftest Trevor Woerner
2026-07-24 9:01 ` [PATCH v4 02/10] wic: add runtime dependencies on the tools it invokes Trevor Woerner
@ 2026-07-24 9:01 ` Trevor Woerner
2026-07-24 9:01 ` [PATCH v4 04/10] oeqa/selftest/wic: drop redundant per-test PATH overrides Trevor Woerner
` (6 subsequent siblings)
9 siblings, 0 replies; 12+ messages in thread
From: Trevor Woerner @ 2026-07-24 9:01 UTC (permalink / raw)
To: openembedded-core
_get_wic_path() searches for the wic binary in two locations: the
in-tree scripts directory and the wic-tools native sysroot. wic was
moved to a standalone repository and is no longer shipped in
scripts/, so scripts/wic never exists and the first search path can
never match.
Look for wic only in the wic-tools native sysroot, where the wic
recipe installs it, and fail with that path if it is missing.
AI-Generated: codex/claude-opus 4.8 (xhigh)
Signed-off-by: Trevor Woerner <twoerner@gmail.com>
---
changes in v4:
- new in v4
---
meta/lib/oeqa/selftest/cases/wic.py | 17 +++++------------
1 file changed, 5 insertions(+), 12 deletions(-)
diff --git a/meta/lib/oeqa/selftest/cases/wic.py b/meta/lib/oeqa/selftest/cases/wic.py
index c4a1c7241bbc..6a2706fc2c8f 100644
--- a/meta/lib/oeqa/selftest/cases/wic.py
+++ b/meta/lib/oeqa/selftest/cases/wic.py
@@ -107,18 +107,11 @@ class WicTestCase(OESelftestTestCase):
def _get_wic_path(self):
if WicTestCase.wic_bindir is None:
- search_paths = [
- os.path.join(self.td['COREBASE'], 'scripts'),
- os.path.join(get_bb_var('RECIPE_SYSROOT_NATIVE', 'wic-tools'), 'usr', 'bin'),
- ]
-
- for bindir in search_paths:
- if os.path.exists(os.path.join(bindir, 'wic')):
- WicTestCase.wic_bindir = bindir
- break
-
- if WicTestCase.wic_bindir is None:
- self.fail("Unable to find the wic binary in %s" % ', '.join(search_paths))
+ bindir = os.path.join(get_bb_var('RECIPE_SYSROOT_NATIVE', 'wic-tools'),
+ 'usr', 'bin')
+ if not os.path.exists(os.path.join(bindir, 'wic')):
+ self.fail("Unable to find the wic binary in %s" % bindir)
+ WicTestCase.wic_bindir = bindir
path_entries = []
for path_group in (
--
2.50.0.173.g8b6f19ccfc3a
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v4 04/10] oeqa/selftest/wic: drop redundant per-test PATH overrides
2026-07-24 9:01 [PATCH v4 00/10] wic: ship its tools, and add an SDK_FEATURES lever Trevor Woerner
` (2 preceding siblings ...)
2026-07-24 9:01 ` [PATCH v4 03/10] oeqa/selftest/wic: drop dead COREBASE/scripts wic lookup Trevor Woerner
@ 2026-07-24 9:01 ` Trevor Woerner
2026-07-24 9:01 ` [PATCH v4 05/10] nativesdk-packagegroup-sdk-host: add an SDK_FEATURES lever Trevor Woerner
` (5 subsequent siblings)
9 siblings, 0 replies; 12+ messages in thread
From: Trevor Woerner @ 2026-07-24 9:01 UTC (permalink / raw)
To: openembedded-core
setUpLocal() already puts wic and its tools on PATH for every test: it
sets os.environ['PATH'] to the wic binary's directory followed by the
whole wic-tools native-sysroot PATH, and tearDownLocal() restores the
original. A number of individual tests then re-set
os.environ['PATH'] = get_bb_var("PATH", "wic-tools")
inside a try/finally, which is a narrower subset of what setUpLocal
already established (it drops the wic bindir prepend and the original
PATH tail) and adds nothing: wic and every tool it runs are reachable
from the PATH setUpLocal installs.
Remove these per-test overrides and their try/finally wrappers. The
tests keep passing the explicit --native-sysroot / RECIPE_SYSROOT_NATIVE
that some of them build, which is a separate concern from PATH.
The diff looks large and noisy, but the change is mechanical: dropping
each try/finally means the whole test body dedents by one level, so
almost every line in the affected tests shows up as removed-and-re-added
with different leading whitespace. The test logic is otherwise
unchanged; reviewing with a whitespace-insensitive diff (git show -w)
shows only the removed override, try: and finally: lines.
AI-Generated: codex/claude-opus 4.8 (xhigh)
Signed-off-by: Trevor Woerner <twoerner@gmail.com>
---
changes in v4:
- new in v4
---
meta/lib/oeqa/selftest/cases/wic.py | 792 +++++++++++++---------------
1 file changed, 362 insertions(+), 430 deletions(-)
diff --git a/meta/lib/oeqa/selftest/cases/wic.py b/meta/lib/oeqa/selftest/cases/wic.py
index 6a2706fc2c8f..37673392c271 100644
--- a/meta/lib/oeqa/selftest/cases/wic.py
+++ b/meta/lib/oeqa/selftest/cases/wic.py
@@ -536,104 +536,97 @@ class Wic(WicTestCase):
def test_exclude_path(self):
"""Test --exclude-path wks option."""
- oldpath = os.environ['PATH']
- os.environ['PATH'] = get_bb_var("PATH", "wic-tools")
-
- try:
- wks_file = 'temp.wks'
- with open(wks_file, 'w') as wks:
- rootfs_dir = get_bb_var('IMAGE_ROOTFS', 'core-image-minimal')
- wks.write("""
+ wks_file = 'temp.wks'
+ with open(wks_file, 'w') as wks:
+ rootfs_dir = get_bb_var('IMAGE_ROOTFS', 'core-image-minimal')
+ wks.write("""
part / --source rootfs --ondisk mmcblk0 --fstype=ext4 --exclude-path usr
part /usr --source rootfs --ondisk mmcblk0 --fstype=ext4 --rootfs-dir %s/usr
part /etc --source rootfs --ondisk mmcblk0 --fstype=ext4 --exclude-path bin/ --rootfs-dir %s/usr
part /mnt --source rootfs --ondisk mmcblk0 --fstype=ext4 --exclude-path bin/whoami --rootfs-dir %s/usr"""
- % (rootfs_dir, rootfs_dir, rootfs_dir))
- runCmd("wic create %s -e core-image-minimal -o %s" \
- % (wks_file, self.resultdir))
-
- os.remove(wks_file)
- wicout = glob(os.path.join(self.resultdir, "%s-*direct" % 'temp'))
- self.assertEqual(1, len(wicout))
+ % (rootfs_dir, rootfs_dir, rootfs_dir))
+ runCmd("wic create %s -e core-image-minimal -o %s" \
+ % (wks_file, self.resultdir))
- wicimg = wicout[0]
-
- # verify partition size with wic
- res = runCmd("parted -m %s unit b p" % wicimg, stderr=subprocess.PIPE)
-
- # parse parted output which looks like this:
- # BYT;\n
- # /var/tmp/wic/build/tmpfwvjjkf_-201611101222-hda.direct:200MiB:file:512:512:msdos::;\n
- # 1:0.00MiB:200MiB:200MiB:ext4::;\n
- partlns = res.output.splitlines()[2:]
+ os.remove(wks_file)
+ wicout = glob(os.path.join(self.resultdir, "%s-*direct" % 'temp'))
+ self.assertEqual(1, len(wicout))
- self.assertEqual(4, len(partlns))
+ wicimg = wicout[0]
- for part in [1, 2, 3, 4]:
- part_file = os.path.join(self.resultdir, "selftest_img.part%d" % part)
- partln = partlns[part-1].split(":")
- self.assertEqual(7, len(partln))
- start = int(partln[1].rstrip("B")) / 512
- length = int(partln[3].rstrip("B")) / 512
- runCmd("dd if=%s of=%s skip=%d count=%d" %
- (wicimg, part_file, start, length))
-
- # Test partition 1, should contain the normal root directories, except
- # /usr.
- res = runCmd("debugfs -R 'ls -p' %s" % \
- os.path.join(self.resultdir, "selftest_img.part1"), stderr=subprocess.PIPE)
- files = extract_files(res.output)
- self.assertIn("etc", files)
- self.assertNotIn("usr", files)
-
- # Partition 2, should contain common directories for /usr, not root
- # directories.
- res = runCmd("debugfs -R 'ls -p' %s" % \
- os.path.join(self.resultdir, "selftest_img.part2"), stderr=subprocess.PIPE)
- files = extract_files(res.output)
- self.assertNotIn("etc", files)
- self.assertNotIn("usr", files)
- self.assertIn("share", files)
-
- # Partition 3, should contain the same as partition 2, including the bin
- # directory, but not the files inside it.
- res = runCmd("debugfs -R 'ls -p' %s" % \
- os.path.join(self.resultdir, "selftest_img.part3"), stderr=subprocess.PIPE)
- files = extract_files(res.output)
- self.assertNotIn("etc", files)
- self.assertNotIn("usr", files)
- self.assertIn("share", files)
- self.assertIn("bin", files)
- res = runCmd("debugfs -R 'ls -p bin' %s" % \
- os.path.join(self.resultdir, "selftest_img.part3"), stderr=subprocess.PIPE)
- files = extract_files(res.output)
- self.assertIn(".", files)
- self.assertIn("..", files)
- self.assertEqual(2, len(files))
-
- # Partition 4, should contain the same as partition 2, including the bin
- # directory, but not whoami (a symlink to busybox.nosuid) inside it.
- res = runCmd("debugfs -R 'ls -p' %s" % \
- os.path.join(self.resultdir, "selftest_img.part4"), stderr=subprocess.PIPE)
- files = extract_files(res.output)
- self.assertNotIn("etc", files)
- self.assertNotIn("usr", files)
- self.assertIn("share", files)
- self.assertIn("bin", files)
- res = runCmd("debugfs -R 'ls -p bin' %s" % \
- os.path.join(self.resultdir, "selftest_img.part4"), stderr=subprocess.PIPE)
- files = extract_files(res.output)
- self.assertIn(".", files)
- self.assertIn("..", files)
- self.assertIn("who", files)
- self.assertNotIn("whoami", files)
-
- for part in [1, 2, 3, 4]:
- part_file = os.path.join(self.resultdir, "selftest_img.part%d" % part)
- os.remove(part_file)
+ # verify partition size with wic
+ res = runCmd("parted -m %s unit b p" % wicimg, stderr=subprocess.PIPE)
- finally:
- os.environ['PATH'] = oldpath
+ # parse parted output which looks like this:
+ # BYT;\n
+ # /var/tmp/wic/build/tmpfwvjjkf_-201611101222-hda.direct:200MiB:file:512:512:msdos::;\n
+ # 1:0.00MiB:200MiB:200MiB:ext4::;\n
+ partlns = res.output.splitlines()[2:]
+
+ self.assertEqual(4, len(partlns))
+
+ for part in [1, 2, 3, 4]:
+ part_file = os.path.join(self.resultdir, "selftest_img.part%d" % part)
+ partln = partlns[part-1].split(":")
+ self.assertEqual(7, len(partln))
+ start = int(partln[1].rstrip("B")) / 512
+ length = int(partln[3].rstrip("B")) / 512
+ runCmd("dd if=%s of=%s skip=%d count=%d" %
+ (wicimg, part_file, start, length))
+
+ # Test partition 1, should contain the normal root directories, except
+ # /usr.
+ res = runCmd("debugfs -R 'ls -p' %s" % \
+ os.path.join(self.resultdir, "selftest_img.part1"), stderr=subprocess.PIPE)
+ files = extract_files(res.output)
+ self.assertIn("etc", files)
+ self.assertNotIn("usr", files)
+
+ # Partition 2, should contain common directories for /usr, not root
+ # directories.
+ res = runCmd("debugfs -R 'ls -p' %s" % \
+ os.path.join(self.resultdir, "selftest_img.part2"), stderr=subprocess.PIPE)
+ files = extract_files(res.output)
+ self.assertNotIn("etc", files)
+ self.assertNotIn("usr", files)
+ self.assertIn("share", files)
+
+ # Partition 3, should contain the same as partition 2, including the bin
+ # directory, but not the files inside it.
+ res = runCmd("debugfs -R 'ls -p' %s" % \
+ os.path.join(self.resultdir, "selftest_img.part3"), stderr=subprocess.PIPE)
+ files = extract_files(res.output)
+ self.assertNotIn("etc", files)
+ self.assertNotIn("usr", files)
+ self.assertIn("share", files)
+ self.assertIn("bin", files)
+ res = runCmd("debugfs -R 'ls -p bin' %s" % \
+ os.path.join(self.resultdir, "selftest_img.part3"), stderr=subprocess.PIPE)
+ files = extract_files(res.output)
+ self.assertIn(".", files)
+ self.assertIn("..", files)
+ self.assertEqual(2, len(files))
+
+ # Partition 4, should contain the same as partition 2, including the bin
+ # directory, but not whoami (a symlink to busybox.nosuid) inside it.
+ res = runCmd("debugfs -R 'ls -p' %s" % \
+ os.path.join(self.resultdir, "selftest_img.part4"), stderr=subprocess.PIPE)
+ files = extract_files(res.output)
+ self.assertNotIn("etc", files)
+ self.assertNotIn("usr", files)
+ self.assertIn("share", files)
+ self.assertIn("bin", files)
+ res = runCmd("debugfs -R 'ls -p bin' %s" % \
+ os.path.join(self.resultdir, "selftest_img.part4"), stderr=subprocess.PIPE)
+ files = extract_files(res.output)
+ self.assertIn(".", files)
+ self.assertIn("..", files)
+ self.assertIn("who", files)
+ self.assertNotIn("whoami", files)
+
+ for part in [1, 2, 3, 4]:
+ part_file = os.path.join(self.resultdir, "selftest_img.part%d" % part)
+ os.remove(part_file)
def test_exclude_path_with_extra_space(self):
"""Test having --exclude-path with IMAGE_ROOTFS_EXTRA_SPACE. [Yocto #15555]"""
@@ -672,75 +665,61 @@ part /mnt --source rootfs --ondisk mmcblk0 --fstype=ext4 --exclude-path bin/whoa
def test_include_path(self):
"""Test --include-path wks option."""
- oldpath = os.environ['PATH']
- os.environ['PATH'] = get_bb_var("PATH", "wic-tools")
-
- try:
- include_path = os.path.join(self.resultdir, 'test-include')
- os.makedirs(include_path)
- with open(os.path.join(include_path, 'test-file'), 'w') as t:
- t.write("test\n")
- wks_file = os.path.join(include_path, 'temp.wks')
- with open(wks_file, 'w') as wks:
- rootfs_dir = get_bb_var('IMAGE_ROOTFS', 'core-image-minimal')
- wks.write("""
+ include_path = os.path.join(self.resultdir, 'test-include')
+ os.makedirs(include_path)
+ with open(os.path.join(include_path, 'test-file'), 'w') as t:
+ t.write("test\n")
+ wks_file = os.path.join(include_path, 'temp.wks')
+ with open(wks_file, 'w') as wks:
+ rootfs_dir = get_bb_var('IMAGE_ROOTFS', 'core-image-minimal')
+ wks.write("""
part /part1 --source rootfs --ondisk mmcblk0 --fstype=ext4
part /part2 --source rootfs --ondisk mmcblk0 --fstype=ext4 --include-path %s"""
- % (include_path))
- runCmd("wic create %s -e core-image-minimal -o %s" \
- % (wks_file, self.resultdir))
-
- part1 = glob(os.path.join(self.resultdir, 'temp-*.direct.p1'))[0]
- part2 = glob(os.path.join(self.resultdir, 'temp-*.direct.p2'))[0]
+ % (include_path))
+ runCmd("wic create %s -e core-image-minimal -o %s" \
+ % (wks_file, self.resultdir))
- # Test partition 1, should not contain 'test-file'
- res = runCmd("debugfs -R 'ls -p' %s" % (part1), stderr=subprocess.PIPE)
- files = extract_files(res.output)
- self.assertNotIn('test-file', files)
- self.assertEqual(True, files_own_by_root(res.output))
+ part1 = glob(os.path.join(self.resultdir, 'temp-*.direct.p1'))[0]
+ part2 = glob(os.path.join(self.resultdir, 'temp-*.direct.p2'))[0]
- # Test partition 2, should contain 'test-file'
- res = runCmd("debugfs -R 'ls -p' %s" % (part2), stderr=subprocess.PIPE)
- files = extract_files(res.output)
- self.assertIn('test-file', files)
- self.assertEqual(True, files_own_by_root(res.output))
+ # Test partition 1, should not contain 'test-file'
+ res = runCmd("debugfs -R 'ls -p' %s" % (part1), stderr=subprocess.PIPE)
+ files = extract_files(res.output)
+ self.assertNotIn('test-file', files)
+ self.assertEqual(True, files_own_by_root(res.output))
- finally:
- os.environ['PATH'] = oldpath
+ # Test partition 2, should contain 'test-file'
+ res = runCmd("debugfs -R 'ls -p' %s" % (part2), stderr=subprocess.PIPE)
+ files = extract_files(res.output)
+ self.assertIn('test-file', files)
+ self.assertEqual(True, files_own_by_root(res.output))
def test_include_path_embeded(self):
"""Test --include-path wks option."""
- oldpath = os.environ['PATH']
- os.environ['PATH'] = get_bb_var("PATH", "wic-tools")
-
- try:
- include_path = os.path.join(self.resultdir, 'test-include')
- os.makedirs(include_path)
- with open(os.path.join(include_path, 'test-file'), 'w') as t:
- t.write("test\n")
- wks_file = os.path.join(include_path, 'temp.wks')
- with open(wks_file, 'w') as wks:
- wks.write("""
+ include_path = os.path.join(self.resultdir, 'test-include')
+ os.makedirs(include_path)
+ with open(os.path.join(include_path, 'test-file'), 'w') as t:
+ t.write("test\n")
+ wks_file = os.path.join(include_path, 'temp.wks')
+ with open(wks_file, 'w') as wks:
+ wks.write("""
part / --source rootfs --fstype=ext4 --include-path %s --include-path core-image-minimal-mtdutils export/"""
- % (include_path))
- runCmd("wic create %s -e core-image-minimal -o %s" \
- % (wks_file, self.resultdir))
-
- part1 = glob(os.path.join(self.resultdir, 'temp-*.direct.p1'))[0]
+ % (include_path))
+ runCmd("wic create %s -e core-image-minimal -o %s" \
+ % (wks_file, self.resultdir))
- res = runCmd("debugfs -R 'ls -p' %s" % (part1), stderr=subprocess.PIPE)
- files = extract_files(res.output)
- self.assertIn('test-file', files)
- self.assertEqual(True, files_own_by_root(res.output))
+ part1 = glob(os.path.join(self.resultdir, 'temp-*.direct.p1'))[0]
- res = runCmd("debugfs -R 'ls -p /export/etc/' %s" % (part1), stderr=subprocess.PIPE)
- files = extract_files(res.output)
- self.assertIn('passwd', files)
- self.assertEqual(True, files_own_by_root(res.output))
+ res = runCmd("debugfs -R 'ls -p' %s" % (part1), stderr=subprocess.PIPE)
+ files = extract_files(res.output)
+ self.assertIn('test-file', files)
+ self.assertEqual(True, files_own_by_root(res.output))
- finally:
- os.environ['PATH'] = oldpath
+ res = runCmd("debugfs -R 'ls -p /export/etc/' %s" % (part1), stderr=subprocess.PIPE)
+ files = extract_files(res.output)
+ self.assertIn('passwd', files)
+ self.assertEqual(True, files_own_by_root(res.output))
def test_include_path_errors(self):
"""Test --include-path wks option error handling."""
@@ -791,9 +770,6 @@ part / --source rootfs --fstype=ext4 --include-path %s --include-path core-imag
# prepare wicenv and rootfs
bitbake('core-image-minimal core-image-minimal-mtdutils -c do_rootfs_wicenv')
- oldpath = os.environ['PATH']
- os.environ['PATH'] = get_bb_var("PATH", "wic-tools")
-
t_normal = """
part / --source rootfs --fstype=ext4
"""
@@ -810,61 +786,50 @@ part /etc --source rootfs --fstype=ext4 --change-directory=etc
"""
tests = [t_normal, t_exclude, t_multi, t_change]
- try:
- for test in tests:
- include_path = os.path.join(self.resultdir, 'test-include')
- os.makedirs(include_path)
- wks_file = os.path.join(include_path, 'temp.wks')
- with open(wks_file, 'w') as wks:
- wks.write(test)
- runCmd("wic create %s -e core-image-minimal -o %s" \
- % (wks_file, self.resultdir))
-
- for part in glob(os.path.join(self.resultdir, 'temp-*.direct.p*')):
- res = runCmd("debugfs -R 'ls -p' %s" % (part), stderr=subprocess.PIPE)
- self.assertEqual(True, files_own_by_root(res.output))
+ for test in tests:
+ include_path = os.path.join(self.resultdir, 'test-include')
+ os.makedirs(include_path)
+ wks_file = os.path.join(include_path, 'temp.wks')
+ with open(wks_file, 'w') as wks:
+ wks.write(test)
+ runCmd("wic create %s -e core-image-minimal -o %s" \
+ % (wks_file, self.resultdir))
- config = 'IMAGE_FSTYPES += "wic"\nWKS_FILE = "%s"\n' % wks_file
- self.append_config(config)
- bitbake('core-image-minimal')
- tmpdir = os.path.join(get_bb_var('WORKDIR', 'core-image-minimal'),'build-wic')
+ for part in glob(os.path.join(self.resultdir, 'temp-*.direct.p*')):
+ res = runCmd("debugfs -R 'ls -p' %s" % (part), stderr=subprocess.PIPE)
+ self.assertEqual(True, files_own_by_root(res.output))
- # check each partition for permission
- for part in glob(os.path.join(tmpdir, 'temp-*.direct.p*')):
- res = runCmd("debugfs -R 'ls -p' %s" % (part), stderr=subprocess.PIPE)
- self.assertTrue(files_own_by_root(res.output)
- ,msg='Files permission incorrect using wks set "%s"' % test)
+ config = 'IMAGE_FSTYPES += "wic"\nWKS_FILE = "%s"\n' % wks_file
+ self.append_config(config)
+ bitbake('core-image-minimal')
+ tmpdir = os.path.join(get_bb_var('WORKDIR', 'core-image-minimal'),'build-wic')
- # clean config and result directory for next cases
- self.remove_config(config)
- rmtree(self.resultdir, ignore_errors=True)
+ # check each partition for permission
+ for part in glob(os.path.join(tmpdir, 'temp-*.direct.p*')):
+ res = runCmd("debugfs -R 'ls -p' %s" % (part), stderr=subprocess.PIPE)
+ self.assertTrue(files_own_by_root(res.output)
+ ,msg='Files permission incorrect using wks set "%s"' % test)
- finally:
- os.environ['PATH'] = oldpath
+ # clean config and result directory for next cases
+ self.remove_config(config)
+ rmtree(self.resultdir, ignore_errors=True)
def test_change_directory(self):
"""Test --change-directory wks option."""
- oldpath = os.environ['PATH']
- os.environ['PATH'] = get_bb_var("PATH", "wic-tools")
-
- try:
- include_path = os.path.join(self.resultdir, 'test-include')
- os.makedirs(include_path)
- wks_file = os.path.join(include_path, 'temp.wks')
- with open(wks_file, 'w') as wks:
- wks.write("part /etc --source rootfs --fstype=ext4 --change-directory=etc")
- runCmd("wic create %s -e core-image-minimal -o %s" \
- % (wks_file, self.resultdir))
-
- part1 = glob(os.path.join(self.resultdir, 'temp-*.direct.p1'))[0]
+ include_path = os.path.join(self.resultdir, 'test-include')
+ os.makedirs(include_path)
+ wks_file = os.path.join(include_path, 'temp.wks')
+ with open(wks_file, 'w') as wks:
+ wks.write("part /etc --source rootfs --fstype=ext4 --change-directory=etc")
+ runCmd("wic create %s -e core-image-minimal -o %s" \
+ % (wks_file, self.resultdir))
- res = runCmd("debugfs -R 'ls -p' %s" % (part1), stderr=subprocess.PIPE)
- files = extract_files(res.output)
- self.assertIn('passwd', files)
+ part1 = glob(os.path.join(self.resultdir, 'temp-*.direct.p1'))[0]
- finally:
- os.environ['PATH'] = oldpath
+ res = runCmd("debugfs -R 'ls -p' %s" % (part1), stderr=subprocess.PIPE)
+ files = extract_files(res.output)
+ self.assertIn('passwd', files)
def test_change_directory_errors(self):
"""Test --change-directory wks option error handling."""
@@ -887,41 +852,34 @@ part /etc --source rootfs --fstype=ext4 --change-directory=etc
def test_no_fstab_update(self):
"""Test --no-fstab-update wks option."""
- oldpath = os.environ['PATH']
- os.environ['PATH'] = get_bb_var("PATH", "wic-tools")
-
# Get stock fstab from base-files recipe
bitbake('base-files -c do_install')
bf_fstab = os.path.join(get_bb_var('D', 'base-files'), 'etc', 'fstab')
self.assertEqual(True, os.path.exists(bf_fstab))
bf_fstab_md5sum = runCmd('md5sum %s ' % bf_fstab).output.split(" ")[0]
- try:
- no_fstab_update_path = os.path.join(self.resultdir, 'test-no-fstab-update')
- os.makedirs(no_fstab_update_path)
- wks_file = os.path.join(no_fstab_update_path, 'temp.wks')
- with open(wks_file, 'w') as wks:
- wks.writelines(['part / --source rootfs --fstype=ext4 --label rootfs\n',
- 'part /mnt/p2 --source rootfs --rootfs-dir=core-image-minimal ',
- '--fstype=ext4 --label p2 --no-fstab-update\n'])
- runCmd("wic create %s -e core-image-minimal -o %s" \
- % (wks_file, self.resultdir))
-
- part_fstab_md5sum = []
- for i in range(1, 3):
- part = glob(os.path.join(self.resultdir, 'temp-*.direct.p') + str(i))[0]
- part_fstab = runCmd("debugfs -R 'cat etc/fstab' %s" % (part), stderr=subprocess.PIPE)
- part_fstab_md5sum.append(hashlib.md5((part_fstab.output + "\n\n").encode('utf-8')).hexdigest())
+ no_fstab_update_path = os.path.join(self.resultdir, 'test-no-fstab-update')
+ os.makedirs(no_fstab_update_path)
+ wks_file = os.path.join(no_fstab_update_path, 'temp.wks')
+ with open(wks_file, 'w') as wks:
+ wks.writelines(['part / --source rootfs --fstype=ext4 --label rootfs\n',
+ 'part /mnt/p2 --source rootfs --rootfs-dir=core-image-minimal ',
+ '--fstype=ext4 --label p2 --no-fstab-update\n'])
+ runCmd("wic create %s -e core-image-minimal -o %s" \
+ % (wks_file, self.resultdir))
- # '/etc/fstab' in partition 2 should contain the same stock fstab file
- # as the one installed by the base-file recipe.
- self.assertEqual(bf_fstab_md5sum, part_fstab_md5sum[1])
+ part_fstab_md5sum = []
+ for i in range(1, 3):
+ part = glob(os.path.join(self.resultdir, 'temp-*.direct.p') + str(i))[0]
+ part_fstab = runCmd("debugfs -R 'cat etc/fstab' %s" % (part), stderr=subprocess.PIPE)
+ part_fstab_md5sum.append(hashlib.md5((part_fstab.output + "\n\n").encode('utf-8')).hexdigest())
- # '/etc/fstab' in partition 1 should contain an updated fstab file.
- self.assertNotEqual(bf_fstab_md5sum, part_fstab_md5sum[0])
+ # '/etc/fstab' in partition 2 should contain the same stock fstab file
+ # as the one installed by the base-file recipe.
+ self.assertEqual(bf_fstab_md5sum, part_fstab_md5sum[1])
- finally:
- os.environ['PATH'] = oldpath
+ # '/etc/fstab' in partition 1 should contain an updated fstab file.
+ self.assertNotEqual(bf_fstab_md5sum, part_fstab_md5sum[0])
def test_no_fstab_update_errors(self):
"""Test --no-fstab-update wks option error handling."""
@@ -995,153 +953,139 @@ bootloader --ptable gpt""")
def test_wic_sector_size_env(self):
"""Test generation image sector size via environment (obsolete)"""
- oldpath = os.environ['PATH']
- os.environ['PATH'] = get_bb_var("PATH", "wic-tools")
+ # Add WIC_SECTOR_SIZE into config
+ config = 'WIC_SECTOR_SIZE = "4096"\n'\
+ 'WICVARS:append = " WIC_SECTOR_SIZE"\n'
+ self.append_config(config)
+ bitbake('core-image-minimal')
- try:
- # Add WIC_SECTOR_SIZE into config
- config = 'WIC_SECTOR_SIZE = "4096"\n'\
- 'WICVARS:append = " WIC_SECTOR_SIZE"\n'
- self.append_config(config)
- bitbake('core-image-minimal')
+ # Check WIC_SECTOR_SIZE apply to bitbake variable
+ wic_sector_size_str = get_bb_var('WIC_SECTOR_SIZE', 'core-image-minimal')
+ wic_sector_size = int(wic_sector_size_str)
+ self.assertEqual(4096, wic_sector_size)
- # Check WIC_SECTOR_SIZE apply to bitbake variable
- wic_sector_size_str = get_bb_var('WIC_SECTOR_SIZE', 'core-image-minimal')
- wic_sector_size = int(wic_sector_size_str)
- self.assertEqual(4096, wic_sector_size)
-
- self.logger.info("Test wic_sector_size: %d \n" % wic_sector_size)
-
- with NamedTemporaryFile("w", suffix=".wks") as wks:
- wks.writelines(
- ['bootloader --ptable gpt\n',
- 'part --fstype vfat --fstype vfat --label emptyfat --size 1M --mkfs-extraopts "-S 4096"\n',
- 'part --fstype ext4 --source rootfs --label rofs-a --mkfs-extraopts "-b 4096"\n',
- 'part --fstype ext4 --source rootfs --use-uuid --mkfs-extraopts "-b 4096"\n'])
- wks.flush()
- cmd = "wic create %s -e core-image-minimal -o %s" % (wks.name, self.resultdir)
- runCmd(cmd)
- wksname = os.path.splitext(os.path.basename(wks.name))[0]
- images = glob(os.path.join(self.resultdir, "%s-*direct" % wksname))
- self.assertEqual(1, len(images))
+ self.logger.info("Test wic_sector_size: %d \n" % wic_sector_size)
- sysroot = get_bb_var('RECIPE_SYSROOT_NATIVE', 'wic-tools')
- # list partitions
- result = runCmd("wic ls %s -n %s" % (images[0], sysroot))
- print(result.output)
- # Deprecated message + 4 lines of output: header + 3 partitions
- self.assertEqual(5, len(result.output.split('\n')))
+ with NamedTemporaryFile("w", suffix=".wks") as wks:
+ wks.writelines(
+ ['bootloader --ptable gpt\n',
+ 'part --fstype vfat --fstype vfat --label emptyfat --size 1M --mkfs-extraopts "-S 4096"\n',
+ 'part --fstype ext4 --source rootfs --label rofs-a --mkfs-extraopts "-b 4096"\n',
+ 'part --fstype ext4 --source rootfs --use-uuid --mkfs-extraopts "-b 4096"\n'])
+ wks.flush()
+ cmd = "wic create %s -e core-image-minimal -o %s" % (wks.name, self.resultdir)
+ runCmd(cmd)
+ wksname = os.path.splitext(os.path.basename(wks.name))[0]
+ images = glob(os.path.join(self.resultdir, "%s-*direct" % wksname))
+ self.assertEqual(1, len(images))
- # verify partition size with wic
- res = runCmd("export PARTED_SECTOR_SIZE=%d; parted -m %s unit b p" % (wic_sector_size, images[0]),
- stderr=subprocess.PIPE)
+ sysroot = get_bb_var('RECIPE_SYSROOT_NATIVE', 'wic-tools')
+ # list partitions
+ result = runCmd("wic ls %s -n %s" % (images[0], sysroot))
+ print(result.output)
+ # Deprecated message + 4 lines of output: header + 3 partitions
+ self.assertEqual(5, len(result.output.split('\n')))
- print(res.output)
- # parse parted output which looks like this:
- # BYT;\n
- # /var/tmp/wic/build/tmpgjzzefdd-202410281021-sda.direct:78569472B:file:4096:4096:gpt::;\n
- # 1:139264B:1187839B:1048576B::emptyfat:msftdata;
- # 2:1187840B:149270527B:148082688B:ext4:rofs-a:;
- # 3:149270528B:297353215B:148082688B:ext4:primary:;
- disk_info = res.output.splitlines()[1]
- # Check sector sizes
- sector_size_logical = int(disk_info.split(":")[3])
- sector_size_physical = int(disk_info.split(":")[4])
- self.assertEqual(wic_sector_size, sector_size_logical, "Logical sector size is not %d." % wic_sector_size)
- self.assertEqual(wic_sector_size, sector_size_physical, "Physical sector size is not %d." % wic_sector_size)
-
- # It is a known issue with parsed that a 4K FAT partition does
- # not have a recognized filesystem type of *fat.
- part_info = res.output.splitlines()[2]
- partname = part_info.split(":")[5]
- parttype = part_info.split(":")[6]
- self.assertEqual('emptyfat', partname)
- self.assertEqual('msftdata;', parttype)
-
- part_info = res.output.splitlines()[3]
- parttype = part_info.split(":")[4]
- partname = part_info.split(":")[5]
- self.assertEqual('ext4', parttype)
- self.assertEqual('rofs-a', partname)
-
- part_info = res.output.splitlines()[4]
- parttype = part_info.split(":")[4]
- partname = part_info.split(":")[5]
- self.assertEqual('ext4', parttype)
- self.assertEqual('primary', partname)
+ # verify partition size with wic
+ res = runCmd("export PARTED_SECTOR_SIZE=%d; parted -m %s unit b p" % (wic_sector_size, images[0]),
+ stderr=subprocess.PIPE)
- finally:
- os.environ['PATH'] = oldpath
+ print(res.output)
+ # parse parted output which looks like this:
+ # BYT;\n
+ # /var/tmp/wic/build/tmpgjzzefdd-202410281021-sda.direct:78569472B:file:4096:4096:gpt::;\n
+ # 1:139264B:1187839B:1048576B::emptyfat:msftdata;
+ # 2:1187840B:149270527B:148082688B:ext4:rofs-a:;
+ # 3:149270528B:297353215B:148082688B:ext4:primary:;
+ disk_info = res.output.splitlines()[1]
+ # Check sector sizes
+ sector_size_logical = int(disk_info.split(":")[3])
+ sector_size_physical = int(disk_info.split(":")[4])
+ self.assertEqual(wic_sector_size, sector_size_logical, "Logical sector size is not %d." % wic_sector_size)
+ self.assertEqual(wic_sector_size, sector_size_physical, "Physical sector size is not %d." % wic_sector_size)
+
+ # It is a known issue with parsed that a 4K FAT partition does
+ # not have a recognized filesystem type of *fat.
+ part_info = res.output.splitlines()[2]
+ partname = part_info.split(":")[5]
+ parttype = part_info.split(":")[6]
+ self.assertEqual('emptyfat', partname)
+ self.assertEqual('msftdata;', parttype)
+
+ part_info = res.output.splitlines()[3]
+ parttype = part_info.split(":")[4]
+ partname = part_info.split(":")[5]
+ self.assertEqual('ext4', parttype)
+ self.assertEqual('rofs-a', partname)
+
+ part_info = res.output.splitlines()[4]
+ parttype = part_info.split(":")[4]
+ partname = part_info.split(":")[5]
+ self.assertEqual('ext4', parttype)
+ self.assertEqual('primary', partname)
def test_wic_sector_size_cli(self):
"""Test sector size handling via CLI option."""
- oldpath = os.environ['PATH']
- os.environ['PATH'] = get_bb_var("PATH", "wic-tools")
-
- try:
- bitbake('core-image-minimal')
-
- with NamedTemporaryFile("w", suffix=".wks") as wks:
- wks.writelines(
- ['bootloader --ptable gpt\n',
- 'part --fstype vfat --fstype vfat --label emptyfat --size 1M\n',
- 'part --fstype ext4 --source rootfs --label rofs-a\n',
- 'part --fstype ext4 --source rootfs --use-uuid\n'])
- wks.flush()
- cmd = "wic create %s -e core-image-minimal -o %s --sector-size 4096" % (wks.name, self.resultdir)
- runCmd(cmd)
- wksname = os.path.splitext(os.path.basename(wks.name))[0]
- images = glob(os.path.join(self.resultdir, "%s-*direct" % wksname))
- self.assertEqual(1, len(images))
+ bitbake('core-image-minimal')
- sysroot = get_bb_var('RECIPE_SYSROOT_NATIVE', 'wic-tools')
- # list partitions
- result = runCmd("wic ls %s -n %s --sector-size 4096" % (images[0], sysroot))
- print(result.output)
- # 4 lines of output: header + 3 partitions
- self.assertEqual(4, len(result.output.split('\n')))
+ with NamedTemporaryFile("w", suffix=".wks") as wks:
+ wks.writelines(
+ ['bootloader --ptable gpt\n',
+ 'part --fstype vfat --fstype vfat --label emptyfat --size 1M\n',
+ 'part --fstype ext4 --source rootfs --label rofs-a\n',
+ 'part --fstype ext4 --source rootfs --use-uuid\n'])
+ wks.flush()
+ cmd = "wic create %s -e core-image-minimal -o %s --sector-size 4096" % (wks.name, self.resultdir)
+ runCmd(cmd)
+ wksname = os.path.splitext(os.path.basename(wks.name))[0]
+ images = glob(os.path.join(self.resultdir, "%s-*direct" % wksname))
+ self.assertEqual(1, len(images))
- # verify partition size with parted output
- res = runCmd("export PARTED_SECTOR_SIZE=%d; parted -m %s unit b p" % (4096, images[0]),
- stderr=subprocess.PIPE)
+ sysroot = get_bb_var('RECIPE_SYSROOT_NATIVE', 'wic-tools')
+ # list partitions
+ result = runCmd("wic ls %s -n %s --sector-size 4096" % (images[0], sysroot))
+ print(result.output)
+ # 4 lines of output: header + 3 partitions
+ self.assertEqual(4, len(result.output.split('\n')))
- print(res.output)
- # parse parted output which looks like this:
- # BYT;\n
- # /var/tmp/wic/build/tmpgjzzefdd-202410281021-sda.direct:78569472B:file:4096:4096:gpt::;\n
- # 1:139264B:1187839B:1048576B::emptyfat:msftdata;
- # 2:1187840B:149270527B:148082688B:ext4:rofs-a:;
- # 3:149270528B:297353215B:148082688B:ext4:primary:;
- disk_info = res.output.splitlines()[1]
- # Check sector sizes
- sector_size_logical = int(disk_info.split(":")[3])
- sector_size_physical = int(disk_info.split(":")[4])
- self.assertEqual(4096, sector_size_logical, "Logical sector size is not 4096.")
- self.assertEqual(4096, sector_size_physical, "Physical sector size is not 4096.")
-
- # It is a known issue with parsed that a 4K FAT partition does
- # not have a recognized filesystem type of *fat.
- part_info = res.output.splitlines()[2]
- partname = part_info.split(":")[5]
- parttype = part_info.split(":")[6]
- self.assertEqual('emptyfat', partname)
- self.assertEqual('msftdata;', parttype)
-
- part_info = res.output.splitlines()[3]
- parttype = part_info.split(":")[4]
- partname = part_info.split(":")[5]
- self.assertEqual('ext4', parttype)
- self.assertEqual('rofs-a', partname)
-
- part_info = res.output.splitlines()[4]
- parttype = part_info.split(":")[4]
- partname = part_info.split(":")[5]
- self.assertEqual('ext4', parttype)
- self.assertEqual('primary', partname)
+ # verify partition size with parted output
+ res = runCmd("export PARTED_SECTOR_SIZE=%d; parted -m %s unit b p" % (4096, images[0]),
+ stderr=subprocess.PIPE)
- finally:
- os.environ['PATH'] = oldpath
+ print(res.output)
+ # parse parted output which looks like this:
+ # BYT;\n
+ # /var/tmp/wic/build/tmpgjzzefdd-202410281021-sda.direct:78569472B:file:4096:4096:gpt::;\n
+ # 1:139264B:1187839B:1048576B::emptyfat:msftdata;
+ # 2:1187840B:149270527B:148082688B:ext4:rofs-a:;
+ # 3:149270528B:297353215B:148082688B:ext4:primary:;
+ disk_info = res.output.splitlines()[1]
+ # Check sector sizes
+ sector_size_logical = int(disk_info.split(":")[3])
+ sector_size_physical = int(disk_info.split(":")[4])
+ self.assertEqual(4096, sector_size_logical, "Logical sector size is not 4096.")
+ self.assertEqual(4096, sector_size_physical, "Physical sector size is not 4096.")
+
+ # It is a known issue with parsed that a 4K FAT partition does
+ # not have a recognized filesystem type of *fat.
+ part_info = res.output.splitlines()[2]
+ partname = part_info.split(":")[5]
+ parttype = part_info.split(":")[6]
+ self.assertEqual('emptyfat', partname)
+ self.assertEqual('msftdata;', parttype)
+
+ part_info = res.output.splitlines()[3]
+ parttype = part_info.split(":")[4]
+ partname = part_info.split(":")[5]
+ self.assertEqual('ext4', parttype)
+ self.assertEqual('rofs-a', partname)
+
+ part_info = res.output.splitlines()[4]
+ parttype = part_info.split(":")[4]
+ partname = part_info.split(":")[5]
+ self.assertEqual('ext4', parttype)
+ self.assertEqual('primary', partname)
class Wic2(WicTestCase):
@@ -1483,47 +1427,41 @@ run_wic_cmd() {
def test_extra_partition_space(self):
native_sysroot = get_bb_var("RECIPE_SYSROOT_NATIVE", "wic-tools")
- oldpath = os.environ['PATH']
- os.environ['PATH'] = get_bb_var("PATH", "wic-tools")
+ with NamedTemporaryFile("w", suffix=".wks") as tempf:
+ tempf.write("bootloader --ptable gpt\n" \
+ "part --ondisk hda --size 10M --extra-partition-space 10M --fstype=ext4\n" \
+ "part --ondisk hda --fixed-size 20M --extra-partition-space 10M --fstype=ext4\n" \
+ "part --source rootfs --ondisk hda --extra-partition-space 10M --fstype=ext4\n" \
+ "part --source rootfs --ondisk hda --fixed-size 200M --extra-partition-space 10M --fstype=ext4\n")
+ tempf.flush()
+
+ _, wicimg = self._get_wic(tempf.name)
- try:
- with NamedTemporaryFile("w", suffix=".wks") as tempf:
- tempf.write("bootloader --ptable gpt\n" \
- "part --ondisk hda --size 10M --extra-partition-space 10M --fstype=ext4\n" \
- "part --ondisk hda --fixed-size 20M --extra-partition-space 10M --fstype=ext4\n" \
- "part --source rootfs --ondisk hda --extra-partition-space 10M --fstype=ext4\n" \
- "part --source rootfs --ondisk hda --fixed-size 200M --extra-partition-space 10M --fstype=ext4\n")
- tempf.flush()
-
- _, wicimg = self._get_wic(tempf.name)
-
- res = runCmd("parted -m %s unit b p" % wicimg,
- native_sysroot=native_sysroot, stderr=subprocess.PIPE)
-
- # parse parted output which looks like this:
- # BYT;\n
- # /var/tmp/wic/build/tmpfwvjjkf_-201611101222-hda.direct:200MiB:file:512:512:msdos::;\n
- # 1:0.00MiB:200MiB:200MiB:ext4::;\n
- partlns = res.output.splitlines()[2:]
-
- self.assertEqual(4, len(partlns))
-
- # Test for each partitions that the extra part space exists
- for part in range(0, len(partlns)):
- part_file = os.path.join(self.resultdir, "selftest_img.part%d" % (part + 1))
- partln = partlns[part].split(":")
- self.assertEqual(7, len(partln))
- self.assertRegex(partln[3], r'^[0-9]+B$')
- part_size = int(partln[3].rstrip("B"))
- start = int(partln[1].rstrip("B")) / 512
- length = part_size / 512
- runCmd("dd if=%s of=%s skip=%d count=%d" %
- (wicimg, part_file, start, length))
- res = runCmd("dumpe2fs %s -h | grep \"^Block count\"" % part_file)
- fs_size = int(res.output.split(":")[1].strip()) * 1024
- self.assertLessEqual(fs_size + 10485760, part_size, "part file: %s" % part_file)
- finally:
- os.environ['PATH'] = oldpath
+ res = runCmd("parted -m %s unit b p" % wicimg,
+ native_sysroot=native_sysroot, stderr=subprocess.PIPE)
+
+ # parse parted output which looks like this:
+ # BYT;\n
+ # /var/tmp/wic/build/tmpfwvjjkf_-201611101222-hda.direct:200MiB:file:512:512:msdos::;\n
+ # 1:0.00MiB:200MiB:200MiB:ext4::;\n
+ partlns = res.output.splitlines()[2:]
+
+ self.assertEqual(4, len(partlns))
+
+ # Test for each partitions that the extra part space exists
+ for part in range(0, len(partlns)):
+ part_file = os.path.join(self.resultdir, "selftest_img.part%d" % (part + 1))
+ partln = partlns[part].split(":")
+ self.assertEqual(7, len(partln))
+ self.assertRegex(partln[3], r'^[0-9]+B$')
+ part_size = int(partln[3].rstrip("B"))
+ start = int(partln[1].rstrip("B")) / 512
+ length = part_size / 512
+ runCmd("dd if=%s of=%s skip=%d count=%d" %
+ (wicimg, part_file, start, length))
+ res = runCmd("dumpe2fs %s -h | grep \"^Block count\"" % part_file)
+ fs_size = int(res.output.split(":")[1].strip()) * 1024
+ self.assertLessEqual(fs_size + 10485760, part_size, "part file: %s" % part_file)
# TODO this test could also work on aarch64
@skipIfNotArch(['i586', 'i686', 'x86_64'])
@@ -1836,45 +1774,39 @@ INITRAMFS_IMAGE = "core-image-initramfs-boot"
testfile.write("test %s" % testfilename)
testfile.close()
- oldpath = os.environ['PATH']
- os.environ['PATH'] = get_bb_var("PATH", "wic-tools")
+ with NamedTemporaryFile("w", suffix=".wks") as wks:
+ wks.writelines([
+ 'part / --source extra_partition --ondisk sda --sourceparams "name=foo" --align 4 --size 5M\n',
+ 'part / --source extra_partition --ondisk sda --label foo --align 4 --size 5M\n',
+ 'part / --source extra_partition --ondisk sda --fstype=vfat --uuid e7d0824e-cda3-4bed-9f54-9ef5312d105d --align 4 --size 5M\n',
+ 'part / --source extra_partition --ondisk sda --fstype=ext4 --label bar --align 4 --size 5M\n',
+ 'bootloader --ptable gpt\n',
+ ])
+ wks.flush()
+ _, wicimg = self._get_wic(wks.name)
- try:
- with NamedTemporaryFile("w", suffix=".wks") as wks:
- wks.writelines([
- 'part / --source extra_partition --ondisk sda --sourceparams "name=foo" --align 4 --size 5M\n',
- 'part / --source extra_partition --ondisk sda --label foo --align 4 --size 5M\n',
- 'part / --source extra_partition --ondisk sda --fstype=vfat --uuid e7d0824e-cda3-4bed-9f54-9ef5312d105d --align 4 --size 5M\n',
- 'part / --source extra_partition --ondisk sda --fstype=ext4 --label bar --align 4 --size 5M\n',
- 'bootloader --ptable gpt\n',
- ])
- wks.flush()
- _, wicimg = self._get_wic(wks.name)
-
- result = runCmd("wic ls %s -n %s" % (wicimg, sysroot))
- partls = result.output.split('\n')[1:]
-
- # Assert the number of partitions is correct
- self.assertEqual(4, len(partls), msg="Expect 4 partitions, not %s" % result.output)
-
- # Fstype column from 'wic ls' should be fstype as given in the part command
- for part_id, part_fs in enumerate(["fat16", "fat16", "fat16", "ext4"]):
- self.assertIn(part_fs, partls[part_id])
-
- # For each partition, assert expected files exist
- for part, part_glob in enumerate([
- ["bar.conf"],
- ["foo.conf"],
- ["foobar.conf", "foobar2.conf", "bar3.conf", "bar4.conf"],
- ["bar.conf", "bar2.conf"],
- ]):
- for part_file in part_glob:
- result = runCmd("wic ls %s:%d/%s -n %s" % (wicimg, part + 1, part_file, sysroot))
- self.assertEqual(0, result.status, msg="File '%s' not found in the partition #%d" % (part_file, part))
+ result = runCmd("wic ls %s -n %s" % (wicimg, sysroot))
+ partls = result.output.split('\n')[1:]
- self.remove_config(config)
- finally:
- os.environ['PATH'] = oldpath
+ # Assert the number of partitions is correct
+ self.assertEqual(4, len(partls), msg="Expect 4 partitions, not %s" % result.output)
+
+ # Fstype column from 'wic ls' should be fstype as given in the part command
+ for part_id, part_fs in enumerate(["fat16", "fat16", "fat16", "ext4"]):
+ self.assertIn(part_fs, partls[part_id])
+
+ # For each partition, assert expected files exist
+ for part, part_glob in enumerate([
+ ["bar.conf"],
+ ["foo.conf"],
+ ["foobar.conf", "foobar2.conf", "bar3.conf", "bar4.conf"],
+ ["bar.conf", "bar2.conf"],
+ ]):
+ for part_file in part_glob:
+ result = runCmd("wic ls %s:%d/%s -n %s" % (wicimg, part + 1, part_file, sysroot))
+ self.assertEqual(0, result.status, msg="File '%s' not found in the partition #%d" % (part_file, part))
+
+ self.remove_config(config)
def test_fs_types(self):
"""Test filesystem types for empty and not empty partitions"""
--
2.50.0.173.g8b6f19ccfc3a
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v4 05/10] nativesdk-packagegroup-sdk-host: add an SDK_FEATURES lever
2026-07-24 9:01 [PATCH v4 00/10] wic: ship its tools, and add an SDK_FEATURES lever Trevor Woerner
` (3 preceding siblings ...)
2026-07-24 9:01 ` [PATCH v4 04/10] oeqa/selftest/wic: drop redundant per-test PATH overrides Trevor Woerner
@ 2026-07-24 9:01 ` Trevor Woerner
2026-07-24 9:01 ` [PATCH v4 06/10] nativesdk-packagegroup-sdk-host: add wic to SDK_FEATURES Trevor Woerner
` (4 subsequent siblings)
9 siblings, 0 replies; 12+ messages in thread
From: Trevor Woerner @ 2026-07-24 9:01 UTC (permalink / raw)
To: openembedded-core
Add SDK_FEATURES, a mechanism for optionally adding features to a
standalone SDK, in the same spirit as DISTRO_FEATURES, MACHINE_FEATURES
and IMAGE_FEATURES: a configuration adds a feature to the list and gets
the corresponding additions, and a developer reads the setting and knows
exactly what is being included.
This commit only introduces the variable (defaulting to empty) and
documents it; the features that consume it are wired up separately. An
empty default changes nothing on its own.
AI-Generated: codex/claude-opus 4.8 (xhigh)
Signed-off-by: Trevor Woerner <twoerner@gmail.com>
---
changes in v4:
- split out from the v3 "add wic via a new SDK_FEATURES lever" patch:
this patch now introduces only the SDK_FEATURES variable and its
documentation, defaulting to empty, with the individual features added
in their own patches
---
meta/conf/bitbake.conf | 1 +
meta/conf/documentation.conf | 1 +
2 files changed, 2 insertions(+)
diff --git a/meta/conf/bitbake.conf b/meta/conf/bitbake.conf
index bdf37d0da247..8f590ed374f0 100644
--- a/meta/conf/bitbake.conf
+++ b/meta/conf/bitbake.conf
@@ -898,6 +898,7 @@ OES_BITBAKE_CONF = "1"
MACHINE_FEATURES:append = " ${@oe.utils.filter_default_features('MACHINE_FEATURES', d)}"
SDK_MACHINE_FEATURES ?= ""
+SDK_FEATURES ?= ""
DISTRO_FEATURES:append = " ${@oe.utils.filter_default_features('DISTRO_FEATURES', d)}"
diff --git a/meta/conf/documentation.conf b/meta/conf/documentation.conf
index 842cf31739de..42c8327e10ff 100644
--- a/meta/conf/documentation.conf
+++ b/meta/conf/documentation.conf
@@ -361,6 +361,7 @@ SANITY_TESTED_DISTROS[doc] = "A list of the host distribution identifiers that t
SDK_ARCH[doc] = "The target architecture for the SDK."
SDK_DEPLOY[doc] = "The directory set up and used by the populate_sdk_base to which the SDK is deployed."
SDK_DIR[doc] = "The parent directory used by the OpenEmbedded build system when creating SDK output."
+SDK_FEATURES[doc] = "The list of optional features to add to the standalone SDK's host tools. Analogous to IMAGE_FEATURES but for the SDK host side."
SDK_NAME[doc] = "The base name for SDK output files."
SDK_OUTPUT[doc] = "The location used by the OpenEmbedded build system when creating SDK output."
SDKIMAGE_FEATURES[doc] = "Equivalent to IMAGE_FEATURES. However, this variable applies to the SDK generated from an image using the command 'bitbake -c populate_sdk imagename'."
--
2.50.0.173.g8b6f19ccfc3a
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v4 06/10] nativesdk-packagegroup-sdk-host: add wic to SDK_FEATURES
2026-07-24 9:01 [PATCH v4 00/10] wic: ship its tools, and add an SDK_FEATURES lever Trevor Woerner
` (4 preceding siblings ...)
2026-07-24 9:01 ` [PATCH v4 05/10] nativesdk-packagegroup-sdk-host: add an SDK_FEATURES lever Trevor Woerner
@ 2026-07-24 9:01 ` Trevor Woerner
2026-07-24 9:01 ` [PATCH v4 07/10] nativesdk-packagegroup-sdk-host: add an sbom SDK feature Trevor Woerner
` (3 subsequent siblings)
9 siblings, 0 replies; 12+ messages in thread
From: Trevor Woerner @ 2026-07-24 9:01 UTC (permalink / raw)
To: openembedded-core
wic is useful from an installed SDK for assembling or inspecting a wic
image, but adding it is not free: nativesdk-wic pulls in the tools it
runs (parted, gptfdisk, dosfstools, mtools, bmaptool, grub, btrfs-tools,
squashfs-tools, e2fsprogs, util-linux, tar, erofs-utils, and syslinux on
x86). Most SDKs do not need any of that, so wic should not be in the
host packagegroup unconditionally.
Gate wic in the host packagegroup on the "wic" SDK feature, which is not
enabled by default. A configuration that wants wic in its SDK adds the
"wic" feature to SDK_FEATURES and gets a working wic, together with the
tools it invokes, in the SDK.
AI-Generated: codex/claude-opus 4.8 (xhigh)
Signed-off-by: Trevor Woerner <twoerner@gmail.com>
---
changes in v4:
- split out from the v3 "add wic via a new SDK_FEATURES lever" patch:
this patch now only wires wic to the "wic" SDK feature
---
.../packagegroups/nativesdk-packagegroup-sdk-host.bb | 1 +
1 file changed, 1 insertion(+)
diff --git a/meta/recipes-core/packagegroups/nativesdk-packagegroup-sdk-host.bb b/meta/recipes-core/packagegroups/nativesdk-packagegroup-sdk-host.bb
index 51e48f250b19..c2974a57fe3e 100644
--- a/meta/recipes-core/packagegroups/nativesdk-packagegroup-sdk-host.bb
+++ b/meta/recipes-core/packagegroups/nativesdk-packagegroup-sdk-host.bb
@@ -29,6 +29,7 @@ RDEPENDS:${PN} = "\
nativesdk-bison \
nativesdk-flex \
nativesdk-perl-module-integer \
+ ${@bb.utils.contains('SDK_FEATURES', 'wic', 'nativesdk-wic', '', d)} \
"
RDEPENDS:${PN}:darwin = "\
--
2.50.0.173.g8b6f19ccfc3a
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v4 07/10] nativesdk-packagegroup-sdk-host: add an sbom SDK feature
2026-07-24 9:01 [PATCH v4 00/10] wic: ship its tools, and add an SDK_FEATURES lever Trevor Woerner
` (5 preceding siblings ...)
2026-07-24 9:01 ` [PATCH v4 06/10] nativesdk-packagegroup-sdk-host: add wic to SDK_FEATURES Trevor Woerner
@ 2026-07-24 9:01 ` Trevor Woerner
2026-07-24 9:01 ` [PATCH v4 08/10] nativesdk-packagegroup-sdk-host: add an lldb " Trevor Woerner
` (2 subsequent siblings)
9 siblings, 0 replies; 12+ messages in thread
From: Trevor Woerner @ 2026-07-24 9:01 UTC (permalink / raw)
To: openembedded-core
Software composition tooling is useful to have in an SDK for generating
or checking SPDX documents and scanning artifacts, but it is not needed
by every SDK and pulls in a Python dependency chain, so it should be
opt-in rather than always present.
Add an "sbom" SDK feature that pulls in the SPDX and SBOM/CVE tools
(nativesdk-python3-spdx-tools and nativesdk-python3-sbom-cve-check). It
is not enabled by default; a configuration that wants it adds the "sbom"
feature to SDK_FEATURES.
AI-Generated: codex/claude-opus 4.8 (xhigh)
Signed-off-by: Trevor Woerner <twoerner@gmail.com>
---
changes in v4:
- reordered ahead of the default-on qemu and gdb features so the opt-in
features are grouped together
changes in v3:
- new in v3
---
.../packagegroups/nativesdk-packagegroup-sdk-host.bb | 1 +
1 file changed, 1 insertion(+)
diff --git a/meta/recipes-core/packagegroups/nativesdk-packagegroup-sdk-host.bb b/meta/recipes-core/packagegroups/nativesdk-packagegroup-sdk-host.bb
index c2974a57fe3e..31710a23969e 100644
--- a/meta/recipes-core/packagegroups/nativesdk-packagegroup-sdk-host.bb
+++ b/meta/recipes-core/packagegroups/nativesdk-packagegroup-sdk-host.bb
@@ -30,6 +30,7 @@ RDEPENDS:${PN} = "\
nativesdk-flex \
nativesdk-perl-module-integer \
${@bb.utils.contains('SDK_FEATURES', 'wic', 'nativesdk-wic', '', d)} \
+ ${@bb.utils.contains('SDK_FEATURES', 'sbom', 'nativesdk-python3-spdx-tools nativesdk-python3-sbom-cve-check', '', d)} \
"
RDEPENDS:${PN}:darwin = "\
--
2.50.0.173.g8b6f19ccfc3a
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v4 08/10] nativesdk-packagegroup-sdk-host: add an lldb SDK feature
2026-07-24 9:01 [PATCH v4 00/10] wic: ship its tools, and add an SDK_FEATURES lever Trevor Woerner
` (6 preceding siblings ...)
2026-07-24 9:01 ` [PATCH v4 07/10] nativesdk-packagegroup-sdk-host: add an sbom SDK feature Trevor Woerner
@ 2026-07-24 9:01 ` Trevor Woerner
2026-07-24 9:01 ` [PATCH v4 09/10] nativesdk-packagegroup-sdk-host: gate qemu behind SDK_FEATURES Trevor Woerner
2026-07-24 9:01 ` [PATCH v4 10/10] packagegroup-cross-canadian: gate gdb " Trevor Woerner
9 siblings, 0 replies; 12+ messages in thread
From: Trevor Woerner @ 2026-07-24 9:01 UTC (permalink / raw)
To: openembedded-core
Some developers prefer lldb to gdb as their SDK host debugger. It is a
large addition and not wanted by default, so make it opt-in.
Add an "lldb" SDK feature that pulls in nativesdk-lldb. It is not enabled
by default; a configuration that wants it adds the "lldb" feature to
SDK_FEATURES.
AI-Generated: codex/claude-opus 4.8 (xhigh)
Signed-off-by: Trevor Woerner <twoerner@gmail.com>
---
changes in v4:
- reordered ahead of the default-on qemu and gdb features so the opt-in
features are grouped together
changes in v3:
- new in v3
---
.../packagegroups/nativesdk-packagegroup-sdk-host.bb | 1 +
1 file changed, 1 insertion(+)
diff --git a/meta/recipes-core/packagegroups/nativesdk-packagegroup-sdk-host.bb b/meta/recipes-core/packagegroups/nativesdk-packagegroup-sdk-host.bb
index 31710a23969e..9e3190af2a56 100644
--- a/meta/recipes-core/packagegroups/nativesdk-packagegroup-sdk-host.bb
+++ b/meta/recipes-core/packagegroups/nativesdk-packagegroup-sdk-host.bb
@@ -31,6 +31,7 @@ RDEPENDS:${PN} = "\
nativesdk-perl-module-integer \
${@bb.utils.contains('SDK_FEATURES', 'wic', 'nativesdk-wic', '', d)} \
${@bb.utils.contains('SDK_FEATURES', 'sbom', 'nativesdk-python3-spdx-tools nativesdk-python3-sbom-cve-check', '', d)} \
+ ${@bb.utils.contains('SDK_FEATURES', 'lldb', 'nativesdk-lldb', '', d)} \
"
RDEPENDS:${PN}:darwin = "\
--
2.50.0.173.g8b6f19ccfc3a
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v4 09/10] nativesdk-packagegroup-sdk-host: gate qemu behind SDK_FEATURES
2026-07-24 9:01 [PATCH v4 00/10] wic: ship its tools, and add an SDK_FEATURES lever Trevor Woerner
` (7 preceding siblings ...)
2026-07-24 9:01 ` [PATCH v4 08/10] nativesdk-packagegroup-sdk-host: add an lldb " Trevor Woerner
@ 2026-07-24 9:01 ` Trevor Woerner
2026-07-24 9:21 ` Patchtest results for " patchtest
2026-07-24 9:01 ` [PATCH v4 10/10] packagegroup-cross-canadian: gate gdb " Trevor Woerner
9 siblings, 1 reply; 12+ messages in thread
From: Trevor Woerner @ 2026-07-24 9:01 UTC (permalink / raw)
To: openembedded-core
qemu (with its helper) is added to every standalone SDK on the
architectures where it builds. It is only useful for running target
binaries on the host via qemu-usermode, which not every SDK user wants,
and it is a large thing to carry when they do not.
Move it behind the "qemu" SDK feature, which is enabled by default so an
unmodified configuration still gets qemu exactly as before on the same
architectures; the architecture guard is retained. A configuration that
does not want it removes the "qemu" feature from SDK_FEATURES.
AI-Generated: codex/claude-opus 4.8 (xhigh)
Signed-off-by: Trevor Woerner <twoerner@gmail.com>
---
changes in v4:
- reordered after the opt-in features (wic, sbom, lldb); the default-on
features (qemu, gdb) now come last
changes in v3:
- new in v3
---
meta/conf/bitbake.conf | 2 +-
.../packagegroups/nativesdk-packagegroup-sdk-host.bb | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/meta/conf/bitbake.conf b/meta/conf/bitbake.conf
index 8f590ed374f0..f96ede6d88df 100644
--- a/meta/conf/bitbake.conf
+++ b/meta/conf/bitbake.conf
@@ -898,7 +898,7 @@ OES_BITBAKE_CONF = "1"
MACHINE_FEATURES:append = " ${@oe.utils.filter_default_features('MACHINE_FEATURES', d)}"
SDK_MACHINE_FEATURES ?= ""
-SDK_FEATURES ?= ""
+SDK_FEATURES ?= "qemu"
DISTRO_FEATURES:append = " ${@oe.utils.filter_default_features('DISTRO_FEATURES', d)}"
diff --git a/meta/recipes-core/packagegroups/nativesdk-packagegroup-sdk-host.bb b/meta/recipes-core/packagegroups/nativesdk-packagegroup-sdk-host.bb
index 9e3190af2a56..bf9de4201810 100644
--- a/meta/recipes-core/packagegroups/nativesdk-packagegroup-sdk-host.bb
+++ b/meta/recipes-core/packagegroups/nativesdk-packagegroup-sdk-host.bb
@@ -13,7 +13,7 @@ PACKAGEGROUP_DISABLE_COMPLEMENTARY = "1"
# build some recent linux kernels (5.14+) for arm
RDEPENDS:${PN} = "\
nativesdk-pkgconfig \
- ${@'nativesdk-qemu nativesdk-qemu-helper' if d.getVar('SDK_ARCH') in ['x86_64', 'aarch64', 'ppc64', 'ppc64le', 'riscv64', 'loongarch64', 'mips64', 's390x', 'sparc64'] else ''} \
+ ${@'nativesdk-qemu nativesdk-qemu-helper' if bb.utils.contains('SDK_FEATURES', 'qemu', True, False, d) and d.getVar('SDK_ARCH') in ['x86_64', 'aarch64', 'ppc64', 'ppc64le', 'riscv64', 'loongarch64', 'mips64', 's390x', 'sparc64'] else ''} \
nativesdk-pseudo \
nativesdk-unfs3 \
nativesdk-opkg \
--
2.50.0.173.g8b6f19ccfc3a
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v4 10/10] packagegroup-cross-canadian: gate gdb behind SDK_FEATURES
2026-07-24 9:01 [PATCH v4 00/10] wic: ship its tools, and add an SDK_FEATURES lever Trevor Woerner
` (8 preceding siblings ...)
2026-07-24 9:01 ` [PATCH v4 09/10] nativesdk-packagegroup-sdk-host: gate qemu behind SDK_FEATURES Trevor Woerner
@ 2026-07-24 9:01 ` Trevor Woerner
9 siblings, 0 replies; 12+ messages in thread
From: Trevor Woerner @ 2026-07-24 9:01 UTC (permalink / raw)
To: openembedded-core
The cross-canadian gdb is added to every SDK's toolchain packagegroup
unconditionally. A host cross-debugger is part of what most people
expect from an SDK, but it is also large, and an SDK built only to
compile does not need it.
Move it behind the "gdb" SDK feature, which is enabled by default so an
unmodified configuration still gets the cross gdb exactly as before;
binutils and gcc remain unconditional, as a cross-compiler is intrinsic
to an SDK. A configuration that wants a compile-only SDK removes the
"gdb" feature from SDK_FEATURES.
AI-Generated: codex/claude-opus 4.8 (xhigh)
Signed-off-by: Trevor Woerner <twoerner@gmail.com>
---
changes in v4:
- reordered after the opt-in features (wic, sbom, lldb); the default-on
features (qemu, gdb) now come last
changes in v3:
- new in v3
---
meta/conf/bitbake.conf | 2 +-
meta/recipes-core/packagegroups/packagegroup-cross-canadian.bb | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/meta/conf/bitbake.conf b/meta/conf/bitbake.conf
index f96ede6d88df..5716b7176ebd 100644
--- a/meta/conf/bitbake.conf
+++ b/meta/conf/bitbake.conf
@@ -898,7 +898,7 @@ OES_BITBAKE_CONF = "1"
MACHINE_FEATURES:append = " ${@oe.utils.filter_default_features('MACHINE_FEATURES', d)}"
SDK_MACHINE_FEATURES ?= ""
-SDK_FEATURES ?= "qemu"
+SDK_FEATURES ?= "gdb qemu"
DISTRO_FEATURES:append = " ${@oe.utils.filter_default_features('DISTRO_FEATURES', d)}"
diff --git a/meta/recipes-core/packagegroups/packagegroup-cross-canadian.bb b/meta/recipes-core/packagegroups/packagegroup-cross-canadian.bb
index 49c075eb1166..9db3cfa28831 100644
--- a/meta/recipes-core/packagegroups/packagegroup-cross-canadian.bb
+++ b/meta/recipes-core/packagegroups/packagegroup-cross-canadian.bb
@@ -13,7 +13,7 @@ GDB = "gdb-cross-canadian-${TRANSLATED_TARGET_ARCH}"
RDEPENDS:${PN} = "\
${@all_multilib_tune_values(d, 'BINUTILS')} \
${@all_multilib_tune_values(d, 'GCC')} \
- ${@all_multilib_tune_values(d, 'GDB')} \
+ ${@all_multilib_tune_values(d, 'GDB') if bb.utils.contains('SDK_FEATURES', 'gdb', True, False, d) else ''} \
meta-environment-${MACHINE} \
"
--
2.50.0.173.g8b6f19ccfc3a
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Patchtest results for [PATCH v4 09/10] nativesdk-packagegroup-sdk-host: gate qemu behind SDK_FEATURES
2026-07-24 9:01 ` [PATCH v4 09/10] nativesdk-packagegroup-sdk-host: gate qemu behind SDK_FEATURES Trevor Woerner
@ 2026-07-24 9:21 ` patchtest
0 siblings, 0 replies; 12+ messages in thread
From: patchtest @ 2026-07-24 9:21 UTC (permalink / raw)
To: Trevor Woerner; +Cc: openembedded-core
[-- Attachment #1: Type: text/plain, Size: 3075 bytes --]
Thank you for your submission. Patchtest identified one
or more issues with the patch. Please see the log below for
more information:
---
Testing patch /home/patchtest/share/mboxes/v4-09-10-nativesdk-packagegroup-sdk-host-gate-qemu-behind-SDK_FEATURES.patch
FAIL: test max line length: Patch line too long (current length 243, maximum is 200) (test_metadata.TestMetadata.test_max_line_length)
PASS: test CVE check ignore (test_metadata.TestMetadata.test_cve_check_ignore)
PASS: test Signed-off-by presence (test_mbox.TestMbox.test_signed_off_by_presence)
PASS: test author valid (test_mbox.TestMbox.test_author_valid)
PASS: test commit message presence (test_mbox.TestMbox.test_commit_message_presence)
PASS: test commit message user tags (test_mbox.TestMbox.test_commit_message_user_tags)
PASS: test lic files chksum modified not mentioned (test_metadata.TestMetadata.test_lic_files_chksum_modified_not_mentioned)
PASS: test mbox format (test_mbox.TestMbox.test_mbox_format)
PASS: test non-AUH upgrade (test_mbox.TestMbox.test_non_auh_upgrade)
PASS: test shortlog format (test_mbox.TestMbox.test_shortlog_format)
PASS: test shortlog length (test_mbox.TestMbox.test_shortlog_length)
PASS: test target mailing list (test_mbox.TestMbox.test_target_mailing_list)
SKIP: pretest pylint: No python related patches, skipping test (test_python_pylint.PyLint.pretest_pylint)
SKIP: pretest src uri left files: Patch cannot be merged (test_metadata.TestMetadata.pretest_src_uri_left_files)
SKIP: test CVE tag format: No new source patches introduced (test_patch.TestPatch.test_cve_tag_format)
SKIP: test Signed-off-by presence: No new source patches introduced (test_patch.TestPatch.test_signed_off_by_presence)
SKIP: test Upstream-Status presence: No new source patches introduced (test_patch.TestPatch.test_upstream_status_presence_format)
SKIP: test bugzilla entry format: No bug ID found (test_mbox.TestMbox.test_bugzilla_entry_format)
SKIP: test lic files chksum presence: No added recipes, skipping test (test_metadata.TestMetadata.test_lic_files_chksum_presence)
SKIP: test license presence: No added recipes, skipping test (test_metadata.TestMetadata.test_license_presence)
SKIP: test pylint: No python related patches, skipping test (test_python_pylint.PyLint.test_pylint)
SKIP: test series merge on head: Merge test is disabled for now (test_mbox.TestMbox.test_series_merge_on_head)
SKIP: test src uri left files: Patch cannot be merged (test_metadata.TestMetadata.test_src_uri_left_files)
SKIP: test summary presence: No added recipes, skipping test (test_metadata.TestMetadata.test_summary_presence)
---
Please address the issues identified and
submit a new revision of the patch, or alternatively, reply to this
email with an explanation of why the patch should be accepted. If you
believe these results are due to an error in patchtest, please submit a
bug at https://bugzilla.yoctoproject.org/ (use the 'Patchtest' category
under 'Yocto Project Subprojects'). For more information on specific
failures, see: https://wiki.yoctoproject.org/wiki/Patchtest. Thank
you!
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2026-07-24 9:21 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-24 9:01 [PATCH v4 00/10] wic: ship its tools, and add an SDK_FEATURES lever Trevor Woerner
2026-07-24 9:01 ` [PATCH v4 01/10] wic-tools: move bootloader firmware staging into the wic oe-selftest Trevor Woerner
2026-07-24 9:01 ` [PATCH v4 02/10] wic: add runtime dependencies on the tools it invokes Trevor Woerner
2026-07-24 9:01 ` [PATCH v4 03/10] oeqa/selftest/wic: drop dead COREBASE/scripts wic lookup Trevor Woerner
2026-07-24 9:01 ` [PATCH v4 04/10] oeqa/selftest/wic: drop redundant per-test PATH overrides Trevor Woerner
2026-07-24 9:01 ` [PATCH v4 05/10] nativesdk-packagegroup-sdk-host: add an SDK_FEATURES lever Trevor Woerner
2026-07-24 9:01 ` [PATCH v4 06/10] nativesdk-packagegroup-sdk-host: add wic to SDK_FEATURES Trevor Woerner
2026-07-24 9:01 ` [PATCH v4 07/10] nativesdk-packagegroup-sdk-host: add an sbom SDK feature Trevor Woerner
2026-07-24 9:01 ` [PATCH v4 08/10] nativesdk-packagegroup-sdk-host: add an lldb " Trevor Woerner
2026-07-24 9:01 ` [PATCH v4 09/10] nativesdk-packagegroup-sdk-host: gate qemu behind SDK_FEATURES Trevor Woerner
2026-07-24 9:21 ` Patchtest results for " patchtest
2026-07-24 9:01 ` [PATCH v4 10/10] packagegroup-cross-canadian: gate gdb " Trevor Woerner
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.