Lesson
Changing Yocto Recipes
How to change an existing recipe
Sooner or later you will find a recipe that is almost what you need.
Maybe a vendor recipe builds the right application, but you need to add a patch. Maybe an upstream recipe installs a default configuration file, but your product needs a different one. Maybe the recipe needs an extra dependency for your board or image.
The tempting thing is to open the original .bb file and edit it directly.
Editing an upstream or vendor recipe directly makes upgrades painful. Your change is mixed into someone else’s layer, so it is easy to lose when the layer is updated. It also makes it harder to see which parts of the build are project customisation and which parts came from upstream.
The recommended Yocto pattern is:
- leave the original
.bbrecipe alone - create a
.bbappendfile in your own layer - put your extra files, patches, and metadata into that append
That keeps your project changes visible, reviewable, and easier to carry forward.
What a .bbappend File Does
A .bbappend file is BitBake metadata that is added to an existing recipe.
It does not build a separate recipe. It extends a .bb recipe that BitBake has
already found.
For example, if another layer provides:
example_1.2.bb
then your layer can provide:
example_1.2.bbappend
When BitBake parses example_1.2.bb, it also applies matching append files. The
final recipe is the combination of the original recipe plus the changes from the
append.
The filename is important. BitBake matches the append to the recipe by recipe name and version.
Exact version match:
example_1.2.bbappend -> example_1.2.bb
Wildcard version match:
example_1.%.bbappend -> example_1.2.bb, example_1.3.bb, etc
example_%.bbappend -> example_1.2.bb, example_2.3.bb, etc
Use an exact version when the change is known to only work with that recipe
version. Use % when the change should apply across recipe version updates.
Where Appends Live
Put .bbappend files in your own layer, using the same broad recipe category as
the recipe you are extending.
Given that you will normally be changing existing packages, then they would tend to live in the BSP layer if they are to do with board bring-up (TF-A, U-Boot, kernel, etc) or the Distro layer for most other recipes.
The path normally mirrors the original recipe structure:
upstream layer:
meta-vendor/recipes-apps/example/example_1.2.bb
your layer:
meta-my-software/recipes-apps/example/example_1.2.bbappend
This mirroring is not for BitBake. It also helps humans. When someone looks at your layer, they can quickly see which upstream recipe your append modifies.
The layer’s conf/layer.conf must include .bbappend files in BBFILES. The
layers created earlier use the standard pattern:
BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \
${LAYERDIR}/recipes-*/*/*.bbappend"
That means this path is found:
meta-my-software/recipes-apps/example/example_%.bbappend
The layer must also be enabled in conf/bblayers.conf. If the layer is not in
BBLAYERS, BitBake will ignore the layer and not see the append at all.
Checking That BitBake Found the Append
Before debugging the contents of a .bbappend, first check that BitBake can see
it.
Show enabled layers:
bitbake-layers show-layers
Show recipes and the layer that provides them:
bitbake-layers show-recipes example
Show all append files that BitBake has discovered:
bitbake-layers show-appends
For a specific recipe, it is often easier to use:
bitbake-layers show-appends example
You should expect to see your .bbappend path listed against the recipe it is
modifying. If it is not listed, BitBake is not applying it.
You can also inspect the final value of a variable after all recipe and append metadata has been processed:
bitbake-getvar -r example SRC_URI
bitbake-getvar -r example DEPENDS
This is useful because it shows both the final value and where the value was set or changed.
Common Things to Change
Most .bbappend files are small. They usually adjust variables, add files,
apply patches, or extend an existing task.
Adding or Overriding Variables
You can set a variable if your project needs a different value:
SUMMARY = "Example application with project customisations"
Only do this when you really want to replace the value. For list-style variables, you normally extend the existing value instead.
Using :append, :prepend, and :remove
Use :append to add to the final value:
PACKAGECONFIG:append = " ssl"
Remember that :append does not add a space for you. For space-separated lists,
include the leading space:
RDEPENDS:${PN}:append = " bash"
${PN} means the main package name for this recipe. If the recipe is
example_1.2.bb, then ${PN} is normally example.
Use :prepend when the new value must come first:
EXTRA_OECONF:prepend = "--enable-project-mode "
Use :remove to remove an item that came from the original recipe or another
layer:
PACKAGECONFIG:remove = "x11"
Adding and Removing Dependencies
DEPENDS is for build-time recipe dependencies. Use it when the recipe needs
headers, libraries, or tools while building:
DEPENDS:append = " openssl"
DEPENDS:remove = "libx11"
RDEPENDS:${PN} is for runtime package dependencies. Use it when the installed
package needs another package on the target:
RDEPENDS:${PN}:append = " bash"
RDEPENDS:${PN}:remove = "busybox-syslog"
Extending SRC_URI
SRC_URI lists the inputs for the recipe. A .bbappend can add more inputs,
such as patches or local files:
SRC_URI:append = " \
file://0001-change-default-message.patch \
file://example.conf \
"
Files listed with file:// must be somewhere BitBake knows to search. In a
normal recipe, BitBake automatically searches the recipe’s own files/
directory. In a .bbappend, the extra files are in your layer, so you normally
extend the search path too.
Using FILESEXTRAPATHS
This is the common pattern:
FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
or
FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}$:"
${THISDIR} is the directory containing the file currently being parsed. In this
case, it is the directory containing your .bbappend.
${PN} is the package name which allow for the common usa case of having the files
located in a directory with the same name as the recipe. This is especially useful when you have multiple
recipes in the same directory and you want to separate out the additional files.
If your append is:
meta-my-software/recipes-apps/example/example_%.bbappend
then:
${THISDIR}/files
points to:
meta-my-software/recipes-apps/example/files
and
${THISDIR}/${PN}
points to:
meta-my-software/recipes-apps/example/example
Extending an Existing Task
You can add commands to an existing task without replacing the whole task.
For example, to install an extra configuration file:
do_install:append() {
install -d ${D}${sysconfdir}/example
install -m 0644 ${UNPACKDIR}/example.conf ${D}${sysconfdir}/example/example.conf
}
This runs after the original recipe’s do_install() task.
${UNPACKDIR} is the recipe’s unpack area. Local files from SRC_URI, such as
file://example.conf, are available there after fetch and unpack have completed.
Complete Worked Example
In this example, an upstream layer already provides an application recipe:
meta-vendor/recipes-apps/hello-recipe/hello-recipe_1.0.bb
We want to keep the vendor recipe unchanged, but add a project configuration file from our own layer.
Create this layout in meta-my-distro:
Create the directory:
mkdir -p meta-my-distro/recipes-apps/hello-recipe/hello-recipe
Create hello-recipe/hello-recipe.conf:
message=Hello from the project layer
Create hello-recipe_%.bbappend:
FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
SRC_URI:append = " file://hello-recipe.conf"
do_install:append() {
install -d ${D}${sysconfdir}/hello-recipe
install -m 0644 ${UNPACKDIR}/hello-recipe.conf ${D}${sysconfdir}/hello-recipe/hello-recipe.conf
}
What this does:
FILESEXTRAPATHStells BitBake to also search your append’shello-recipe/directorySRC_URI:appendadds the local configuration file to the recipe inputsdo_install:append()installs the file after the original recipe has installed its own files
Now check that the append is active:
bitbake-layers show-layers
bitbake-layers show-appends hello-recipe
You should see meta-my-software in the layer list, and you should see
hello-recipe_%.bbappend listed as an append for hello-recipe.
Build the recipe:
bitbake hello-recipe
If you want to inspect just the install stage while debugging:
bitbake -c install hello-recipe
The staged file should appear under the recipe work directory, usually in a path like:
tmp/work/<machine>/hello-recipe/1.0/image/etc/hello-recipe/hello-recipe.conf
After the package is included in an image and the image is rebuilt, the file should appear on the target as:
/etc/hello-recipe/hello-recipe.conf
Complete Patch Example
Bitbake recognises any file ending in .patch as a patch file and will automatically
try and apply that to the source.
Patch files work the same way as other local files - put them in a subdirectory, add that
directory to FILESEXTRAPATHS, and list the patch in SRC_URI.
Layout:
meta-my-distro/
recipes-apps/
hello-recipe/
hello-recipe_%.bbappend
hello-recipe/
0001-print-project-message.patch
Append:
FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}$:"
SRC_URI:append = " file://0001-print-project-message.patch"
Patch:
From: Example Developer <developer@example.com>
Date: Thu, 13 Aug 2026 10:00:00 +0000
Subject: [PATCH] Print project message
---
hello-recipe.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hello-recipe.c b/hello-recipe.c
index 1111111..2222222 100644
--- a/hello-recipe.c
+++ b/hello-recipe.c
@@ -1,6 +1,6 @@
#include <stdio.h>
int main(void)
{
- puts("hello from upstream");
+ puts("hello from the project layer");
return 0;
}
When you build the recipe, BitBake applies patches listed in SRC_URI during
do_patch, before configure and compile tasks run.
If the patch fails, run:
bitbake -c patch hello-recipe
Then inspect the patch log under the recipe work directory:
tmp/work/<machine>/hello-recipe/1.0/temp/log.do_patch
Common Mistakes
The .bbappend Filename Does Not Match
If the recipe is:
hello-recipe_1.0.bb
then these match:
hello-recipe_1.0.bbappend
hello-recipe_%.bbappend
This does not match:
hello_recipe_1.0.bbappend
BitBake is strict about recipe names. A small filename difference means the append is ignored or BitBake reports that no matching recipe exists.
The Layer Is Not Enabled
Your append can be perfectly written and still do nothing if the layer is not in
conf/bblayers.conf.
Check:
bitbake-layers show-layers
Add the layer if it is missing:
bitbake-layers add-layer ../meta-my-software
FILESEXTRAPATHS Points to the Wrong Place
This is the usual form:
FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
Common problems include:
- forgetting the trailing
: - using
=instead of:=when${THISDIR}is involved - putting the file in a different directory from the one you added to the search path
The File or Patch Is Not in SRC_URI
Putting a file in files/ is not enough. BitBake also needs to know that the
recipe uses it.
This file:
files/hello-recipe.conf
also needs:
SRC_URI:append = " file://hello-recipe.conf"
The same applies to patches:
SRC_URI:append = " file://0001-print-project-message.patch"
Editing the Original Recipe Instead
Editing the upstream .bb recipe may look faster at the start, but it creates a
maintenance problem. The next time you update the vendor or community layer, you
have to rediscover and reapply your local changes.
Keep product changes in your own layer. Use .bbappend files when the recipe
already exists and you only need to adjust it. Write a new .bb recipe when you
are adding a new software component.
Summary
A .bbappend is the normal way to modify an existing recipe from your own layer.
The important habits are:
- do not edit upstream or vendor recipes directly
- match the
.bbappendfilename to the recipe name and version - keep appends and local files in your own layer
- use
FILESEXTRAPATHS:prepend := "${THISDIR}/files:"when adding files beside an append - list every local file and patch in
SRC_URI - use
:append,:prepend, and:removeto adjust existing metadata - use
bitbake-layers show-appendsandbitbake-getvar -rto check what BitBake actually sees