BitBake
The task coordinator. It reads recipes, works out dependencies, fetches sources, compiles packages and assembles the image. bitbake hello-pi builds a package; bitbake core-image-minimal builds a whole filesystem image.
SMALL BOARD. YOUR LINUX.
Prepare a Yocto recipe. Understand what it does. Then follow the path to a Linux image made for your Raspberry Pi.
MAKE SOMETHING SMALL
Choose a template, give it a name,
and inspect every generated file.
The archive preserves these paths. Individual downloads contain one file only.
S is the source directory; B is the build directory. do_compile uses Yocto's cross-compiler, not your laptop's gcc. do_install stages files under ${D}, not on your host filesystem.
For this pinned Scarthgap release, local file:// sources unpack into ${WORKDIR}; Git sources into ${WORKDIR}/git. Newer releases changed unpacking conventions. Do not blindly copy this into Styhead or later.
IMAGE_INSTALL:append = " hello-pi" adds a package to an image. The initial space matters. Downloaded files are examples licensed under this repository's MIT license unless you explicitly select CLOSED and replace them with authorized proprietary code.
THE WHOLE JOURNEY
Linux Bash commands for Raspberry Pi 4.
Take one step at a time.
Debugging a Make, Autotools or CMake package? The basics tab includes a separate Compile inside a Yocto devshell lesson for each, with copyable original-terminal and devshell commands. The same recipe-specific steps are included in project downloads as devshell-steps.txt. Finish the layer/package setup below first.
The source files at these exact revisions take precedence over generic “latest” tutorials.
conf/layer.conf, conf/machine and docsA FEW NEW WORDS
Yocto assembles your own Linux distribution.
It is not an operating system you install with apt.
The task coordinator. It reads recipes, works out dependencies, fetches sources, compiles packages and assembles the image. bitbake hello-pi builds a package; bitbake core-image-minimal builds a whole filesystem image.
A set of build instructions: where the source is, its license, how to compile it and where files belong. A recipe is not usually your application source code; it describes how to turn that code into packages.
A folder of related recipes and settings. Poky supplies the base. meta-raspberrypi supplies board support. Your meta-myboard keeps personal changes separate. bblayers.conf tells BitBake which layers to read.
The collection of packages you want on the board. An image recipe chooses the contents. A .wic file is a disk image with partitions, boot files and the root filesystem, ready to write to a card.
MACHINE chooses hardware settings, kernel and device trees from the board support package (BSP). Pi 4 uses raspberrypi4-64; Pi 5 uses raspberrypi5 here. Similar-looking names are not interchangeable.
Your x86 Linux computer builds ARM64 software using a target compiler. Yocto supplies the toolchain. An ARM binary will not normally run on your laptop; test it on the target, or use an appropriate emulator separately.
CHOOSE YOUR BUILD SYSTEM
These complete local C examples are source scaffolds for pinned Scarthgap 5.0.13, not a claim of successful BitBake or Raspberry Pi testing. Select the matching workbench template to inspect/copy its recipe and every source/build file, or download the entire layer.
Source layout: files/project/main.c and files/project/Makefile. The recipe fetches file://project/, sets S = "${WORKDIR}/project" and B = "${S}", because this small Makefile builds in its source directory. A Git project uses S = "${WORKDIR}/git" instead.
There is no configure script, so do_configure[noexec] = "1". The recipe owns do_compile (calls oe_runmake) and do_install (calls oe_runmake 'DESTDIR=${D}' install). oe_runmake is Yocto's Make wrapper: it applies EXTRA_OEMAKE and parallel-build settings and reports failures. Do not replace it with a hardcoded host compiler command.
The generated EXTRA_OEMAKE passes Yocto's CC, CFLAGS, CPPFLAGS and LDFLAGS as Make command-line variables, plus prefix and bindir. The Makefile consumes these variables and uses real tab-indented rules. DESTDIR prepends the staging directory to the final path: ${D}/usr/bin/hello-pi is packaged as /usr/bin/hello-pi. Never set prefix to ${D}/usr or run sudo make install inside a recipe.
For an existing Git project, its Makefile must honor these variables and provide an install target with DESTDIR support. Otherwise patch the Makefile or write a suitable do_install. Do not assume all Makefiles support out-of-tree builds or identical install variables.
Source layout: files/project/main.c, configure.ac and Makefile.am. configure.ac declares the project, enables Automake and finds the C compiler; Makefile.am lists the executable under bin_PROGRAMS and its source under hello_pi_SOURCES. Hyphens in the executable name become underscores in Automake variable names.
The recipe uses inherit autotools. The class owns all three tasks: do_configure runs autoreconf when needed and configure with cross-build/host settings and installation paths; do_compile calls oe_runmake; do_install calls make install with DESTDIR=${D}. The class supplies native Autoconf/Automake dependencies and normally builds out-of-tree in ${WORKDIR}/build.
Do not paste manual ./configure, host gcc, or duplicate task bodies into this recipe. Use EXTRA_OECONF for actual upstream configure options. The class generates configure/Makefile.in from the bundled inputs; you do not need to bundle generated configure scripts. Older projects requiring in-source builds may need autotools-brokensep after investigation, not as a default workaround. Cross-compile tests that try running target executables may need upstream fixes or reviewed cached test answers.
Source layout: files/project/main.c and CMakeLists.txt. The build file declares a C project, creates the executable with add_executable, includes GNUInstallDirs and installs the target using ${CMAKE_INSTALL_BINDIR}. An add_executable without an install rule would build successfully but leave nothing to package.
The recipe uses inherit cmake. The class owns do_configure, do_compile and do_install: it generates the cross-toolchain file, configures a separate ${WORKDIR}/build, builds the target (Ninja by default in this pinned class), and stages installation with DESTDIR=${D}. It supplies cmake-native and the selected backend tools.
Do not hardcode /usr/bin/gcc, an ARM compiler path, host include/library directories, or your own CMAKE_TOOLCHAIN_FILE in the example. The class sets compiler/sysroot search paths and target install directories. Use EXTRA_OECMAKE for actual upstream -D options. Do not use FetchContent to download undeclared dependencies during compilation: express sources in SRC_URI and dependencies in DEPENDS. For C++, adapt LANGUAGES, the source extension and target sources; the class also supplies the C++ cross-toolchain.
do_configure prepares build rules, do_compile produces binaries, and do_install stages the files for packaging. The last step does not install on your laptop or directly onto your Pi. Preserve class-owned tasks; use class variables first, and a small do_install:append() only when extra files truly need installing.
DEPENDS += "zlib" prepares another recipe's headers/libraries in the build sysroot. It does not link the library automatically: adapt the Makefile, configure checks or CMake target linkage. RDEPENDS:${PN} += "some-runtime-package" declares an additional runtime package (replace that example with a real package name); it does not provide build headers. Shared-library runtime dependencies are often detected automatically, but helper executables, scripts and data may require explicit runtime dependencies. The generated project recipes use += so class tool dependencies are preserved.
For all six templates, build your package, add it through IMAGE_INSTALL or the custom image recipe, rebuild and flash the image. Local project templates name the executable after your package. Git templates cannot know upstream output names or install paths: check the install rules, package FILES and image manifest. Consult task logs and bitbake -e hello-pi; never disable packaging QA merely to hide missing files.
Scarthgap recipe-writing guide · Autotools class · CMake class
DEBUG THE BUILD, NOT YOUR HOST
For the pinned Scarthgap release. These are documented debugging workflows, not an executed Yocto devshell test. Each example uses recipe hello-pi; replace it with your recipe, or download the project template's devshell-steps.txt with your chosen name. Run blocks one at a time, in the indicated terminal, and stop at the first failure.
Use a supported Linux build host and an interactive terminal. First initialize the existing build directory with oe-init-build-env; the layer must already be enabled. bitbake hello-pi -c devshell opens a new terminal, normally in the source directory S. It is not necessarily the build directory B. In the pinned source, devshell depends on patch and prepare_recipe_sysroot, not on successful configure/compile/install. Prepare those tasks explicitly as shown below.
OE_TERMINAL selects a supported terminal backend. On a headless host, install/configure a supported terminal such as tmux and use an interactive login; a desktop terminal also needs a working display/session. If no usable terminal is found, fix the host terminal setup rather than using OE_TERMINAL = "none" and expecting a shell. Noninteractive CI should run BitBake tasks directly.
Before entering, inspect bitbake -e in the original initialized terminal. It prints the expanded S, B, D, T and toolchain values. Copy the absolute T path, which points to this recipe's task scripts/logs. Do not source or eval the complete bitbake -e output. Inside devshell, use pwd and the exported CC to check context; S/B/D/T are BitBake metadata and may not be shell environment variables. Do not paste cd ${B} or guess ../temp.
Task scripts live in the recorded T directory. Unnumbered run.do_compile and similar names link to the latest generated scripts; PID-suffixed copies may be old. Read them first, then execute, do not source, the current configure/compile scripts to reproduce BitBake's captured flags, toolchain and working directory. oe_runmake is provided inside task scripts, not guaranteed as an interactive shell function.
If sstate or stamps skipped a task and its run script is missing, exit devshell and run bitbake hello-pi -c configure -f (Autotools/CMake) or bitbake hello-pi -c compile -f as appropriate, then reopen. If configure fails, debug its script/log before continuing. Plain Make's noexec configure task intentionally has no configure script. Check the exact T directory after changing recipe versions, MACHINE or build directory.
For missing cmake, autoreconf or compiler tools, check the inherited class, recipe DEPENDS, prepare_recipe_sysroot and task logs. The classes supply native tools and target sysroots. Installing an unrelated host tool or calling host gcc does not reproduce the recipe's cross-build. ARM output is for the Pi; do not expect to run it on your x86 host.
Stage-install through BitBake: the preparation block runs install outside devshell to create run.do_install and stage into D. Read that script to see the exact install command, but do not replay it in an ordinary devshell: install tasks require BitBake's pseudo/fakeroot context for ownership tracking. D is a temporary packaging root, not your host's /usr and not a deployment to the Pi. Never sudo make install.
Manual script replay does not update BitBake's task stamps or package/image outputs. Workdir edits are temporary debugging experiments. Save local source/build-file changes under the layer's files/project, save patches in the recipe, or commit Git changes and update SRCREV. Review license checksums if license text changed. Close devshell before rebuilding to avoid concurrent workdir changes. The final -C configure (or -C compile for Make) invalidates that task and lets BitBake rebuild the recipe's downstream tasks; then build your selected image and verify its manifest before flashing.
Official Scarthgap devshell guide · Pinned devshell prerequisites and start directory