Building the Mender-Rust project with Yocto

This is part III in a series on writing a Mender-client in Rust.

Read part II here, and part I here.

In order to really get the project tested, we are going to build it along with the the Yocto sources for the Mender project. For the uninitiated, Yocto is a configurable Linux distribution, which relies on the Bitbake build-system, and comes with a reference distribution called Poky.

My initial idea was to simply build a static binary, and install it, using a Yocto recipe. However, I did not manage to complete this install, due to OpenSSL versioning errors.

This is what the binary looks like when inspected:

➜ Mender-Rust git:(master) ✗ ldd target/debug/mender-rust    
    linux-vdso.so.1 (0x00007ffcadbed000)
    libgtk3-nocsd.so.0 => /usr/lib/x86_64-linux-gnu/libgtk3-nocsd.so.0 (0x00007fe38bc00000)
    libssl.so.1.0.0 => /usr/lib/x86_64-linux-gnu/libssl.so.1.0.0 (0x00007fe38b998000)
    libcrypto.so.1.0.0 => /usr/lib/x86_64-linux-gnu/libcrypto.so.1.0.0 (0x00007fe38b555000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fe38b351000)
    librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fe38b149000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fe38af2a000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fe38ad12000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe38a921000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fe38ce5d000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fe38a583000)

Also the paths are static, and frankly I am unsure if this would even work, as the paths are most likely different in the final sysroot in the image built, and I don't want to look into link-hacks like LD_LOAD, or rpath etc. Usually, this is what I have my colleagues Vratislav, and Kristian for, but since this is a Sunday night, this is probably not at the top of their priorities list.

In general, when building a Rust project with Yocto, there are two options available. These were found from https://layers.openembedded.org/layerindex/branch/master/layers/, and simply typing in rust. The first option

1) meta-rust

This project provides the rust-compiler, and the tools for building packages (cargo), and a few example projects. It also (supposedly) works well, alongside 'cargo-bitbake', which can be used to automatically generate Yocto-recipes for a rust crate.

2) meta-rust-bin

The meta-rust-bin project is a little different as it relies on pre-built tool-chains. Which means that they are using the tool-chains provided by the Rust team. In general the trade-off means that, while this provides less configureability, and is arguably a less 'Yoctoish' way of doing things, upgrading to the latest version of the tool-chain is easy as changing the checksum in the recipe.

After a little bit back and forth, I decided to go with the 'mender-rust-bin' version, as I am trying to keep things as easy as possible, and also, i will not be targeting anything else than the standard rust triplet on my machine 'x86_64-unknown-linux-gnueabihf'.

The first draft of the recipe looks like this:

inherit cargo

LICENSE = "CLOSED"
LICENSE_FLAGS = "commercial"

SRC_URI = "git:///home/olepor/misc/rust/Mender-Rust;protocol=file"
SRC_URI[md5sum] = "e9335536da6a611bd1ef58e64d3b9b88"
SRC_URI[sha256sum] = "b56b4b60ceaaa39440b59d32877f550601d2f4d5a437c1367aa3fe51aa9b1c13"

S = "${WORKDIR}/git"

SRCREV = "989e3fa50a378323bf665e23bfb0f3d4e39cdb8c"

Which is a simple Yocto recipe for building from my local git repository. This fails however, due to the dependency that the Mender-Rust project has on the local sources of 'mender-artifact-rust' project.

  Updating crates.io index
| error: failed to load source for a dependency on `mender_artifact`

Now, how to remedy this?

Let's upload the mender-artifact project to 'crates.io', which is the Rust project's index for packages. And the way Rust software is distributed, and is the way that all the other dependencies of Mender-Rust is resolved. From the 'Cargo.toml' file, we see that:

[package]
name = "mender-rust"
version = "0.1.1"
authors = ["Ole Petter <olepor@matnat.uio.no>"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[target.x86_64-unknown-linux-gnu]
rustflags = ["-C", "target-feature=+crt-static"]

[dependencies]
serde = { version = "1.0", features = ["derive"] } # Derive Deserialization for the config struct
serde_json = "1" # serde_json
base64 = "0.10"
reqwest = "0.9"
rsa = "0.1.3"
log = "0.4"
simple_logger = "1.3.0"
hex = "0.3.2"
# OpenSSL = { version = "0.10", features = ["vendored"] }
openssl = "0.10.24"
ma = { path = "../mender-artifact-rust" , version = "0.1.1", package = "mender_artifact"  }

Since hard-coding the path now is futile, let's change the mender-artifact dependency to rely on the GitHub project.

...
...
openssl = "0.10.24"
ma = { git = "https://github.com/olepor/mender-artifact-rust.git", version = "0.1.1", package = "mender_artifact"  }

Which will then default to using the latest commit on the master branch, which suits us well.

Then now building the project with Yocto works fine, and our shiny Rust client works just fine on our own custom Linux setup :)

Recent articles

How over-the-air (OTA) updates help emergency response teams

How over-the-air (OTA) updates help emergency response teams

Discover how over-the-air (OTA) updates revolutionize emergency response teams, ensuring secure and seamless device maintenance and functionality in critical situations.
What’s hot in the open source and embedded community?

What’s hot in the open source and embedded community?

AI, robotics, IoT, AVs, and more – 2024 is proving to be an exciting year for technology. And the open source and embedded tech community is no exception.
How to use over-the-air (OTA) updates & NVIDIA Jetson Microservices

How to leverage over-the-air (OTA) updates with NVIDIA Microservices for Jetson

Mender, in collaboration with NVIDIA, published two critical use cases, providing a step-by-step guide to over-the-air (OTA) updates with NVIDIA Jetson.
View more articles

Learn more about Mender

Explore our Resource Center to discover more about how Mender empowers both you and your customers with secure and reliable over-the-air updates for IoT devices.

 
sales-pipeline_295756365