32blogby StudioMitsu
yocto7 min read

How to Write Yocto Recipes: A .bb File Guide

Write Yocto recipes from scratch. Covers Hello World, GitHub source fetching, CMake and Autotools with inherit classes.

yoctoembedded-linuxrecipesscarthgap
On this page

You want to bundle your own application into a Yocto Linux image. You need to build a GitHub project with Yocto. But how do you write a .bb file?

This guide walks you through creating Yocto recipes from the ground up, with working code examples at every step. Once you understand how recipes work, you can package virtually any software into a Yocto image.

What Is a Yocto Recipe?

A recipe is a .bb file that describes how to build and install a specific piece of software. Think of it as a self-contained build script that answers four questions:

  • Where to get the source code (SRC_URI)
  • How to build it (do_compile)
  • Where to install it (do_install)
  • What license it uses (LICENSE)

Recipe File Naming

Recipe filenames follow the pattern packagename_version.bb:

text
hello-world_1.0.bb      # hello-world version 1.0
myapp_2.3.1.bb          # myapp version 2.3.1
busybox_1.36.1.bb       # busybox version 1.36.1

BitBake automatically extracts the package name (PN) and version (PV) from the filename.

Basic Recipe Structure

text
# hello-world_1.0.bb

# ===== Metadata =====
SUMMARY = "Hello World sample"
DESCRIPTION = "A minimal example recipe for learning Yocto"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"

# ===== Source acquisition =====
SRC_URI = "file://hello.c"

# ===== Source directory =====
S = "${WORKDIR}"

# ===== Build =====
do_compile() {
    ${CC} ${CFLAGS} ${LDFLAGS} -o hello hello.c
}

# ===== Install =====
do_install() {
    install -d ${D}${bindir}
    install -m 0755 hello ${D}${bindir}
}

Key Variables

Package Metadata

VariableDescriptionExample
SUMMARYShort one-line description"Hello World sample"
DESCRIPTIONDetailed description"A minimal learning example..."
LICENSELicense identifier (SPDX)"MIT", "GPL-2.0-only", "Apache-2.0"
LIC_FILES_CHKSUMLicense file checksumfile://LICENSE;md5=xxx
SRC_URIWhere to get the source"file://", "git://", "https://"
SWhere source is unpacked$/git

Build and Install Variables

VariableDescriptionExpands to
${WORKDIR}Working directory for this build/tmp/work/.../hello-world/1.0-r0/
${D}Staging root for installation.../image/
${bindir}/usr/bin path/usr/bin
${libdir}/usr/lib path/usr/lib
${sysconfdir}/etc path/etc
${CC}Cross-compilerarm-poky-linux-gnueabi-gcc

Building a Hello World Recipe

Let's build the simplest possible recipe and confirm it works end-to-end.

Create a Custom Layer

Always put your recipes in your own layer — never in Poky's layers directly.

bash
cd ~/yocto/poky
source oe-init-build-env build

# Create a new layer
cd ..
bitbake-layers create-layer meta-mylayer

# Add it to the build
cd build
bitbake-layers add-layer ../meta-mylayer

See the layer creation guide for details on layer management.

Create the Directory Structure and Source

bash
mkdir -p ../meta-mylayer/recipes-example/hello-world/files

Write files/hello.c:

c
// files/hello.c
#include <stdio.h>

int main(void) {
    printf("Hello from Yocto!\n");
    printf("This app was built with a custom recipe.\n");
    return 0;
}

Write the Recipe

Create hello-world_1.0.bb:

text
# hello-world_1.0.bb
SUMMARY = "Hello World - Yocto recipe learning example"
DESCRIPTION = "A minimal application demonstrating how to write a custom Yocto recipe"

LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"

SRC_URI = "file://hello.c"

S = "${WORKDIR}"

do_compile() {
    ${CC} ${CFLAGS} ${LDFLAGS} -o hello hello.c
}

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

Build and Include in Your Image

bash
# Build the recipe individually
bitbake hello-world

# Success looks like:
NOTE: Tasks Summary: Attempted 123 tasks of which 120 didn't need to be rerun

Add to conf/local.conf to include it in the image:

text
IMAGE_INSTALL:append = " hello-world"

Rebuild and test in QEMU:

bash
bitbake core-image-minimal
runqemu qemux86-64 nographic

# After boot:
root@qemux86-64:~# hello
Hello from Yocto!
This app was built with a custom recipe.

