The OpenEmbedded build system used by the Yocto Project has a powerful feature that is slightly hidden in the documentation: package configuration, controlled by the PACKAGECONFIG
variable that you may have encountered in some context. Here’s a quick guide on how to use the package configuration. All this information can also be found in the Yocto manual’s PACKAGECONFIG
variable definition.
What Is Package Configuration?
Package configuration, or PACKAGECONFIG
, allows enabling or disabling features of the build artefacts by modifying the build configuration flags. The package configuration options are first defined in the recipe file, and the desired features can then be enabled either in the recipe files or Bitbake configuration files like local.conf
or distro.conf
. Using package configuration allows building only the features that are needed, and it can also help to minimise the dependencies in the system.
How To Create a Configurable Feature?
Package configuration features can be defined in a recipe file in the following manner:
PACKAGECONFIG[feature] = "\
--config-flag-feature-enabled, \
--config-flag-feature-disabled, \
build-dependencies-for-feature, \
runtime-dependencies-for-feature, \
runtime-recommends-for-feature, \
packageconfig-conflicts-for-feature"
The last packageconfig-conflicts-for-feature
field should list out the other configurable features that conflict with the feature being defined. Any of the fields can be left empty if they are not applicable, but the commas should still be left in place to allow proper parsing.
It’s worth noting that the configuration flags apply only to recipes that inherit autotools
, cmake
, meson
, and waf
bbclasses (at least in Scarthgap). Recipes using other build systems can use the PACKAGECONFIG
feature, but they need to manually handle the configuration flags.
How to Enable a Package Configuration Feature?
There are two ways you can enable a feature: either in a recipe file or in a configuration file.
In a .bb
or .bbappend
recipe file, you can simply use the PACKAGECONFIG
variable to set the desired features. The features not present in the variable are disabled:
PACKAGECONFIG = "feature"
Appending, removal, etc. work as usual. The default value can be set with a weak assignment:
PACKAGECONFIG ??= "default-feature"
In a configuration file like local.conf
or distro.conf
, you need to add the package name override to the PACKAGECONFIG
variable, like so:
PACKAGECONFIG:pn-recipename = "feature"
Override syntax append with the package name override works as follows. Be careful not to mix up the order of the overrides:
PACKAGECONFIG:append:pn-recipename = " feature"
Demonstration
The following files demonstrate an example project that uses the CMake build system. The output binary is a program that can either print a regular hello world (the default option) or a fancy hello world, depending on the CMake configuration.
# CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(hello)
option(FANCY_HELLO "Enable fancy hello message" OFF)
add_executable(hello hello.c)
if(FANCY_HELLO)
target_compile_definitions(hello PRIVATE FANCY_HELLO)
endif()
// hello.c
#include <stdio.h>
int main() {
#ifdef FANCY_HELLO
printf("Greetings, O grand and boundless world, I emerge!\n");
#else
printf("Hello, World!\n");
#endif
return 0;
}
We can then write the following recipe that makes the fanciness of the print configurable:
# example_0.1.bb
SUMMARY = "Example of packageconfig"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
SRC_URI = "file://hello.c file://CMakeLists.txt"
inherit cmake
# We only need to define what happens when the feature is enabled
# because it is disabled by default in CMake.
PACKAGECONFIG[fancy-print] = "-DFANCY_HELLO=ON,,,,,"
PACKAGECONFIG ??= ""
do_configure:prepend() {
cp ${WORKDIR}/CMakeLists.txt ${S}
cp ${WORKDIR}/hello.c ${S}
}
do_install() {
install -d ${D}/${bindir}
install -m 755 ${B}/hello ${D}/${bindir}
}
Then, we can use either of the two methods to enable the fancy print:
# example_%.bbappend
PACKAGECONFIG = "fancy-print"
# Configuration file
PACKAGECONFIG:pn-example = "fancy-print"
