27 stable releases
| new 1.1.16 | Dec 4, 2025 |
|---|---|
| 1.1.11 | Dec 2, 2025 |
| 1.1.7 | Nov 30, 2025 |
| 1.0.9 | Oct 28, 2025 |
#81 in Cargo plugins
81 downloads per month
105KB
2K
SLoC
Rust Cross Build Action
A powerful GitHub Action for building, testing, and checking Rust projects with cross-compilation support. This action automatically downloads and configures the necessary cross-compilation toolchains, making it easy to execute various Rust commands for multiple platforms. No Need Docker!
Features
- 🚀 Cross-compilation support for Linux (GNU/musl), Windows, macOS, FreeBSD, Android, and iOS
- 🖥️ Multi-platform hosts - runs on Linux (x86_64/aarch64/armv7) and macOS (x86_64/aarch64)
- 📦 Automatic toolchain setup - downloads and configures cross-compilers as needed
- 🎯 Multiple target support - build for 63+ target platforms in a single run
- 🏗️ Workspace support - work with entire workspaces or specific packages
- ⚡ Flexible linking - musl targets default to static, GNU targets default to dynamic, both configurable via
static-crtparameter - 🔧 Flexible configuration - extensive customization options
- 📁 Organized output - all artifacts collected in a single directory
- 🛠️ Multiple commands - supports build, test, and check operations
Quick Start
Basic Usage
name: Build
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Cross compile
uses: zijiren233/cargo-cross@v1
with:
command: build
targets: |
x86_64-unknown-linux-musl
aarch64-unknown-linux-musl
Build for Multiple Platforms
name: Release
on:
release:
types: [created]
jobs:
build:
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
- name: Build Release
uses: zijiren233/cargo-cross@v1
with:
command: build
targets: |
x86_64-unknown-linux-musl
aarch64-unknown-linux-musl
x86_64-pc-windows-gnu
x86_64-apple-darwin
aarch64-apple-darwin
profile: release
- name: Upload artifacts
uses: actions/upload-artifact@v3
with:
name: binaries-${{ matrix.os }}
path: target/*/release/*
Host Platforms (Runners)
This action can run on the following GitHub Actions runners or local platforms:
Supported Host Platforms
| Platform | Architecture | GitHub Runner | Local Support |
|---|---|---|---|
| Linux | x86_64 (amd64) | ubuntu-latest, ubuntu-24.04, ubuntu-22.04, ubuntu-20.04 |
✅ Yes |
| Linux | aarch64 (arm64) | ubuntu-24.04-arm |
✅ Yes |
| Linux | armv7 | Self-hosted ARMv7 runners | ✅ Yes |
| macOS | x86_64 (Intel) | macos-15-intel |
✅ Yes |
| macOS | aarch64 (Apple Silicon) | macos-15 |
✅ Yes |
Recommended Usage
For maximum compatibility and cross-compilation support, use Linux x86_64 runners:
jobs:
build:
runs-on: ubuntu-latest # Best for cross-compilation
steps:
- uses: actions/checkout@v3
- uses: zijiren233/cargo-cross@v1
with:
targets: |
x86_64-unknown-linux-musl
aarch64-unknown-linux-musl
x86_64-pc-windows-gnu
aarch64-apple-darwin
aarch64-apple-ios
For macOS/iOS native/cross builds, use macOS runners:
jobs:
build-macos:
runs-on: macos-latest # Apple Silicon
steps:
- uses: actions/checkout@v3
- uses: zijiren233/cargo-cross@v1
with:
targets: |
x86_64-unknown-linux-musl
aarch64-unknown-linux-musl
x86_64-pc-windows-gnu
aarch64-apple-darwin
aarch64-apple-ios
Supported Targets
Linux (musl - static by default)
musl targets produce statically linked binaries by default. Use static-crt: false to enable dynamic linking.
i586-unknown-linux-musl- Linux i586i686-unknown-linux-musl- Linux i686x86_64-unknown-linux-musl- Linux x86_64arm-unknown-linux-musleabi- ARM Linuxarm-unknown-linux-musleabihf- ARM Linux hard-floatarmv5te-unknown-linux-musleabi- ARMv5TE Linuxarmv7-unknown-linux-musleabi- ARMv7 Linuxarmv7-unknown-linux-musleabihf- ARMv7 Linux hard-floataarch64-unknown-linux-musl- ARM64 Linuxloongarch64-unknown-linux-musl- LoongArch64 Linuxmips-unknown-linux-musl- MIPS Linuxmipsel-unknown-linux-musl- MIPS little-endian Linuxmips64-unknown-linux-muslabi64- MIPS64 Linuxmips64-openwrt-linux-musl- MIPS64 OpenWrt Linuxmips64el-unknown-linux-muslabi64- MIPS64 little-endian Linuxpowerpc64-unknown-linux-musl- PowerPC64 Linuxpowerpc64le-unknown-linux-musl- PowerPC64 little-endian Linuxriscv64gc-unknown-linux-musl- RISC-V 64-bit Linuxs390x-unknown-linux-musl- S390x Linux
Linux (GNU libc - dynamic by default)
GNU libc targets produce dynamically linked binaries by default. Use static-crt: true to enable static linking.
i586-unknown-linux-gnu- Linux i586i686-unknown-linux-gnu- Linux i686x86_64-unknown-linux-gnu- Linux x86_64arm-unknown-linux-gnueabi- ARM Linuxarm-unknown-linux-gnueabihf- ARM Linux hard-floatarmv5te-unknown-linux-gnueabi- ARMv5TE Linuxarmv7-unknown-linux-gnueabi- ARMv7 Linuxarmv7-unknown-linux-gnueabihf- ARMv7 Linux hard-floataarch64-unknown-linux-gnu- ARM64 Linuxloongarch64-unknown-linux-gnu- LoongArch64 Linuxmips-unknown-linux-gnu- MIPS Linuxmipsel-unknown-linux-gnu- MIPS little-endian Linuxmips64-unknown-linux-gnuabi64- MIPS64 Linuxmips64el-unknown-linux-gnuabi64- MIPS64 little-endian Linuxpowerpc64-unknown-linux-gnu- PowerPC64 Linuxpowerpc64le-unknown-linux-gnu- PowerPC64 little-endian Linuxriscv64gc-unknown-linux-gnu- RISC-V 64-bit Linuxs390x-unknown-linux-gnu- S390x Linux
Windows
i686-pc-windows-gnu- Windows i686 (MinGW)x86_64-pc-windows-gnu- Windows x86_64 (MinGW)
FreeBSD
x86_64-unknown-freebsd- FreeBSD x86_64aarch64-unknown-freebsd- FreeBSD ARM64powerpc64-unknown-freebsd- FreeBSD PowerPC64powerpc64le-unknown-freebsd- FreeBSD PowerPC64 little-endianriscv64gc-unknown-freebsd- FreeBSD RISC-V 64-bit
macOS
x86_64-apple-darwin- macOS Intel (x86_64)x86_64h-apple-darwin- macOS Intel (x86_64h, optimized for Haswell+)aarch64-apple-darwin- macOS Apple Silicon (ARM64)arm64e-apple-darwin- macOS Apple Silicon (ARM64e)
Android
i686-linux-android- Android x86x86_64-linux-android- Android x86_64armv7-linux-androideabi- Android ARMv7arm-linux-androideabi- Android ARMaarch64-linux-android- Android ARM64riscv64-linux-android- Android RISC-V 64-bit
iOS
x86_64-apple-ios- iOS Simulator (x86_64)aarch64-apple-ios- iOS ARM64aarch64-apple-ios-sim- iOS ARM64 Simulator
Inputs
| Input | Description | Default |
|---|---|---|
command |
Command to execute (build, test, check) |
build |
targets |
Newline-separated list of Rust target triples (comma-separated also supported) | Host target |
profile |
Build profile (debug or release) |
release |
features |
Comma-separated list of features to activate | |
no-default-features |
Do not activate default features | false |
all-features |
Activate all available features | false |
package |
Package to build (workspace member) | |
bin |
Binary target to build | |
workspace |
Build all workspace members | false |
manifest-path |
Path to Cargo.toml | |
source-dir |
Directory containing the Rust project | ${{ github.workspace }} |
bin-name-no-suffix |
Don't append target suffix to binary name | false |
github-proxy-mirror |
GitHub proxy mirror URL | |
cross-compiler-dir |
Directory to store cross compilers | |
ndk-version |
Android NDK version | r27 |
use-default-linker |
Use system default linker | false |
cc |
Force set the C compiler | |
cxx |
Force set the C++ compiler | |
rustflags |
Additional rustflags | |
static-crt |
Control CRT linking mode: true for static (+crt-static), false for dynamic (-crt-static), empty for default (musl=static, gnu=dynamic) |
`` |
build-std |
Use -Zbuild-std for building standard library from source (true for default, or specify crates like core,alloc) |
false |
args |
Additional arguments to pass to cargo command | |
toolchain |
Rust toolchain to use (stable, nightly, etc.) | stable |
cargo-trim-paths |
Set CARGO_TRIM_PATHS environment variable for reproducible builds | |
no-embed-metadata |
Add -Zno-embed-metadata flag to cargo | false |
rustc-bootstrap |
Set RUSTC_BOOTSTRAP environment variable: 1 for all crates, -1 for stable behavior, or crate_name for specific crate |
|
clean-cache |
Clean build cache before building | false |
no-strip |
Do not strip binaries | false |
verbose |
Use verbose output | false |
Outputs
| Output | Description |
|---|---|
targets |
Targets that were processed |
Advanced Examples
Build with Features
- name: Build with features
uses: zijiren233/cargo-cross@v1
with:
command: build
targets: x86_64-unknown-linux-musl
features: feature1,feature2
no-default-features: true
Build Specific Binary from Workspace
- name: Build specific binary
uses: zijiren233/cargo-cross@v1
with:
command: build
targets: x86_64-unknown-linux-musl
package: my-package
bin: my-binary
Android Build
- name: Build for Android
uses: zijiren233/cargo-cross@v1
with:
command: build
targets: |
aarch64-linux-android
armv7-linux-androideabi
ndk-version: r27
Custom Compiler
- name: Build with custom compiler
uses: zijiren233/cargo-cross@v1
with:
command: build
targets: x86_64-unknown-linux-gnu
cc: /usr/bin/custom-gcc
cxx: /usr/bin/custom-g++
Static/Dynamic Linking Configuration
# musl targets: static by default, set to false for dynamic linking
- name: Build musl with dynamic linking
uses: zijiren233/cargo-cross@v1
with:
command: build
targets: x86_64-unknown-linux-musl
static-crt: false
# GNU targets: dynamic by default, set to true for static linking
- name: Build GNU with static linking
uses: zijiren233/cargo-cross@v1
with:
command: build
targets: x86_64-unknown-linux-gnu
static-crt: true
# Leave empty to use default behavior (musl=static, gnu=dynamic)
- name: Build with default linking
uses: zijiren233/cargo-cross@v1
with:
command: build
targets: |
x86_64-unknown-linux-musl
x86_64-unknown-linux-gnu
# static-crt not specified - uses defaults
Custom Rustflags
- name: Build with custom rustflags
uses: zijiren233/cargo-cross@v1
with:
command: build
targets: x86_64-unknown-linux-musl
rustflags: "-C opt-level=3 -C codegen-units=1"
Build Standard Library from Source
# Build with default std crates
- name: Build with build-std (default)
uses: zijiren233/cargo-cross@v1
with:
command: build
targets: x86_64-unknown-linux-musl
build-std: true
toolchain: nightly
# Build with specific crates
- name: Build with build-std (custom crates)
uses: zijiren233/cargo-cross@v1
with:
command: build
targets: x86_64-unknown-linux-musl
build-std: core,alloc
toolchain: nightly
Matrix Build
jobs:
build:
strategy:
matrix:
target:
- x86_64-unknown-linux-musl
- aarch64-unknown-linux-musl
- x86_64-pc-windows-gnu
- x86_64-apple-darwin
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build
uses: zijiren233/cargo-cross@v1
with:
command: build
targets: ${{ matrix.target }}
- name: Upload
uses: actions/upload-artifact@v3
with:
name: ${{ matrix.target }}
path: target/${{ matrix.target }}/release/*
Test Across Multiple Targets
- name: Test cross-platform
uses: zijiren233/cargo-cross@v1
with:
command: test
targets: |
x86_64-unknown-linux-musl
aarch64-unknown-linux-musl
Check Code Quality
- name: Check code
uses: zijiren233/cargo-cross@v1
with:
command: check
targets: x86_64-unknown-linux-musl
all-features: true
Use Nightly Toolchain
- name: Build with nightly
uses: zijiren233/cargo-cross@v1
with:
command: build
targets: x86_64-unknown-linux-musl
toolchain: nightly
Reproducible Builds with CARGO_TRIM_PATHS
- name: Build with reproducible paths
uses: zijiren233/cargo-cross@v1
with:
command: build
targets: x86_64-unknown-linux-musl
cargo-trim-paths: all
Build without Metadata Embedding
- name: Build without embedding metadata
uses: zijiren233/cargo-cross@v1
with:
command: build
targets: x86_64-unknown-linux-musl
no-embed-metadata: true
toolchain: nightly
Build with RUSTC_BOOTSTRAP
The RUSTC_BOOTSTRAP environment variable tells rustc to act as if it is a nightly compiler, allowing use of #![feature(...)] attributes and -Z flags even on the stable release channel.
# Enable nightly features for all crates
- name: Build with nightly features on stable
uses: zijiren233/cargo-cross@v1
with:
command: build
targets: x86_64-unknown-linux-musl
rustc-bootstrap: "1"
# Enable nightly features for specific crate
- name: Build with nightly features for specific crate
uses: zijiren233/cargo-cross@v1
with:
command: build
targets: x86_64-unknown-linux-musl
rustc-bootstrap: "my_crate_name"
# Force stable behavior even on nightly
- name: Build with stable behavior on nightly
uses: zijiren233/cargo-cross@v1
with:
command: build
targets: x86_64-unknown-linux-musl
toolchain: nightly
rustc-bootstrap: "-1"
Local Usage
Installation as Cargo Subcommand
You can install this tool as a cargo subcommand for easy cross-compilation:
# Install from crate
cargo install cargo-cross
# Install from GitHub
cargo install cargo-cross --git https://github.com/zijiren233/cargo-cross
# Or install from local path
cargo install --path .
After installation, you can use cargo cross command:
# Show help
cargo cross --help
# Show all supported targets
cargo cross --show-all-targets
# Build for a specific target
cargo cross build --target x86_64-unknown-linux-musl
# Build for multiple targets
cargo cross build --targets x86_64-unknown-linux-musl,aarch64-unknown-linux-musl
# Build with release profile
cargo cross build --target x86_64-unknown-linux-musl --release
# Build with features
cargo cross build --target x86_64-unknown-linux-musl --features feature1,feature2
# Test for a target
cargo cross test --target x86_64-unknown-linux-musl
# Check the project
cargo cross check --target x86_64-unknown-linux-musl
Direct Script Usage
You can also use the execution script directly:
# Build for a specific target (default command)
./cross.sh --targets=x86_64-unknown-linux-musl
# Explicitly specify build command
./cross.sh build --targets=x86_64-unknown-linux-musl
# Test for multiple targets
./cross.sh test --targets=x86_64-unknown-linux-musl,aarch64-unknown-linux-musl
# Check the project
./cross.sh check --targets=x86_64-unknown-linux-musl
# Show all supported targets
./cross.sh --show-all-targets
# Build with features
./cross.sh build --targets=x86_64-unknown-linux-musl --features=feature1,feature2
# Build entire workspace
./cross.sh build --targets=x86_64-unknown-linux-musl --workspace
# Build with nightly toolchain
./cross.sh build --targets=x86_64-unknown-linux-musl --toolchain=nightly
# Test with stable toolchain (explicitly)
./cross.sh test --targets=x86_64-unknown-linux-musl --toolchain=stable
# Build musl with dynamic linking (musl is static by default)
./cross.sh build --targets=x86_64-unknown-linux-musl --static-crt=false
# Build GNU with static linking (GNU is dynamic by default)
./cross.sh build --targets=x86_64-unknown-linux-gnu --static-crt=true
# Build with custom rustflags
./cross.sh build --targets=x86_64-unknown-linux-musl --rustflags="-C opt-level=3 -C codegen-units=1"
# Build with build-std (build standard library from source)
./cross.sh build --targets=x86_64-unknown-linux-musl --build-std
# Build with build-std using specific crates
./cross.sh build --targets=x86_64-unknown-linux-musl --build-std=core,alloc
# Build with reproducible paths
./cross.sh build --targets=x86_64-unknown-linux-musl --cargo-trim-paths=all
# Build without embedding metadata (requires nightly toolchain)
./cross.sh build --targets=x86_64-unknown-linux-musl --no-embed-metadata --toolchain=nightly
# Build with RUSTC_BOOTSTRAP (enable nightly features for all crates)
./cross.sh build --targets=x86_64-unknown-linux-musl --rustc-bootstrap=1
# Build with RUSTC_BOOTSTRAP for specific crate
./cross.sh build --targets=x86_64-unknown-linux-musl --rustc-bootstrap=my_crate_name
# Build with RUSTC_BOOTSTRAP=-1 (force stable behavior on nightly)
./cross.sh build --targets=x86_64-unknown-linux-musl --rustc-bootstrap=-1 --toolchain=nightly
How It Works
- Command Detection: The action detects the requested command (build, test, or check)
- Target Detection: The action detects the requested target platforms
- Toolchain Setup: Automatically downloads and configures the necessary cross-compilation toolchains
- Environment Configuration: Sets up the correct environment variables for cross-compilation
- Command Execution: Runs the specified cargo command with the appropriate flags and configuration
- Artifact Output: Built binaries and libraries are placed in
target/{target}/{profile}/directories following Cargo's standard structure
Troubleshooting
Build fails with "linker not found"
Make sure you're running on a supported host OS. Linux hosts support the most targets. For macOS and Windows targets, you may need to run on the respective OS runners.
Binary is too large
Use profile: release and ensure stripping is enabled (default). Note that:
- musl targets produce statically linked binaries by default, which are larger but completely self-contained
- GNU targets produce dynamically linked binaries by default, which are smaller but require system libraries
- You can configure the linking behavior using the
static-crtparameter
Android build fails
Ensure you have enough disk space for the Android NDK download. You can also try a different NDK version with the ndk-version input.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Credits
This action uses cross-compilation toolchains from:
- cross-make for Linux/Windows/Freebsd targets
- osxcross for macOS targets
- cctools-port for ios targets
- Android NDK for Android targets