Lesson
Setting up the System
Setting up the system to build the first image
A Yocto project is notoriously hungry. The more resources you can give it, the easier life will be.
While it is possible to build a project with WSL2 on Windows, having a Linux host reduces the friction. All the examples here are based on Debian.
Build Host
- A system with at least 100 GB of free disk space
- Fast I/O, because it noticeably improves build performance
- At least 16 GB of RAM
- More RAM and more CPU cores if you want faster builds
- A supported recent Linux distribution such as Debian, Ubuntu, openSUSE, Red Hat, or Fedora
- Core build tools including Git 1.8.3.1+, tar 1.28+, Python 3.8+, gcc 8+, and GNU make 4.0+
Build Tools
These are the packages you should install on your build host:
sudo apt install bc gawk wget git diffstat unzip texinfo gcc \
build-essential chrpath socat cpio python3 python3-pip \
python3-pexpect xz-utils debianutils iputils-ping \
python3-git python3-jinja2 libegl1-mesa libsdl1.2-dev \
python3-subunit mesa-common-dev zstd liblz4-tool file \
locales libacl1 libncurses-dev libssl-dev
sudo locale-gen en_US.UTF-8
Setting up the Project
The structure you set up now affects the whole experience of working with the Yocto Project.
Create a Shared Directory
A Yocto project caches a lot of data so that later builds can reuse it.
- Downloaded source files
- Build state and artifacts
Downloads
Yocto builds components from source, so it caches downloaded files to save time and bandwidth the next time they are needed.
Shared State Cache
There are many steps in a full build, for example:
- Download the source
- Configure
- Compile
- Install
The result of each of these steps is saved in the shared state cache, or
sstate, so it can be reused where appropriate.
Reuse
It makes good sense to share these caches between projects. If project A has
already downloaded busybox, for example, then project B should be able to
reuse that download instead of fetching it again.
The same idea applies to the state cache. If several projects share the same board family or common packages, they can often reuse build steps and reduce build time significantly.
As a result, it is usually best to keep the cache outside the main project directory so it can be shared by multiple projects.
mkdir -p ~/yocto/shared
Create the Project Directory
Your Yocto project will become a complete working environment, so it is a bad idea to keep it directly in your home directory. A separate working directory keeps things much easier to manage.
A simple pattern is:
~/wip/<project_name>
Initialise the Project
mkdir -p ~/wip/my_project
cd ~/wip/my_project
git init
Create the directories to hold your layers
mkdir -p layers/project
mkdir layers/third-party
Understanding Layers
A layer is just a collection of Yocto metadata grouped together for convenience.
That metadata may include:
- recipes
- append files
- machine configuration
- distro configuration
- classes
- configuration fragments
- patches
- image recipes
Each layer gives BitBake another set of files to search when resolving how the system should be built.
Why Layers Matter
Layers help you keep different responsibilities separate.
A healthy Yocto project usually separates:
- upstream vendor or community layers
- your own board or BSP layer
- your own distro or policy layer
- your own application or product layer
This makes it easier to answer questions like:
- is this change ours or upstream?
- what can be upgraded safely?
- where should a new recipe live?
- where should a project-specific patch be stored?
Typical Layer Structure
A project often ends up looking something like this:
You do not have to use exactly these names, but the separation is useful.
Common Project Layers
meta-my-bsp usually contains machine configuration, kernel changes, bootloader
settings, and board-specific patches.
meta-my-distro usually contains distribution policy, image defaults, overrides
to standard packages, and system-wide behaviour.
meta-my-software usually contains recipes for your own applications and software
components.
That keeps hardware concerns, policy concerns, and application concerns from being mixed together.
Clone the Initial Layers
BitBake - The Build Tool
git clone https://git.openembedded.org/bitbake layers/third-party/bitbake
OpenEmbedded Core
git clone -b scarthgap git://git.openembedded.org/openembedded-core \
layers/third-party/meta-openembedded-core
Create a Start Script
Rather than typing long initialisation commands every time, create a small start script for the project.
In ~/wip/my_project (where you should be if you are following the instructions), create a script start-yocto.sh
#!/bin/bash --init-file
# Ensure the shared directories exist for caching
mkdir -p ~/yocto/shared > /dev/null 2>&1
source ./layers/third-party/meta-openembedded-core/oe-init-build-env \
./build
Make sure it is executable.
Run this script each time you want to build anything. It initialises the environment correctly and drops you into the right build directory.
Run the script now and you will be able to start your first build.
Checkpoint - Files and Directories
bblayers.conf
BitBake only knows about layers that are listed in bblayers.conf.
For example:
BBLAYERS ?= " \
${YOCTOROOT}/third-party/meta-openembedded-core/meta \
${YOCTOROOT}/third-party/meta-some-vendor \
${YOCTOROOT}/project/meta-my-bsp \
${YOCTOROOT}/project/meta-my-distro \
${YOCTOROOT}/project/meta-my-software \
"
If a layer is not listed there, its metadata will not be available to the build.
layer.conf
Every layer contains a conf/layer.conf file.
That file tells BitBake things such as:
- where to find recipes
- where to find
.bbappendfiles - which collection name the layer uses
- compatibility with Yocto releases
You do not need to memorise all of layer.conf immediately, but you should know
that it is what makes the directory behave as a proper BitBake layer.
Layer Priority
When multiple layers affect the same metadata, BitBake needs rules to decide how things combine.
Layer priority helps determine which layer wins in certain cases, especially when similarly named metadata exists in more than one place.
You do not need to rely on priority for everyday work, but you should know that it exists and that overlapping metadata between layers can create confusing results.
In practice, good structure is more important than clever priority tricks.
Configure Your Build
To make use of the shared cache, modify your local configuration file,
build/conf/local.conf. This file defines local configuration parameters for
the build.
The defaults are commented out, so you can add your own values below them.
Find the section for DL_DIR and change it to use your shared directory.
#DL_DIR ?= "${TOPDIR}/downloads"
DL_DIR = "${HOME}/yocto/shared/downloads"
Do the same for SSTATE_DIR:
#SSTATE_DIR ?= "${TOPDIR}/sstate-cache"
SSTATE_DIR = "${HOME}/yocto/shared/sstate-cache/${MACHINE}"
Then, to keep the first build simple, allow root login:
# INSECURE - DO NOT USE FOR PRODUCTION
EXTRA_IMAGE_FEATURES ?= "allow-empty-password \
empty-root-password allow-root-login"
Build Your First Image
Create a minimal image with:
bitbake core-image-minimal
Test the Image
At this point, you have built an image for a QEMU x86-64 target. You can run it with:
runqemu qemux86-64
Login as root with no password.
If you want to learn more about running QEMU, see the Using the Quick EMUlator (QEMU) chapter in the Yocto Project Development Tasks Manual.
Exit QEMU either by clicking the shutdown icon or by typing Ctrl-C in the
terminal where you launched QEMU.
Summary
Setting up the project correctly at the beginning makes the rest of the Yocto workflow much easier.
The key concepts from this lesson are:
- make sure the build host has enough storage, RAM, and the required tools
- create shared download and sstate cache directories
- keep the working project in its own clean directory structure
- clone the core layers needed to start the build
- separate third-party, BSP, distro, and application metadata into appropriate layers
- use
bblayers.confto control which layers are active - create a startup script so the environment is always initialised consistently
- update
local.confso the build uses your shared caches - build and test a first image in QEMU
Check your understanding
Quick quiz: setup
A short review before moving on from the initial build environment.