How to use Cargo to cross compile Rust programs for Raspberry Pi?


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//release/yourapp pi@raspberrypi.local:/home/pi/
ssh pi@raspberrypi.local ./yourapp
Enter fullscreen mode

Exit fullscreen mode

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)

  1. 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
Enter fullscreen mode

Exit fullscreen mode

macOS (Homebrew):

brew tap messense/macos-cross-toolchains
brew install aarch64-linux-gnu-gcc arm-linux-gnueabihf-gcc
Enter fullscreen mode

Exit fullscreen mode

  1. Add Rust targets
rustup target add aarch64-unknown-linux-gnu
rustup target add armv7-unknown-linux-gnueabihf
rustup target add arm-unknown-linux-gnueabihf
Enter fullscreen mode

Exit fullscreen mode

  1. 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"])
Enter fullscreen mode

Exit fullscreen mode

  1. Build
cargo build --target=aarch64-unknown-linux-gnu --release
Enter fullscreen mode

Exit fullscreen mode

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
Enter fullscreen mode

Exit fullscreen mode

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//lib/pkgconfig
export PKG_CONFIG_SYSROOT_DIR=/
Enter fullscreen mode

Exit fullscreen mode

  • 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, ...
Enter fullscreen mode

Exit fullscreen mode



Source link

Leave a Reply

Your email address will not be published. Required fields are marked *