Skip to main content

Customization

Create a layer​

In Yocto a layer can be seen as a collection of related recipes (instructions) that tell the build system what to do. As an example, Embedded Artists created the layer meta-ea to contain all recipes needed to build an image for one of our COM boards.

For these instructions you should first have built an image as described in Build Images chapter. We are using the name meta-example in these examples. Change this to the name you want to use for your layer.

Create the layer​

The instruction is run from the build directory and the layer will be created in the sources directory.

bitbake-layers create-layer ../sources/meta-example

The meta-example layer will be created with a number of files including an example recipe. The directory structure will look like below.

meta-example
| -- conf
| | -- layer.conf
| -- COPYING.MIT
| -- README
| -- recipes-example
| | -- example
| | | -- example_0.1.bb

Add the layer​

The previous instruction only created the layer, but you also need to add it to the build. You can do this by either manually editing <build-dir>/conf/bblayers.bb or running the command below.

bitbake-layers add-layer ../sources/meta-example

The disadvantage of running bitbake-layers is that it will add the layer with an absolute path and not a relative path as the other layers in bblayers.conf. Below is an example of bblayers.conf were meta-example has been added using bitbake-layers.

...
BBLAYERS += " ${BSPDIR}/sources/meta-qt5 "
#Embedded Artists Yocto layer
BBLAYERS += " ${BSPDIR}/sources/meta-ea "
BBLAYERS += " ${BSPDIR}/sources/meta-murata-wireless "
BBLAYERS += "/home/user/builds/build-dir/sources/meta-example"

Version control​

It is recommended that you add your new layer to a version-controlled repository such as GitHub. It is out of the scope of this document to describe how you do this, but there are many guides online such as the link below that describes how to create a new repository on GitHub.

https://docs.github.com/en/get-started/quickstart/create-a-repo

By adding the layer to a repository, you can also add it to a repo manifest that will keep track of all repositories needed to do a full Yocto image. Embedded Artists has created the repository ea-yocto-base that contains a repo manifest. See an example by following the link below.

https://github.com/embeddedartists/ea-yocto-base/blob/ea-5.10.72/default.xml#L47

Create a recipe​

It is the recipe that contains the settings and tasks needed to build a package. The recipe contains the information about where the source code can be found, which version to use and if any patches should be applied. It can also specify dependencies to other recipes.

When a new layer was created in the Create a layer section an example recipe was also created. This example only contains one .bb file which will print a message during the build.

example_0.1.bb

SUMMARY = "bitbake-layers recipe"
DESCRIPTION = "Recipe created by bitbake-layers"
LICENSE = "MIT"
python do_build() {
bb.plain("***********************************************");
bb.plain("* *");
bb.plain("* Example recipe created by bitbake-layers *");
bb.plain("* *");
bb.plain("***********************************************");
}

A better example is to create a recipe that will build and install a hello world application. The instructions below are based on the example described in Yocto’s official documentation.

https://www.yoctoproject.org/docs/2.5.3/mega-manual/mega-manual.html#new-recipe-single-c-file-package-hello-world

Create recipe directory​

Within the meta-example layer create the directories needed for the new recipe. The first directory, recipes-example, is a container directory where you can put several recipes (using the same directory as was created when creating the layer). The directory hello-world is the actual recipe directory for this example. The sub-directory files will contain the source code, helloworld.c in this example.

cd ../sources/meta-example
mkdir -p recipes-example/hello-world/files

Create recipe file​

Create a file called hello-world.bb within the hello-world directory. The content of the file should be as shown below.

SUMMARY = "Simple helloworld application"
SECTION = "examples"
LICENSE = "MIT"
LIC_FILES_CHKSUM =
"file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"

SRC_URI = "file://helloworld.c"
S = "${WORKDIR}"

do_compile() {
${CC} helloworld.c -o helloworld
}

do_install() {
install -d ${D}${bindir}
install -m 0755 helloworld ${D}${bindir}
}

INSANE_SKIP_${PN} = "ldflags"

The recipe file begins with short description of the recipe and also specifies which license that will apply.

The file continues with specifying the path to the source code (SRC_URI). It only lists the name of the file, but Yocto will know to look for this file in the sub-directory files.

Then comes the compile and install steps. In do_compile the file will be compiled into an executable program and in do_install the program will be installed into the file system at the location defined by ${bindir} (typically /usr/bin).

The last line (INSANE_SKIP_${PN}) was added to skip ldflags. Without this line, QA errors were generated (like below).

ERROR: hello-world-1.0-r0 do_package_qa: QA Issue: No GNU_HASH in the elf binary:

Create helloworld.c​

Within hello-world/files create the file helloworld.c and add the content below to that file.

#include <stdio.h>

int main() {
printf("Hello world\n");
return 0;
}

Build the recipe​

You can now try to build the recipe by running the command below from your build directory

cd ../../<build-dir>
bitbake hello-world

To make sure the hello world application is included in the image you are building add the following to conf/local.conf.

IMAGE_INSTALL_append = " hello-world"

Then build the image (in this example we are using ea-image-base, but you can change to the image you are using).

bitbake ea-image-base

Add content or change behavior of existing recipe​

It is possible to modify an existing recipe by using a bbappend file. This avoids duplication of functionality and allows for modifying a recipe from another layer. One common usage of bbappend files is to apply patches to existing recipes without having to modify the original source.

In the example below we will modify the content of the file asound.conf being installed by the recipe alsa-state.

A file called alsa-state.bbappend is created in a recipes-bsp/alsa-state. We are keeping the same directory structure as for the original file which is located in the poky/meta layer. Below you can see the content of this file.

# Change the default configuration from 44100Hz to 48000Hz for iMX6 UltraLite

do_install_append_mx6ul () {
if [ -e ${D}/${sysconfdir}/asound.conf ]; then
sed -e "s:playback\.pcm.*:playback.pcm \"dmix_48000\":g" \
-e "s:capture\.pcm.*:capture.pcm \"dsnoop_48000\":g" \
-i ${D}/${sysconfdir}/asound.conf
fi
}

What this file do is to append to the do_install task. When this task is run it will look for the asound.conf file and modify it to use 48000 Hz instead of 44100 Hz using the sed command. Please note that this change will only be applied for the mx6ul target (i.e., iMX6 UltraLite). The reason to limit the change to the iMX6 UltraLite is because for this target it wasn’t possible to generate a 44100 Hz clock given the way the audio related clocks are setup for the processor.

The original file can be found on GitHub.

https://github.com/embeddedartists/meta-ea/blob/ea-4.14.98/recipes-bsp/alsa-state/alsastate.bbappend

More information in the Yocto documentation:

https://www.yoctoproject.org/docs/2.5.3/mega-manual/mega-manual.html#using-bbappend-files