Rust with Yocto

Michael Zhao
5 min readMay 12, 2022

--

This article introduces how to build Rust based applications with Yocto.

Yocto

The Yocto Project is an open source collaboration project that helps developers create custom Linux-based systems that are designed for embedded products regardless of the product’s hardware architecture.

I am not going to talk much about Yocto itself. Because there is a lot to say. Only the necessary repositories and commands will be mentioned.

Preparing Source Code

To build a Rust application with Yocto, you need to clone 3 Yocto repositories at least:

  • poky: The essential part of Yocto
  • meta-rust: The Yocto layer that supports Rust
  • meta-openembedded: The layer that meta-rust depends on

Yocto requires that all the layers working together must align to the same release. Now the latest Yocto release that meta-rust supports is honister.

Here come the commands for cloning the repos at the correct branch:

# Clone `meta-rust`
~ git clone https://github.com/meta-rust/meta-rust.git
# Clone `poky` and checkout the `honister` branch
~ git clone https://git.yoctoproject.org/poky
~ cd poky && git checkout -b honister origin/honister && cd -
# Clone `meta-openembedded` and checkout the `honister` branch
~ git clone https://git.openembedded.org/meta-openembedded
~ cd meta-openembedded && git checkout -b honister origin/honister && cd -

Setup

After fetching all the layers at correct branches. You need to initialize the build environment for bitbake :

~ cd poky
~ source oe-init-build-env

The oe-init-build-env script creates a build/ folder in poky/. Some initialization work is done and folders are created in build/ (and now this is your working directory). Among the new sub-folders is conf/, which contains some configuration files for bitbake.

Now you need to update conf/bblayers.conf file to add the additional layers besides poky :

~  conf git:(honister) ✗ ls
bblayers.conf local.conf templateconf.cfg
~ conf git:(honister) ✗ cat bblayers.conf
# POKY_BBLAYERS_CONF_VERSION is increased each time build/conf/bblayers.conf
# changes incompatibly
POKY_BBLAYERS_CONF_VERSION = "2"
BBPATH = "${TOPDIR}"
BBFILES ?= ""
BBLAYERS ?= " \
/mnt/data/tmp/poky/meta \
/mnt/data/tmp/poky/meta-poky \
/mnt/data/tmp/poky/meta-yocto-bsp \
/mnt/data/tmp/meta-openembedded/meta-oe \
/mnt/data/tmp/meta-rust \

"

The last lines of the file in bold font was added for this test.

Build Hello-world

meta-rust provides an example recipe for building an easy hello-world application. Try to build it with command:

# Make sure you are in `poky/build` folder and 
# `source oe-init-build-env` has been issues in the terminal
# you are working on.
~ bitbake rust-hello-world

The first-time build takes quite a few minutes.

Packing the Hello-world into Distribution

Rather than building a standalone application, you can also build the hello-world binary and deploy it into a distribution image. The image contains everything for a whole system. Then it can be written to a flash device.

To make the hello-world into the distribution image, you need to append one line to a configuration file: ./build/conf/local.conf :

DISTRO_FEATURES += "rust-hello-world"

With DISTRO_FEATURES you can specify the software you want in the distribution.

Then you need to build a whole image.

# Make sure you are in `poky/build` folder and `source oe-init-build-env` has been issues in the terminal you are working on
~ bitbake core-image-minimal

If this is the first time you build the image, it must take a long time to finish: maybe an hour or more. Because a lot of thing are to be built: kernel, root-fs, every applications and etc.

Once the building is done, the image will be ready in folder ./build/tmp/deploy/images/qemux86_64.

Building Cloud Hypervisor with Yocto

The hello-world demo is too simple. How to work with a more complex application?

I tried to build Cloud Hypervisor with the help of meta-rust but didn’t succeed. Here I recorded how I was trying everything.

The first question is how to create the Yocto recipe. For Rust based software, if you don’t want to write the recipe manually, cargo-bitbake is a good choice.

cargo-bitbake is developed in a sibling repo of meta-rust mentioned previously under the same project. You can install it with cargo :

~ cargo install --locked cargo-bitbake

Then enter the Rust based repository folder (in this test, it is where I cloned Cloud Hypervisor repository), and generate a recipe file for the software as easily as:

$ cargo bitbake

When I was doing this under Cloud Hypervisor folder, a file cloud-hypervisor_22.0.0.bb was generated. The recipe is not complete yet, there is a little more job you need to do. cargo-bitbake didn’t generate the MD5 checksum for the license files. You need to do that at first, open the .bb file and fill the digits. Find the comments with “FIXME”, you will not miss it.

Now the recipe is ready, let’s find a layer to hold it. I put it in meta-rust. The folder setting in meta-rust is like this when I finished:

recipes-example
├── cloud-hypervisor
└── cloud-hypervisor_22.0.0.bb

Next I tried to build with following command, but failed.

bitbake cloud-hypervisor

The problem is related to the lack of cargo edition2021 support in meta-rust :

  • My first test was made on latest Cloud Hypervisor version, that is release 23.0.0. Cloud Hypervisor has upgraded Cargo to 2021 edition in this release. When I tried cargo bitbake, cargo-bitbake complained that Cargo is too new, only edition 2018 and 2015 is supported. So I have to checkout Cloud Hypervisor to the last commit before upgrading Cargo edition.
  • When I built the generated recipe, some errors were seen about the missing requirement for “edition2021”.

I was between Scylla and Charybdis.

Adding the support of edition2021 looks the correct way to let everything work. But now meta-rust community is not active now. I am not sure whether the gap will be filled in future or never.

Reference

--

--