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.
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