Yocto 03: How to Handle Multiple Yocto Meta Layers with repo
Yocto has layers, like Ogres and onions. Each layer brings a new set of tools, functions or configuration to the table. A custom image usually means putting together a whole stack of them, five, ten, or even more layers. Keeping all of them in sync? That’s where things can get messy, unless the right tools are used.
Keep the layers in sync, but why?#
The meta-layers of Yocto are complex constructs - each one has multiple branches, typically one per Yocto release, and each branch comes with a shitload of commits. In practice, only the LTS (long term support) and actively maintained branches receive ongoing updates. At the moment, the LTS Yocto releases are Kirkstone (until Apr. 2026) and Scarthgap (util April 2026).
When assembling a custom distribution, it’s essential to treat the layer setup as a consistent snapshot in time, all layers should be pinned to compatible commits from the same release branch and roughly the same point in time.
Introducing: repo#
The solution to the synchronization problem is called repo
- a repository management tool build on top of Git. Similar to git
submodules, repo can fetch specific branches and commits of multiple meta-layers, and does all of it based on a configuration file manifest.xml. repo
was created by Google to help with the management of the Android and Yocto repositories and slowly is becoming the standard tool for putting Yocto distributions together. Many popular vendors like NXP or STM already use it.
Install Instructions#
repo
is a python script at its core and can be installed as such simply by downloading a single file from google. The script will then take care of creating a repo environment by fetching the rest of the resources.
# manual install mkdir -p ~/.bin PATH="${HOME}/.bin:${PATH}" curl https://storage.googleapis.com/git-repo-downloads/repo > ~/.bin/repo chmod a+rx ~/.bin/repo
That’s not the only option though. repo
is available in most of the package managers of the popular Linux distributions.
Debian / Ubuntu
sudo apt-get install repo
Gentoo
sudo emerge dev-vcs/repo
Repo Manifest#
The previously mentioned repo manifest file serves as the foundation of a custom Yocto distribution. The manifest itself must be hosted in a Git repository. A common best practice is to align the manifest’s branch names with Yocto release names - for example, use branches like kirkstone
or scarthgap
to reflect the corresponding Yocto version.
For the purpose of this blog and to exercise repo
skills, I made a simple project on github with a manifest for a Raspberry Pi-based Yocto distribution: rpi-manifest. This repository contains the complete manifest used in this example, and the rest of the article walks through the process of building it step by step
Synthax and Structure
Manifests are always XML files. Are you thinking messy tags and never ending indentations? Well, that should not be the case here, as the indentations are rather shallow, but tags are real and it’s possible to use them efficiently. The manifest starts with a line stating the XML version and encoding - standard XML stuff:
<?xml version="1.0" encoding="UTF-8"?>
then, the tag opening the manifest meta-layer configuration follows
<manifest> # manifest content goes here </manifest>
repo manifest files have a syntax rich in keywords like revision, remote, fetch, path, project and a few more, which are described in detail in the Manifest Format documentation provided by Google. As this article is based on my own work experience, only the syntax options I have personally used are introduced below.
Remote
The tag remote
assigns a name to a git URL - think of it as a shortcut to that URL. Intuitively, the name is defined with the name
attribute, and the URL itself with fetch
. The URL should point to the location of a parent project or a group, which members are specified further down with the project
tags.
<remote name="yp" fetch="https://git.yoctoproject.org"/>
Project
project
tag describes a git repository to be cloned. A few attributes go along with it, to provide the detailed info about how the repository should be cloned.
name
- name of the git project. The value of this attribute is appended to the URL specified in theremote
attribute, followed by .git.remote
- the parent URL of the requested git project. This could be either the group URL or user main workspace, just like in theremote
tag. What’s more is that theremote
tags can be referenced here, by passing theremote
tagname
value, this is later expanded into the full URL.path
- the destination path of the cloned project, the path is relative to the top directory of the repo client. Usually the format is"sources/<project-name>"
revision
- name of the Git branch the manifest wants to track for this project, a commit hash should also work.upstream
- according to the docs it does not differ that much fromrevision
, but to my understanding it should be set to the fetched branch name.
<project name="poky" remote="yp" path="sources/poky" revision="792d18b4cb2451b00280641403e6eaf37bd6e53f" upstream="scarthgap" /> <project name="meta-raspberrypi" remote="rpi" path="sources/meta-raspberrypi" revision="8e9ec2685a902038d1d6ad20f0821ee5655432a9" upstream="scarthgap" /> <project name="meta-openembedded" remote="oe" path="sources/meta-openembedded" revision="e8fd97d86af86cdcc5a6eb3f301cbaf6a2084943" upstream="walnascar" />
Linkfile
linkfile
tag lives inside the manifest tags and is used to specify symbolic linking to the files provided by the project. The file location in the source git repository is set with src
attribute and the target location in the local filetree is specified with dest
attribute. Both paths are relative. A single project
tag may be a home to multiple linkfile
tags.
Fetch the repositories with repo#
Now, that the manifest file is ready and pushed to its git repository, use repo init
to create the yocto environment on a local linux machine.
repo init -u https://github.com/anthonio9/rpi-manifest -b scarthgap -m rpi-6.12.25.xml repo sync
reported output of a successful `repo sync`should be like below:
Syncing: 100% (3/3), done in 1m40.918s repo sync has finished successfully.
Now, verify the content of the sources directory, make sure it contains all three meta layers.
[antoni@supercomputer sources]$ tree -L 1 . ├── meta-openembedded ├── meta-raspberrypi └── poky 4 directories, 0 files
CONGRATULATIONS! Yocto sources are fetched!
yay! Yeah, this is it. The most basic repo manifest, but enough to get you started on this Yocto journey :)
Extra stuff#
This was good, but there’s still a lot to learn. In the next chapters of my blog, more steps on Yocto are to be covered, so stay tuned. But if you can’t wait already, then I suggest you learn:
How to shallow clone a git repository with repo, to speed up the download times and decrease the used disk space
How to configure Yocto build directory, or you could also read my other article that shortly talks about it
I hope this was useful! Thanks for reading, more will come soon.