Build/demo integration project for Eclipse Ankaios on Yocto/OpenEmbedded.
This repository is not a reusable layer. It provides the tooling and image
glue to build demo images, and consumes the reusable
meta-ankaios layer (which
ships the Ankaios recipe) from git.
To build a Yocto image you need
- At least 90 GB of free disk space
- At least 20-32 GB of RAM
All images run Ankaios and start containers with Podman. Both build systems
(kas and bitbake-setup) share the same download and sstate cache (see
Shared build cache below), so sources and sstate artifacts
are reused across build variants.
The dev container already has all required tools installed so the build can be easily started in it.
The repo contains six kas build configs, split by Yocto release. Each variant
config includes the matching kas-common-<release>.yml, so you build the variant
directly:
- kas-full-cmd-systemd-whinlatter.yml —
core-image-full-cmdlinewith systemd on Yocto 5.3 "Whinlatter" - kas-minimal-sysvinit-whinlatter.yml —
core-image-minimalwith sysvinit on Yocto 5.3 "Whinlatter" - kas-full-cmd-systemd-wrynose.yml —
core-image-full-cmdlinewith systemd on Yocto 6.0 "Wrynose" - kas-minimal-sysvinit-wrynose.yml —
core-image-minimalwith sysvinit on Yocto 6.0 "Wrynose" - kas-full-cmd-systemd-kirkstone.yml —
core-image-full-cmdlinewith systemd on Yocto 4.0 "Kirkstone" - kas-minimal-sysvinit-kirkstone.yml —
core-image-minimalwith sysvinit on Yocto 4.0 "Kirkstone"
Important — use a dedicated build directory per config. kas does not set the build directory from the config file; it defaults to
$PWD/buildfor every config. If you build more than one variant from the same directory, they clobber each other'sbuild/confandbuild/tmp(e.g. switching release fails withTEMPLATECONF value points to nonexistent directory). PointKAS_BUILD_DIRat a per-variant folder so each build is isolated (kas only creates the final build dir, somkdir -pits parentkas-builds/first).
The following example builds a minimal Yocto 6.0 "Wrynose" image with sysvinit as
init manager into its own build directory. Create the directory first, because kas
only creates the final build dir, not its parent kas-builds/:
mkdir -p kas-builds/minimal-sysvinit-wrynose
KAS_BUILD_DIR=kas-builds/minimal-sysvinit-wrynose \
kas build kas-minimal-sysvinit-wrynose.ymlAfterwards you can start a kas shell and run the image with qemu and login with
user root (no password). Use the same KAS_BUILD_DIR so the shell attaches to
the build you just made:
# First start the shell
KAS_BUILD_DIR=kas-builds/minimal-sysvinit-wrynose \
kas shell kas-minimal-sysvinit-wrynose.yml
# And in the shell run qemu
runqemu snapshot nographic slirp qemuparams="-m 1024"To build one of the other five options, use the desired config file and give it a
matching KAS_BUILD_DIR (e.g. kas-builds/full-cmd-systemd-kirkstone).
To also route downloads/sstate through the Elektrobit Artifactory mirror, layer
kas-eb-mirror.yml on top (see
Elektrobit Artifactory mirror):
mkdir -p kas-builds/minimal-sysvinit-whinlatter
KAS_BUILD_DIR=kas-builds/minimal-sysvinit-whinlatter \
kas build kas-minimal-sysvinit-whinlatter.yml:kas-eb-mirror.ymlTip: there are also
justcommands that set a dedicatedKAS_BUILD_DIRfor you, so you don't have to remember it. They default to Whinlatter and take aRELEASE=wrynose/RELEASE=kirkstoneoverride:just kas-build-sysvinit-minimal # minimal + sysvinit (whinlatter) just RELEASE=kirkstone kas-build-sysvinit-minimal just kas-run-systemd-full # build + run full + systemd in QEMUAdd
EB_MIRROR=1to route through the Elektrobit Artifactory mirror (see Elektrobit Artifactory mirror), e.g.just EB_MIRROR=1 kas-build-sysvinit-minimal.Run
just --listto see them all.
This section provides information on building an image with bitbake-setup.
Tip: there are also
justcommands that handle the most common bitbake-setup configs. Runjust --listto see them.
The following bitbake-setup profiles are available as an alternative to some
of the kas build configs above:
Note: Kirkstone is not supported by
bitbake-setupbecause that tool was introduced after Yocto 4.0.
The bitbake-setup executable is provided by the bitbake repo which is not included in
the current devcontainer. To get the repo in order to prepare the environment, just run
once the following script (or use just, it willdo it for you ;) ):
./scripts/bitbake-setup-repo.shAfterwards (or if bitbake-setup was already available) continue with the setup init:
bitbake-setup init --non-interactive ./bitbake-setup-ankaios-whinlatter.conf.json <runtime-oriented config> <machine target>For Wrynose, use ./bitbake-setup-ankaios-wrynose.conf.json instead.
Note: the
justtargets use Whinlatter by default and can be switched to Wrynose via:just RELEASE=wrynose <target>
The supported runtime-oriented configurations are:
ankaios-sysvinitankaios-systemd
and the supported machine targets:
machine/qemux86-64machine/raspberrypi4-64machine/raspberrypi5
For Raspberry Pi machine targets (raspberrypi4-64 and raspberrypi5), the image
includes rootfs-resize, which expands the root partition and filesystem on first
boot to use the full SD card capacity.
After the setup is complete, source the environment with:
. bitbake-builds/<runtime-oriented config>-<release>-<machine target>/build/init-build-envNote that after sourcing the config, the environment is set for exactly this runtime-oriented config, release, and machine target. Use another shell or source another environment to change this.
To build the image, trigger the bitbake command with the preferred target:
bitbake <image-target>where the image target can be one of the following (other targets would probably work too, but these are tested):
core-image-minimalcore-image-full-cmdline
After the build is complete, run QEMU from the same shell with:
runqemu snapshot nographic slirpThe following two examples show how to build a minimal image with SysVinit and a full-cmdline image with Systemd, but you can also mix and match with different configs. For example, you can try to build a full-cmdline image with SysVinit for RaspberryPi4.
For a minimal image with a SysV init configuration for qemux86-64:
bitbake-setup init --non-interactive ./bitbake-setup-ankaios-whinlatter.conf.json ankaios-sysvinit machine/qemux86-64
. bitbake-builds/ankaios-sysvinit-whinlatter-qemux86-64/build/init-build-env
bitbake core-image-minimalSystemd configuration example:
bitbake-setup init --non-interactive ./bitbake-setup-ankaios-whinlatter.conf.json ankaios-systemd machine/qemux86-64
. bitbake-builds/ankaios-systemd-whinlatter-qemux86-64/build/init-build-env
bitbake core-image-full-cmdlineAll builds — both kas and bitbake-setup, and every release/runtime variant —
share a single download and sstate cache at:
/workspace/bitbake-shared-cache/
├── downloads/ # DL_DIR
└── sstate-cache/ # SSTATE_DIR
This is set in meta-ankaios-demo/conf/fragments/ankaios/common.conf and the
kas-common-*.yml files. Because every build directory points at the same
absolute path, downloads and sstate are reused across all builds instead of being
re-fetched/rebuilt per build directory. The folder is git-ignored.
Builds are expected to run inside the devcontainer. The path is intentionally
absolute (/workspace/...) so the cache is shared regardless of where a given
build directory lives. By default it sits inside the workspace bind mount, so it
persists on the host (inside the repo checkout) with no root-owned directories.
To keep the (large) cache outside the repo so it survives deleting or
re-cloning the repo, opt in to a host-side mount: create a bitbake-shared-cache
folder next to this repo on the host, then uncomment the shared-cache mount in
.devcontainer/devcontainer.json. The mount is opt-in on purpose — it is only
used if that folder already exists.
If you build directly on the host (no devcontainer), /workspace/bitbake-shared-cache
will not exist and would require write access to /. Point the cache at a
writable location instead by overriding DL_DIR/SSTATE_DIR, e.g.:
DL_DIR="$HOME/bitbake-shared-cache/downloads" \
SSTATE_DIR="$HOME/bitbake-shared-cache/sstate-cache" \
kas shell kas-common-whinlatter.yml -c "bitbake ankaios-bin"or add an override fragment/overlay that sets those two variables.
Elektrobit-internal builds can route source downloads and sstate through the Elektrobit Artifactory mirror instead of hitting upstream servers. This is off by default and lives in an opt-in fragment/overlay so the public repo builds without any Elektrobit access.
Requirements:
- Network access to
*.elektrobit.com. - A
~/.netrc(mode600) with the mirror credentials forartifactory.elektrobit.com(the devcontainer bind-mounts your host~/.netrc).
Enable it per build system:
-
bitbake-setup — add the fragment to the setup's
oe-fragments, e.g. appendmeta-ankaios-demo/ankaios/eb-mirroralongside the existingmeta-ankaios-demo/ankaios/minimal-sysvinit/full-systemdfragment inbitbake-setup-ankaios-*.conf.json. -
kas — layer
kas-eb-mirror.ymlon top of the config on the command line:kas build kas-minimal-sysvinit-whinlatter.yml:kas-eb-mirror.yml
What it configures:
SOURCE_MIRROR_URL+INHERIT += "own-mirrors"— sets PREMIRRORS so source fetches try Artifactory first (upstream stays as fallback).SSTATE_MIRRORS =+ ...— prepends the Artifactory sstate mirror in front of the public Yocto sstate mirror (public mirror stays as fallback).BB_GENERATE_MIRROR_TARBALLS = "1"— so fetched source/git downloads can be published back to the mirror withscripts/push_mirror.sh.
UNINATIVE_URL points BitBake at the mirror for the uninative toolchain
tarball. Unlike normal source downloads, it has no upstream fallback — if the
mirror does not yet contain the uninative tarball, a clean build fails instead of
fetching it from elsewhere. For that reason it is left commented out in
eb-mirror.conf / kas-eb-mirror.yml:
# UNINATIVE_URL = "${SOURCE_MIRROR_URL}"
Only enable it after the mirror has been seeded: run a build once (which downloads
uninative), publish with scripts/push_mirror.sh, then uncomment the line so
subsequent builds pull uninative from Artifactory as well.
scripts/push_mirror.sh uploads the local caches to Artifactory so later builds
can pull from the mirror. It pushes both caches in place, preserving relative
paths so the layout matches what SOURCE_MIRROR_URL / SSTATE_MIRRORS expect:
DL_DIR→.../linux/yocto/package-mirror/SSTATE_DIR→.../linux/yocto/sstate-mirror/
Prerequisites:
- A
~/.netrc(mode600) with deploy rights on the target repo forartifactory.elektrobit.com. - Builds run with
BB_GENERATE_MIRROR_TARBALLS = "1"(the eb-mirror fragment/overlay sets this) so source/git downloads exist as tarballs. The live VCS working dirs (git2/,svn/, ...) are not uploaded, only their tarballs.
Usage:
# preview what would be uploaded (HEAD probe only, no PUT)
scripts/push_mirror.sh --dry-run
# publish
scripts/push_mirror.shBehaviour and configuration:
- Files already present on the mirror are skipped (HEAD returns
200); missing files are uploaded withcurl --fail, so any auth/permission error (401/403) fails the run with a non-zero exit. - Environment overrides:
DL_DIR,SSTATE_DIR,MIRROR_BASE_URL, andJOBS(parallel uploads, default8).
The dev container includes just and oelint-adv.
To lint the .bb recipe files in the meta-ankaios-demo layer, run:
just lintThe command walks the recipe directories, prints each parsed file, and then prints only lint warnings and errors for that file.
Question: The build suddenly exits with "[process exited with code 1 (0x00000001)]".
Answer: Problems might be out of memory or disk space. Check the remaining
disk space with df -h. Check the memory with free -h. On WSL2 you can increase
the memory by editing %USERPROFILE%\.wslconfig and adding:
[wsl2]
memory=25GBQuestion: I get fetch errors during the bitbake build.
Answer: Unfortunately this sometimes happens during the download of the required packages. If it happens, just rerun the build again until it succeeds.
Question: I use WSL and ran out of space during the builds.
Answer: Even if you delete some files on the Linux system, the space will not automatically be reclaimed as free. To do this follow these steps:
-
First trim the disk on the Linux guest:
sudo fstrim /.
-
Then shutdown WSL from a windows shell:
wsl.exe --shutdown -
Run diskpart from a windows shell:
diskpart -
In DISKPART select the virtual disk by customizing the following to your machine:
select vdisk file="C:\Users\<user name>\AppData\Local\Packages\<guest name>\LocalState\ext4.vhdx" -
And trigger the compacting:
compact vdisk