Supporting multiple build configurations with Yocto

Supporting multiple build configurations with Yocto

When adding new MACHINE and DISTRO configurations to Yocto, handling build setup for all of them can become complicated. The increased complexity is especially obvious when new DISTRO configurations are introduced, since different build directories are needed in order to avoid polluting each other’s environment (like we had in the previous post on QEMU NOR SPI).

Having separate build directories also means that builds for both configurations cannot be performed at the same time using the same bitbake instance, and products of one build cannot be easily used in another build.

Yocto has a solution for this problem: multiconfig.

Tip

Yocto does support dynamic-layers which can help when different configurations depend on different layers. The same can be accomplished using multiconfig with BBMASK to mask layers that should not be used for the selected configuration.

Yocto multiconfig

Yocto multiconfig provides a mechanism to specify different configurations, as if having different local.conf files, but making builds in the same build directory. That way, the shared state cache and download directories are shared between configurations, which saves both time during build and space on the build machine.

It is also possible to specify that multiconfigs should use different TMPDIR, which is useful when different DISTROs are used between multiconfigs, in order to avoid polluting each other’s environment.

The multiconfig is defined in the conf/multiconfig directory of a layer or in the build directory. For each multiconfig option an entry in the BBMULTICONFIG variable of the local.conf should exist. There is also the default configuration, where configuration stems only from the local.conf file.


Looking to apply the multiconfig for the setup in QEMU SPI NOR post, the default configuration will cover the regular build running from the eMMC, and a new multiconfig called recovery will be introduced to cover the build of recovery image. Therefore, the local.conf should contain the following definition

BBMULTICONFIG = "recovery"

The value of the current multiconfig that is used for building can be fetched using BB_CURRENT_MC, so that parameter can be used in recipes to have conditional includes. Of course, the regular ways to make disctinction between builds, like MACHINEOVERRIDES or DISTROOVERRIDES still apply, so BB_CURRENT_MC should only be used as a supplement.

Note

The Yocto multiconfig page covers all the details on use of multiconfig with examples.

Example multiconfig

Tip

All of the changes that will be described, plus a few more which are required for this to work, are available in the scarthgap branch of meta-mistra and qemu-sunxi-yocto repositories in Github.

Continuing our example, the local.conf (from where the default configuration stems) should be configured to specify the default DISTRO to be mistra-framebuffer and the default MACHINE cubieboard-ng.

DISTRO ?= "mistra-framebuffer"
MACHINE ?= "cubieboard-ng"

The recovery multiconfig will then change DISTRO to mistra-recovery in the conf/multiconfig/recovery.conf file in the meta-mistra layer.

TMPDIR .= "-${BB_CURRENT_MC}"

DISTRO = "mistra-recovery"
MACHINE = "cubieboard-ng"

Since different DISTRO is used compared to the default configuration, the TMPDIR is redefined to have multiconfig value in it, so it is different from the other configurations.

Running builds

After the multiconfig definition is in place, the build is done using bitbake. The format of the target that is built is mc:<multiconfig>:<recipe>, where <multiconfig> is an empty string for the default configuration.

So, if we want to build the update-image for the default configuration, command would be

bitbake mc::update-image

The command for building the bootloader and mistra-swupdate-recovery for the recovery multiconfig is

bitbake mc:recovery:virtual/bootloader mc:recovery:mistra-swupdate-recovery

And the command to build all these three targets at the same time

bitbake mc::update-image mc:recovery:virtual/bootloader mc:recovery:mistra-swupdate-recovery

The output files for all the targets would be under the same build but different TMPDIR directories (tmp and tmp-recovery).

Multiconfig task dependencies

Multiconfig also provides a way to specify dependencies between tasks in different configs using mcdepends, which simplifies integration between different configs.

For instance, if we wanted to include the recovery fitImage in the rootfs of the regular mistra-swupdate (for instance if we wanted to update the stored fitImage in the SPI NOR flash memory), we could add the following dependency in the mistra-swupdate.bb

do_rootfs[mcdepends] = "mc::recovery:virtual/kernel:do_deploy"

and copy the file in the ROOTFS_POSTPROCESS_COMMAND

copy_fitimage() {
  install -d ${IMAGE_DIR}/usr/share/recovery
  install -m 0644 ${TMPDIR}-recovery/deploy/images/cubieboard-ng/fitImage-cubieboard-ng.bin ${IMAGE_DIR}/usr/share/recovery/fitImage
}

ROOTFS_POSTPROCESS_COMMAND += "copy_fitimage"

Things to keep in mind

Multiconfig comes with many benefits, but there are also some things to keep in mind before using them.

With more multiconfigs that are used, the preparation step, where dependencies between tasks and recipes are analyzed, takes much longer every time configuration is changed, since that same step is done for all of the defined multiconfig options, plus the default configuration.

This also means that each of the multiconfig configurations has to be valid for all recipes at the time of building. Therefore, masking unused parts of layers using BBMASK and scoping recipes that apply to certain configurations using COMPATIBLE_MACHINE should be done in order to streamline builds.

Summary

This was a short overview on Yocto multiconfig. Multiconfig allows creating separate build configurations and specifying dependencies between them, so they can all be built at the same time and within the same build directory, sharing same download and sstate cache, which saves both time and space.

Subscribe
If you would like to get information as soon as new content is published, please subscribe to the "MistraSolutions newsletter".