Fetching Source from GitHub

In real projects, you'll usually fetch source from an external repository rather than shipping it locally.

Example: Adding nlohmann/json

text
# nlohmann-json_3.11.3.bb
SUMMARY = "JSON for Modern C++"
DESCRIPTION = "A header-only JSON library for C++"
HOMEPAGE = "https://github.com/nlohmann/json"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://LICENSE.MIT;md5=f5f7c71504da070bcf4f090205ce1080"

# Fetch from GitHub using HTTPS
SRC_URI = "git://github.com/nlohmann/json.git;protocol=https;branch=master"

# Pin to a specific commit — always do this for reproducibility
SRCREV = "9cca280a4d0ccf0c08f47a99aa71d1b0e52f8d03"

S = "${WORKDIR}/git"

inherit cmake

EXTRA_OECMAKE = "-DJSON_BuildTests=OFF"

SRC_URI Patterns

Source typeSRC_URI format
Local filefile://hello.c
Git (HTTPS)git://github.com/user/repo.git;protocol=https;branch=main
Git (SSH)git://git@github.com/user/repo.git;protocol=ssh;branch=main
HTTP/HTTPS tarballhttps://example.com/file.tar.gz
Patch filefile://fix-build.patch

Using Inherit Classes

Yocto ships with classes that encapsulate common build patterns. Using inherit saves you from writing boilerplate do_compile and do_install tasks.

ClassUse CaseWhat It Automates
cmakeCMake projectscmake → make → make install
autotoolsAutoconf projectsconfigure → make → make install
mesonMeson projectsmeson → ninja → install
setuptools3Python packagessetuptools / wheel install
systemdsystemd servicesService enablement

CMake Project Example

text
# myapp-cmake_1.0.bb
SUMMARY = "My CMake App"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"

SRC_URI = "git://github.com/user/myapp.git;protocol=https;branch=main"
SRCREV = "abc123def456..."
S = "${WORKDIR}/git"

inherit cmake

EXTRA_OECMAKE = "-DBUILD_TESTS=OFF -DCMAKE_BUILD_TYPE=Release"

Autotools Project Example

text
# myapp-autotools_1.0.bb
SUMMARY = "My Autotools App"
LICENSE = "GPL-2.0-only"
LIC_FILES_CHKSUM = "file://COPYING;md5=..."

SRC_URI = "https://example.com/myapp-1.0.tar.gz"
SRC_URI[sha256sum] = "def456..."

inherit autotools

EXTRA_OECONF = "--disable-docs"

systemd Services

To automatically start your application at boot, use inherit systemd. For detailed configuration, see the systemd service guide.

Common Errors and Fixes

LIC_FILES_CHKSUM mismatch

text
ERROR: License checksum mismatch...

Cause: The MD5 hash in your recipe doesn't match the actual license file.

Fix: Recalculate the correct hash:

bash
md5sum LICENSE

do_fetch failed

text
ERROR: Fetcher failure: Unable to find file...

Cause: Wrong path in SRC_URI, or network issue when fetching from Git.

Fix: Double-check your SRC_URI and SRCREV. Make sure the commit hash exists in the repository.

Nothing PROVIDES 'hello-world'

text
ERROR: Nothing PROVIDES 'hello-world'

Cause: The layer containing your recipe isn't in bblayers.conf.

Fix: Add the layer:

bash
bitbake-layers add-layer ../meta-mylayer

SRC_URI checksum mismatch

text
ERROR: SRC_URI checksum mismatch...

Cause: Checksum for an HTTP/HTTPS download isn't set or doesn't match.

Fix: Calculate the correct checksum:

bash
sha256sum downloaded-file.tar.gz

Wrapping Up

Here's what to remember about writing Yocto recipes:

  • Recipes are .bb files that describe a complete build process
  • Core variables: SRC_URI, do_compile, do_install
  • Always put your recipes in a custom layer, not in Poky
  • Use inherit to automatically handle CMake/Autotools/Meson projects
  • Add packages to an image with IMAGE_INSTALL:append
  • Always pin SRCREV to a specific commit hash for reproducibility

Once you're comfortable writing recipes, you can package anything into a Yocto image. Here's where to go next:

To go deeper into embedded Linux, these books are excellent references.

PRMastering Embedded Linux Development 4th Ed (2024)View on Amazon
PREmbedded Linux Development Using Yocto Project 3rd Ed (2023)View on Amazon