Adding Rust Applications to Yocto Images Using the meta-oe’s cargo class

If you want to use Rust for Linux system programming and build your system with Yocto, you’ll need clear steps to let Yocto build Rust code for another system and include it in the final image.

You can add Rust support in different ways, but I prefer using Yocto’s built-in cargo class. With this method, the process is straightforward: use an existing Rust project or create a new one, make sure the cargo.lock file is present, upload the project to a Git repository, and then create or use a Yocto layer to add your instructions.

Next, check that the cargo version on your local system matches the one Yocto uses. In your recipe, tell Yocto to fetch the Rust project from the repository, cross-compile it, and install the binary into the root filesystem. Finally, build the Linux image and run your application.

I created a repository for a simple Rust project, followed all of these steps, tested the result, and documented the entire process in the repository as a reference and example.

One important detail: Cargo doesn’t create a cargo.lock file when you first make a project. The lock file only appears after you run a command like cargo build or cargo generate-lockfile. Since Yocto needs a fixed dependency graph, the cargo.lock file must be present and committed to your application repository before building with Yocto. So, always check that this file exists and is correct when adding your Rust repository.

Another important point is the version of rust-native and cargo-native that Yocto provides. Each Yocto release comes with certain versions of Rust and Cargo, and these versions can be different in each release. To avoid build problems, the Rust project in your application repository must be set up using the same Cargo version as the one Yocto uses. This means that, on your own computer, you should build the Rust project and create its cargo.lock file using the same cargo version before you add it to the repository. The cargo version you use and the one Yocto uses must match.


1. Preparing a Clean Yocto Build Environment

Start by creating a clean Yocto workspace with the Scarthgap release. This ensures you have the same setup as my layer, so you don’t need to go with item number 7: Cargo.lock Compatibility, otherwise you need to follow that section.

Edit the build configuration file:

<yocto-build-directory>/conf/local.conf

Set the target machine to QEMU ARM64:

MACHINE = "qemuarm64"

2. Checking the Rust and Cargo Versions Used by Yocto

Before working with your Rust application repository, check which Rust and Cargo versions Yocto provides. These versions decide which Cargo.lock formats are supported.

From within the Yocto build environment, run:

bitbake -e cargo-native | grep '^PV='bitbake -e rust-native  | grep '^PV='

For Yocto Scarthgap, you’ll usually see output like this:

PV="1.75.0"

This version number should match the Cargo version you used to generate the Cargo.lock file in your Rust repository.


3. Cloning and Adding the meta-rust-apps Layer

Next, clone and add the meta-rust-apps layer to your Yocto setup. This layer has example application recipes and keeps app-level metadata separate from core system components.

From the Yocto environment:

cd <layers-directory>git clone https://github.com/mominux/meta-rust-apps.git

Add the layer to the build:

bitbake-layers add-layer <layers-directory>/meta-rust-appsbitbake-layers show-layers

Verify that the example recipe is visible:

bitbake-layers show-recipes | grep -i hello

Now, you should see the hello-yocto recipe listed.


4. Building the Example Rust Application

To check that the layer and recipe are set up right, build the example application:

bitbake hello-yocto

If the build works, add the package to your image configuration.

Edit:

<yocto-build-directory>/conf/local.conf

Append:

IMAGE_INSTALL:append = " hello-yocto"

Then build the image:

bitbake core-image-minimal

This builds a full Yocto image with the Rust application installed in /usr/bin.


5. Running the Image in QEMU and Testing the Application

When the image build finishes, start QEMU:

runqemu qemuarm64 nographic

After the system boots and you log in as root, run your Rust application:

root@qemuarm64:~# hello-rust-yocto 

You should see this output:


root@qemuarm64:~# hello-rust-yocto
Hello Yocto, from Rust!

This shows that your Rust application was built, packaged, installed, and executed inside the Yocto image.


6. Using Your Own Rust Application Repository

Once you’ve tested the example application, you can swap it out for your own Rust project.

Clone your Rust application repository:

git clone <your-rust-application-repository>
cd <the-cloned-rust-application-repository>

7. Making Sure Cargo.lock Is Compatible (If Needed)

Check the Cargo version installed on your local system:

cargo --version

If your version doesn’t match the one Yocto uses, install the right toolchain with rustup:

rustup toolchain install <yocto-cargo-version>

Create the lock file with the matching Cargo version:

cargo +<yocto-cargo-version> generate-lockfile

For example, if Yocto uses Cargo 1.75.0:

rustup toolchain inFor example, if Yocto uses Cargo 1.75.0, run:kfile

Commit the updated lock file:

git add Cargo.lockgit commit -m "Generate Cargo.lock using Yocto-compatible Cargo version"git push

Record the commit SHA:

git rev-parse HEAD

Update your Yocto recipe by setting the SRCREV value to this commit SHA.

Visited 143 times, 1 visit(s) today