In the last post, we got NFS set up - that should make it quite easy to experiment with cross-compiling our own code for the scope and run it directly off of an NFS share.
I'm using the same Ubuntu 20.10 VM as always for this. The goal this time is to see
if we can write some code in rust and get it running. To follow along, you should
have rustup
installed. You can find
instructions here.
Creating a hello world binary
First, we're going to need the ARM target for Rust as well as the ARM cross compiler:
$ sudo apt install gcc-arm-linux-gnueabihf
$ rustup target install armv7-unknown-linux-musleabihf
Note that the target is using musl (a small C standard library) instead of glibc. The reason for this is mainly that on the scope, we have glibc 2.4 and we'd need a toolchain built against the same version in order to support dynamic linking. It therefore seems easier to use musl and just link everything statically for now.
Let's create a new rust project:
$ cargo new hello
Created binary (application) `hello` package
$ cd hello
Feel free to use your favorite editor to change the hello world message into whatever you like
in src/main.rs
. We can tell cargo what linker to use and build a binary for our target:
$ export CARGO_TARGET_ARMV7_UNKNOWN_LINUX_MUSLEABIHF_LINKER=/usr/bin/arm-linux-gnueabihf-gcc
$ cargo build --target=armv7-unknown-linux-musleabihf --release
Unfortunately this results in a 3.6 MB executable for me, which seems a bit excessive. We can
squash this in half: In Cargo.toml
, add a [profile.release]
section with the option lto = true
and build again.
A slight detour: Let's make it smaller
1.5 MB still seems excessive, so let's see if we can't make this even smaller. The nightly rust releases seem to have some more features:
- Install nightly:
rustup default nightly
- Install the rust source for nightly:
rustup component add rust-src --toolchain nightly
- You might have to install the target again for nightly:
rustup target install armv7-unknown-linux-musleabihf
Applying some more tricks, we get this Cargo.toml
:
cargo-features = ["strip"]
[package]
name = "hello"
version = "0.1.0"
edition = "2018"
[dependencies]
[profile.release]
lto = true
strip = "symbols"
codegen-units = 1
opt-level = "z"
for a binary size of about 260 KB. Still large for just printing "hello world" but much better.
Running it on the actual scope
You will need SSH access to your scope to test it - refer to the fist post in this series on how to get that.
You can either use the NFS share from last time or copy our binary over to the scope:
$ scp target/armv7-unknown-linux-musleabihf/release/hello root@IPOFYOURSCOPE:/tmp/
and login via SSH and run it:
<root@rigol>/tmp/hello
Hello, world!