One of the key things I often stress when working with the Yocto Project is:
Never edit the recipe files of a layer you have downloaded from the Internet
(unless you are planning on pushing those changes back upstream)
If you need to add, modify or override the behaviour of a recipe you should be doing it with a .bbappend file within a layer that you maintain.
Naming Convention
The whole point of a bbappend file is to change an existing recipe – so the name of your append file must match the name of the recipe you are changing.
Recipe Names
The name of a recipe file (file ending in .bb
) is:
<PACKAGE-NAME>_<PACKAGE-VERSION>.bb
PACKAGE-NAME
This is the name of the package. This can be anything, with words separated by a dash ( -
). Do not use an underscore ( _
) as that is the separator between the Name and Version.
Within the recipe, this can be referenced by the variable PN
.
PACKAGE-VERSION (Optional).
This is whatever is after the underscore and is the version of the package. This means that it is possible to have multiple versions of a package in your layer. Unless you explicitly specify a version, BitBake will use the highest version number.
Append File Naming
The convention for naming your bbappend file is
<Recipe-to-be-changed>.bbappend
So, if you had a recipe
that you wanted to modify, you would need an append file named linux-yocto_6.6.bb
.linux-yocto_6.6.bbappend
Wildcards
BitBake recognises the character % in the filename as a wildcard and will match anything.
For example, if we had multiple recipes for a package, such as:
linux-yocto_5.4.bb
linux-yocto_6.1.bb
linux-yocto_6.6.bb
Depending on what we wanted to modify, we would have options:
linux-yocto_6.6.bbappend
would be applied after BitBake had parsedlinux-yocto_6.6.bb
and only that recipe.linux-yocto_6.%.bbappend
would match bothlinux-yocto_6.6.bb
andlinux-yocto_6.1.bb
.linux-yocto_%.bbappend
would match all versions oflinux-yocto
Multiple Append Files With The Same Name
If for some reason you have multiple append files with the same name (bizarre, but it is not unheard of), then you need to be aware of the layer priorities. The build system works from the top-down through the layers listed in BBLAYERS (namely defined in your conf/bblayers.conf
file.
To see what layers you have defined and their priority, use the command bitbake-layers show-layers
bitbake-layers show-layers
NOTE: Starting bitbake server...
layer path priority
==============================================================================
core /work/build/../layers/third-party/poky/meta 5
yocto /work/build/../layers/third-party/poky/meta-poky 5
yoctobsp /work/build/../layers/third-party/poky/meta-yocto-bsp 5
meta-my_bsp /work/build/../layers/project/meta-my_bsp 20
meta-my_distro /work/build/../layers/project/meta-my_distro 20
If you want to see all the append files in your project, use the command bitbake-layers show-appends
The Contents of a bbappend File
Now that you have an append file to change a recipe, the main things you can do are add, remove or override.
Overriding
To override a variable (as in completely change its value), just redefine it.
Say, the base recipe defines a variable FOO
FOO = "Value1"
If you wanted to change that to be My-Value
FOO = "My-Value"
The value of FOO
is now "My-Value"
Adding Values
There are two ways to add to a recipe. The first and simplest is if the thing you are adding does not already exist in the base recipe. In which case, just add it to the append file. This would typically be if you wanted to add your own tasks to a recipe – which is outside the scope of this article.
Typically however, you want to add to something that has already been defined. This could be adding a value to a variable or adding/overwriting a file (see How to Override Standard Files in a Yocto Project).
There are two options to add something to a variable in an append file.
Add to the Start
If you want your new value to appear before the existing value, use the modifier :prepend
Say, the base recipe defines a variable FOO
FOO = "Value1 Value2"
If you wanted to add a Value0
to the start of the list
FOO:prepend = "Value0"
The value of FOO
is now "Value0 Value1 Value2"
One of the most common use of this is to add a directory to BitBake’s search path
FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
This will now look for files in the SRC_URI in the local ./files
directory before anywhere else (which is how you can override files in your project – just make sure the filename exists in the files directory and it will get picked up and used before the original file of that name).
Add to the End
If you want your new value to appear after the existing value, use the modifier :append
Say, the base recipe defines a variable FOO
FOO = "Value1 Value2"
If you wanted to add a Value
3 to the end of the list
FOO:apppend = "Value3"
The value of FOO
is now "Value1
Value2
Value
3"
NOTE: The :append
and :prepend
can also be applied to tasks as well as variables.
For example, if you wanted to add some commands to you install task you could use
do_install:append() {
# Shell commands to run here
}
A typical example of this is if you wanted to add a file to your image as part of an existing recipe
FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
SRC_URI:append= "file://new-file"
do_install:append() {
install -d /usr/share
install -m 0755 ${WORKDIR}/new-file ${D}/usr/share/new-file
}
FILES:${PN} += "\
/usr/share/new-file \
"
Removing Values
To remove a value from a variable, use the modifier :remove
Say, the base recipe defines a variable FOO
FOO = "Value1 Value2 Value3"
If you wanted to remove Value
2 from the list
FOO:remove = "Value2"
The value of FOO
is now "Value1
Value
3"
An example of this is where I have a production image with a Read-Only root filesystem and I want a development version that is Read-Write
IMAGE_FEATURES:remove = "read-only-rootfs"