
Rust Cross
- 307 installs
- 155 repo stars
- Updated June 27, 2026
- mohitmishra786/low-level-dev-skills
Cross-compile Rust crates to Linux, macOS, Windows, and embedded targets using targets.json, linkers, musl/glibc choices, and cross toolchains in CI.
About
Guides Rust cross-compilation setup for shipping binaries to multiple OS and CPU targets, covering target triples, linker config, libc choices, and CI patterns for CLI, API, and mobile-adjacent native artifacts.
- rustup target installation
- Cargo .cargo/config.toml
- musl vs gnu libc
- Cross-compiler and linker setup
- Multi-arch CI matrices
Rust Cross by the numbers
- 307 all-time installs (skills.sh)
- +23 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #39 of 121 Rust skills by installs in the Skillselion catalog
- Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/mohitmishra786/low-level-dev-skills --skill rust-crossAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 307 |
|---|---|
| repo stars | ★ 155 |
| Last updated | June 27, 2026 |
| Repository | mohitmishra786/low-level-dev-skills ↗ |
What it does
Cross-compile Rust crates to Linux, macOS, Windows, and embedded targets using targets.json, linkers, musl/glibc choices, and cross toolchains in CI.
Files
Rust Cross-Compilation
Purpose
Guide agents through Rust cross-compilation: adding rustup targets, using cross for hermetic Docker-based cross-builds, cargo-zigbuild for zero-setup cross-compilation, .cargo/config.toml configuration, and embedded bare-metal targets.
Triggers
- "How do I cross-compile Rust for ARM/aarch64?"
- "How do I build a Rust binary for a different OS?"
- "How do I use the cross tool for Rust cross-compilation?"
- "How do I build Rust for embedded (no_std) targets?"
- "How do I use cargo-zigbuild?"
- "My cross-compiled Rust binary won't run on the target"
Workflow
1. Add a rustup target
# List installed targets
rustup target list --installed
# List all available targets
rustup target list
# Add a target
rustup target add aarch64-unknown-linux-gnu
rustup target add x86_64-unknown-linux-musl # static Linux
rustup target add wasm32-unknown-unknown # WASM
rustup target add thumbv7m-none-eabi # Cortex-M
# Build for target
cargo build --target aarch64-unknown-linux-gnu --release2. Common target triples
| Target | Use case |
|---|---|
x86_64-unknown-linux-gnu | Linux x86-64 (glibc) |
x86_64-unknown-linux-musl | Linux x86-64 (musl, static) |
aarch64-unknown-linux-gnu | ARM64 Linux (Raspberry Pi 4, AWS Graviton) |
aarch64-unknown-linux-musl | ARM64 Linux static |
x86_64-pc-windows-gnu | Windows x86-64 (MinGW) |
x86_64-pc-windows-msvc | Windows x86-64 (MSVC) |
x86_64-apple-darwin | macOS x86-64 |
aarch64-apple-darwin | macOS Apple Silicon |
wasm32-unknown-unknown | WASM (browser) |
wasm32-wasi | WASM with WASI |
thumbv7m-none-eabi | Cortex-M3 bare metal |
thumbv7em-none-eabihf | Cortex-M4/M7 with FPU |
riscv32imac-unknown-none-elf | RISC-V 32-bit bare metal |
3. cross tool (Docker-based, easiest)
cross uses pre-built Docker images with the correct cross-toolchain:
# Install
cargo install cross
# Build (drop-in replacement for cargo)
cross build --target aarch64-unknown-linux-gnu --release
cross test --target aarch64-unknown-linux-gnu
# Cross.toml — project configuration# Cross.toml
[target.aarch64-unknown-linux-gnu]
image = "ghcr.io/cross-rs/aarch64-unknown-linux-gnu:main"
pre-build = [
"apt-get update && apt-get install -y libssl-dev:arm64"
]
[build.env]
passthrough = ["PKG_CONFIG_PATH", "OPENSSL_DIR"]4. cargo-zigbuild (zero-setup, uses zig cc)
zig cc ships a complete C cross-toolchain — no system cross-compiler needed:
# Install
cargo install cargo-zigbuild
# Also needs zig installed: https://ziglang.org/download/
# Build (no Docker, no system cross-compiler)
cargo zigbuild --target aarch64-unknown-linux-gnu --release
cargo zigbuild --target x86_64-unknown-linux-musl --release
# Target with glibc version (important for compatibility)
cargo zigbuild --target aarch64-unknown-linux-gnu.2.17 --release
# This builds against glibc 2.17 (very compatible)
# Windows from Linux/macOS
cargo zigbuild --target x86_64-pc-windows-gnu --releasecargo-zigbuild advantages over cross:
- No Docker required
- Faster (no container startup)
- Works for most targets out of the box
- Supports precise glibc version targeting
5. .cargo/config.toml for cross targets
# .cargo/config.toml
[target.aarch64-unknown-linux-gnu]
linker = "aarch64-linux-gnu-gcc" # System cross-linker
# or with zig:
# linker = "zig"
# rustflags = ["-C", "link-arg=cc", "-C", "link-arg=-target", "-C", "link-arg=aarch64-linux-gnu"]
[target.x86_64-unknown-linux-musl]
linker = "x86_64-linux-musl-gcc"
rustflags = ["-C", "target-feature=+crt-static"]
[target.wasm32-unknown-unknown]
runner = "wasmtime" # Run WASM tests with wasmtime
[target.thumbv7m-none-eabi]
runner = "qemu-arm -cpu cortex-m3"6. Static binaries with musl
# Add musl target
rustup target add x86_64-unknown-linux-musl
# Build statically linked binary
cargo build --target x86_64-unknown-linux-musl --release
# Verify it's static
file target/x86_64-unknown-linux-musl/release/myapp
# → ELF 64-bit, statically linked, not stripped
# Or with cargo-zigbuild (easier musl)
cargo zigbuild --target x86_64-unknown-linux-musl --release7. Embedded bare-metal (#[no_std])
# .cargo/config.toml
[build]
target = "thumbv7em-none-eabihf" # Set default target
[target.'cfg(target_arch = "arm")']
runner = "probe-run --chip STM32F411CE"// src/main.rs
#![no_std]
#![no_main]
use core::panic::PanicInfo;
#[cortex_m_rt::entry]
fn main() -> ! {
loop {}
}
#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
loop {}
}# Cargo.toml
[dependencies]
cortex-m = "0.7"
cortex-m-rt = "0.7"
[profile.release]
opt-level = "z"
lto = true
codegen-units = 1
panic = "abort"cargo build --release # Uses default target from .cargo/config.tomlFor target triple reference and embedded setup details, see references/.
Related skills
- Use
skills/rust/rustc-basicsfor compiler and profile configuration - Use
skills/compilers/cross-gccfor the underlying cross-compiler setup - Use
skills/zig/zig-crossfor Zig's native cross-compilation approach - Use
skills/build-systems/cmakewhen Rust is part of a CMake cross-build
Rust Cross-Compilation Target Reference
Full Target Triple Format
<cpu_arch>-<vendor>-<os>-<abi>cpu_arch: x86_64, aarch64, armv7, thumbv7m, riscv32imac, wasm32, ...vendor: unknown, pc, apple, (omitted for bare metal)os: linux, windows, macos, none (bare metal), wasiabi: gnu, musl, msvc, eabi, eabihf, (omitted for some)
Tier 1 Targets (guaranteed to work)
| Target | Platform |
|---|---|
x86_64-unknown-linux-gnu | Linux 64-bit (glibc) |
x86_64-pc-windows-gnu | Windows 64-bit (MinGW) |
x86_64-pc-windows-msvc | Windows 64-bit (MSVC) |
x86_64-apple-darwin | macOS 64-bit |
aarch64-unknown-linux-gnu | ARM64 Linux |
aarch64-apple-darwin | macOS Apple Silicon |
i686-unknown-linux-gnu | Linux 32-bit |
Popular Tier 2 Targets
| Target | Platform | Notes |
|---|---|---|
x86_64-unknown-linux-musl | Linux static | No glibc dep |
aarch64-unknown-linux-musl | ARM64 Linux static | |
armv7-unknown-linux-gnueabihf | ARM 32-bit Linux | Raspberry Pi 2/3 (32-bit) |
wasm32-unknown-unknown | WASM browser | No std |
wasm32-wasi | WASM WASI | Some std |
x86_64-unknown-freebsd | FreeBSD | |
aarch64-linux-android | Android ARM64 | |
x86_64-linux-android | Android x86-64 |
Bare Metal (Embedded) Targets
| Target | Architecture | Use case |
|---|---|---|
thumbv6m-none-eabi | Cortex-M0/M0+ | RP2040, lowest-end MCUs |
thumbv7m-none-eabi | Cortex-M3 | STM32F1, LPC1768 |
thumbv7em-none-eabi | Cortex-M4/M7 (no FPU) | STM32F4 without FPU |
thumbv7em-none-eabihf | Cortex-M4/M7 (FPU) | STM32F4/F7 with FPU |
thumbv8m.main-none-eabi | Cortex-M33 | STM32U5, nRF9160 |
riscv32imac-unknown-none-elf | RISC-V 32-bit | ESP32-C3, GD32VF |
riscv64imac-unknown-none-elf | RISC-V 64-bit | SiFive boards |
avr-unknown-gnu-atmega328 | AVR | Arduino Uno (nightly only) |
Glibc Version Targeting (cargo-zigbuild)
# Format: <target>.<glibc_major>.<glibc_minor>
cargo zigbuild --target aarch64-unknown-linux-gnu.2.17 # Very compatible
cargo zigbuild --target x86_64-unknown-linux-gnu.2.28 # Modern systems
cargo zigbuild --target aarch64-unknown-linux-gnu.2.35 # Ubuntu 22.04+
# Check required glibc version of a binary
objdump -T ./myapp | grep GLIBC
readelf -V ./myappcross Docker Images
# List available images
docker pull ghcr.io/cross-rs/aarch64-unknown-linux-gnu:main
# Available at ghcr.io/cross-rs/<target>:main
# aarch64-unknown-linux-gnu
# x86_64-unknown-linux-musl
# armv7-unknown-linux-gnueabihf
# aarch64-unknown-linux-musl
# x86_64-pc-windows-gnu
# ... (see https://github.com/cross-rs/cross)OpenSSL Cross-Compilation
OpenSSL is the most common pain point in cross-compilation:
# Option 1: use rustls instead (no C dependency)
# In Cargo.toml:
# reqwest = { version = "0.11", default-features = false, features = ["rustls-tls"] }
# Option 2: cross with pre-built OpenSSL
# Cross.toml:
# [target.aarch64-unknown-linux-gnu]
# pre-build = ["apt-get install -y libssl-dev:arm64"]
# Option 3: cargo-zigbuild with vendored OpenSSL
OPENSSL_STATIC=1 cargo zigbuild --target aarch64-unknown-linux-gnu
# Option 4: openssl-src crate (builds from source)
# [dependencies]
# openssl = { version = "0.10", features = ["vendored"] }Embedded Project Structure
my-embedded/
├── .cargo/
│ └── config.toml # default target, runner, linker
├── Cargo.toml
├── memory.x # Linker script (memory map)
├── build.rs # Copy memory.x to OUT_DIR
└── src/
└── main.rs # #![no_std] #![no_main]# .cargo/config.toml for STM32F4
[build]
target = "thumbv7em-none-eabihf"
[target.thumbv7em-none-eabihf]
runner = "probe-run --chip STM32F411CEUx"
rustflags = [
"-C", "link-arg=-Tlink.x",
"-C", "link-arg=--nmagic",
]# Cargo.toml for embedded
[dependencies]
cortex-m = { version = "0.7", features = ["critical-section-single-core"] }
cortex-m-rt = "0.7"
stm32f4xx-hal = { version = "0.20", features = ["stm32f411"] }
panic-probe = { version = "0.3", features = ["print-defmt"] }
defmt = "0.3"
defmt-rtt = "0.4"