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.