I was working on a DIY project and needed to compile some Rust code I wrote for a Raspberry Pi Zero W. There are plenty of blog posts and howto’s on the web about how to cross-compile Rust for the Pi but most of those resources are about newer Pi’s which have the ARMv7 (or v8) architecture (see Wikipedia for a list of which Pis are based on which ARM architecture). The Zero W (and Zero) are based on ARMv6, so it took a little extra Google-ing to figure out how to compile for that. And since I don’t really want to have a bunch of ARM packages installed on my own x86 laptop I put everything in a Docker image so it’s nice and isolated.
Thanks to Reddit user Arakvk33 on who’s post this image is mostly based.
The cmd
in the Dockerfile is:
cargo build --release --target=arm-unknown-linux-gnueabihf
Cargo knows how to cross-compile to ARMv6,
but we need the linker from the official Raspberry PI toolchain (installed in
the image). To use it, make sure your project has a .cargo/config
file with at
least the following content:
[target.arm-unknown-linux-gnueabihf]
linker = "/rpi_tools/arm-bcm2708/arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc"
For Cargo to pick up on this config it needs to be in the working directory
(inside the running docker container) where the command is run, so we need
to run docker
with the -w
switch. We should also mount our local Cargo
registry in the container (to avoid downloading the registry and all
dependencies each time) and provide an environment flag that tells pkg-config
it’s allowed to cross-compile. Also, for good measure, don’t run the container
as root (so that root doesn’t own all the binaries that are produced) and also
set the HOME
environment variable to the working directory so Cargo doesn’t
attempt to create files in the home of a non-existent (in the container at
least) uid.
Putting that all together we get:
WORKDIR="/work"
docker run -t --rm \
-u "$(id -u):$(id -g)"
-e "HOME=${WORKDIR}"
-e "PKG_CONFIG_ALLOW_CROSS=1"
-w "${WORKDIR}"
-v "$(pwd):${WORKDIR}"
-v "${HOME}/.cargo/registry:/usr/local/cargo/registry"
mdirkse/rust_armv6:latest
Copy and paste at will or use the script included with this repo.