Here’s a practical, no-drama way to cross-compile Rust for Raspberry Pi with Cargo. Pick ONE of the three methods below; Method A is the simplest.
A) Easiest: cross (Docker-based)
# 1) Install cargo install cross rustup target add aarch64-unknown-linux-gnu # 64-bit Pi OS rustup target add armv7-unknown-linux-gnueabihf # 32-bit Pi 2/3/4 OS rustup target add arm-unknown-linux-gnueabihf # ARMv6 (Pi Zero/1) # 2) Build cross build --target aarch64-unknown-linux-gnu --release # or: cross build --target armv7-unknown-linux-gnueabihf --release # or: cross build --target arm-unknown-linux-gnueabihf --release # 3) Copy & run on the Pi scp target/<target>/release/yourapp pi@raspberrypi.local:/home/pi/ ssh pi@raspberrypi.local ./yourapp
cross bundles the right GCC/linkers in Docker images, so you avoid toolchain setup pain. Great if your project pulls C libraries.
B) Native toolchains + Cargo (no Docker)
- Install cross GCC/linker on your dev machine
Ubuntu/Debian:
sudo apt-get update sudo apt-get install gcc-aarch64-linux-gnu gcc-arm-linux-gnueabihf
macOS (Homebrew):
brew tap messense/macos-cross-toolchains brew install aarch64-linux-gnu-gcc arm-linux-gnueabihf-gcc
- Add Rust targets
rustup target add aarch64-unknown-linux-gnu rustup target add armv7-unknown-linux-gnueabihf rustup target add arm-unknown-linux-gnueabihf
- Tell Cargo which linker to use (.cargo/config.toml at workspace root)
[target.aarch64-unknown-linux-gnu] linker = "aarch64-linux-gnu-gcc" [target.armv7-unknown-linux-gnueabihf] linker = "arm-linux-gnueabihf-gcc" [target.arm-unknown-linux-gnueabihf] linker = "arm-linux-gnueabihf-gcc" # (Pi Zero/1 may need: rustflags = ["-C", "target-cpu=arm1176jzf-s"])
- Build
cargo build --target=aarch64-unknown-linux-gnu --release
C) “It just works” linker: cargo-zigbuild
If you can install Zig:
cargo install cargo-zigbuild rustup target add aarch64-unknown-linux-gnu cargo zigbuild --target aarch64-unknown-linux-gnu --release
Zig handles cross-linking without extra GCC toolchains.
Pick the correct target
The target depends on the OS architecture, not just the board. uname -m on the Pi: aarch64 → 64-bit, armv7l/armv6l → 32-bit.
Dealing with native C deps (OpenSSL, SDL, etc.)
- On the Pi, install dev packages (sudo apt-get install libssl-dev, etc.).
- When cross-compiling without cross/zigbuild, you may need:
export PKG_CONFIG_ALLOW_CROSS=1 export PKG_CONFIG_LIBDIR=/usr/<triple>/lib/pkgconfig export PKG_CONFIG_SYSROOT_DIR=/
- If it’s painful, build those crates on the Pi once, or switch to Method A/C.
Sanity checks
file target/aarch64-unknown-linux-gnu/release/yourapp # Expect: ELF 64-bit LSB executable, ARM aarch64, ...
Top comments (0)