Cross-Compilation em Rust: Guia Completo

Guia completo de cross-compilation em Rust: targets, crate cross, builds musl, ARM, RISC-V, WebAssembly e Docker cross builds para múltiplas plataformas.

Uma das grandes vantagens do Rust é a facilidade de compilar para diferentes plataformas a partir de uma única máquina. Neste guia, vamos explorar cross-compilation em Rust, desde builds musl estáticos até targets ARM, RISC-V e WebAssembly.

Conceitos Básicos

O que é um Target?

Um target no Rust segue o formato <arch>-<vendor>-<os>-<abi>:

  • x86_64-unknown-linux-gnu — Linux 64-bit com glibc
  • x86_64-unknown-linux-musl — Linux 64-bit com musl (estático)
  • aarch64-unknown-linux-gnu — Linux ARM 64-bit
  • x86_64-pc-windows-msvc — Windows 64-bit com MSVC
  • wasm32-unknown-unknown — WebAssembly
  • riscv64gc-unknown-linux-gnu — RISC-V 64-bit Linux

Listar Targets Disponíveis

# Targets instalados
rustup target list --installed

# Todos os targets disponíveis
rustup target list

# Filtrar por nome
rustup target list | grep linux
rustup target list | grep arm

Para mais detalhes sobre gerenciamento de targets, consulte o Guia Completo do Rustup.

Builds Musl (Binários Estáticos)

Binários estáticos com musl não dependem de bibliotecas compartilhadas do sistema, sendo portáveis entre distribuições Linux:

# Adicionar o target musl
rustup target add x86_64-unknown-linux-musl

# Instalar ferramentas musl
# Ubuntu/Debian
sudo apt install -y musl-tools

# Fedora
sudo dnf install -y musl-gcc

# Arch
sudo pacman -S musl

Compilar

cargo build --release --target x86_64-unknown-linux-musl

Verificar que o binário é estático

file target/x86_64-unknown-linux-musl/release/meu-app
# Saída: ELF 64-bit LSB executable, statically linked

ldd target/x86_64-unknown-linux-musl/release/meu-app
# Saída: not a dynamic executable

Binários estáticos são ideais para containers Docker mínimos usando FROM scratch.

Compilação para ARM

ARM 64-bit (aarch64) — Raspberry Pi 4/5, AWS Graviton

# Adicionar target
rustup target add aarch64-unknown-linux-gnu

# Instalar cross-compiler
# Ubuntu/Debian
sudo apt install -y gcc-aarch64-linux-gnu

# Configurar o linker
mkdir -p .cargo
cat > .cargo/config.toml << 'EOF'
[target.aarch64-unknown-linux-gnu]
linker = "aarch64-linux-gnu-gcc"
EOF

# Compilar
cargo build --release --target aarch64-unknown-linux-gnu

ARM 32-bit (armv7) — Raspberry Pi 2/3

rustup target add armv7-unknown-linux-gnueabihf

# Ubuntu/Debian
sudo apt install -y gcc-arm-linux-gnueabihf

cat >> .cargo/config.toml << 'EOF'
[target.armv7-unknown-linux-gnueabihf]
linker = "arm-linux-gnueabihf-gcc"
EOF

cargo build --release --target armv7-unknown-linux-gnueabihf

Compilação para RISC-V

# RISC-V 64-bit
rustup target add riscv64gc-unknown-linux-gnu

# Ubuntu 22.04+
sudo apt install -y gcc-riscv64-linux-gnu

cat >> .cargo/config.toml << 'EOF'
[target.riscv64gc-unknown-linux-gnu]
linker = "riscv64-linux-gnu-gcc"
EOF

cargo build --release --target riscv64gc-unknown-linux-gnu

WebAssembly (WASM)

O Rust tem suporte de primeira classe para WebAssembly:

wasm32-unknown-unknown (Navegador)

# Adicionar target
rustup target add wasm32-unknown-unknown

# Instalar wasm-pack (ferramenta essencial para WASM)
cargo install wasm-pack

# Compilar biblioteca para WASM
wasm-pack build --target web

wasm32-wasi (Server-side WASM)

rustup target add wasm32-wasi

cargo build --target wasm32-wasi

# Executar com wasmtime
cargo install wasmtime-cli
wasmtime target/wasm32-wasi/debug/meu-app.wasm

Exemplo: Função Rust para o Navegador

// src/lib.rs
use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub fn somar(a: i32, b: i32) -> i32 {
    a + b
}

#[wasm_bindgen]
pub fn saudacao(nome: &str) -> String {
    format!("Olá, {}! Bem-vindo ao Rust + WASM.", nome)
}
# Cargo.toml
[lib]
crate-type = ["cdylib"]

[dependencies]
wasm-bindgen = "0.2"
wasm-pack build --target web

Usando o Crate cross

O cross simplifica cross-compilation usando Docker:

cargo install cross

# Compilar para ARM sem configurar nada
cross build --release --target aarch64-unknown-linux-gnu

# Compilar para musl
cross build --release --target x86_64-unknown-linux-musl

# Compilar para Windows a partir do Linux
cross build --release --target x86_64-pc-windows-gnu

# Executar testes em outra plataforma (via QEMU)
cross test --target aarch64-unknown-linux-gnu

O cross usa imagens Docker pré-configuradas com os cross-compilers necessários. Funciona em qualquer máquina com Docker instalado.

Configuração do Cross (Cross.toml)

# Cross.toml
[target.aarch64-unknown-linux-gnu]
image = "ghcr.io/cross-rs/aarch64-unknown-linux-gnu:main"

[target.aarch64-unknown-linux-musl]
image = "ghcr.io/cross-rs/aarch64-unknown-linux-musl:main"

[build.env]
passthrough = ["RUST_LOG"]

Docker Cross Builds

Para builds multiplataforma com Docker:

# Dockerfile multi-arch
FROM --platform=$BUILDPLATFORM rust:1.83 AS builder

ARG TARGETPLATFORM
RUN case "$TARGETPLATFORM" in \
      "linux/amd64")  echo "x86_64-unknown-linux-musl" > /target ;; \
      "linux/arm64")  echo "aarch64-unknown-linux-musl" > /target ;; \
    esac

RUN rustup target add $(cat /target)

WORKDIR /app
COPY . .
RUN cargo build --release --target $(cat /target)
RUN cp target/$(cat /target)/release/meu-app /meu-app

FROM scratch
COPY --from=builder /meu-app /meu-app
ENTRYPOINT ["/meu-app"]
# Build para múltiplas arquiteturas
docker buildx build --platform linux/amd64,linux/arm64 -t meu-app .

Para mais padrões Docker, consulte o guia de Rust com Docker.

Compilação para macOS e Windows

De Linux para macOS

Cross-compilation para macOS requer o SDK da Apple, que não pode ser distribuído livremente. Use o osxcross:

# Instalar osxcross (requer SDK do macOS)
# Veja: https://github.com/tpoechtrager/osxcross

rustup target add x86_64-apple-darwin
rustup target add aarch64-apple-darwin

De Linux para Windows

rustup target add x86_64-pc-windows-gnu
sudo apt install -y gcc-mingw-w64-x86-64

cat >> .cargo/config.toml << 'EOF'
[target.x86_64-pc-windows-gnu]
linker = "x86_64-w64-mingw32-gcc"
EOF

cargo build --release --target x86_64-pc-windows-gnu

Configurar CI/CD para Cross-Compilation

Combine com o GitHub Actions para releases multiplataforma:

strategy:
  matrix:
    include:
      - target: x86_64-unknown-linux-gnu
        os: ubuntu-latest
      - target: aarch64-unknown-linux-gnu
        os: ubuntu-latest
      - target: x86_64-apple-darwin
        os: macos-latest
      - target: aarch64-apple-darwin
        os: macos-latest
      - target: x86_64-pc-windows-msvc
        os: windows-latest

Solução de Problemas

Erro: “linker not found” para o target

Instale o cross-compiler para a plataforma alvo ou use o cross:

# Mais simples: use cross
cargo install cross
cross build --target aarch64-unknown-linux-gnu

Erro: “linking with cc failed” para OpenSSL

Para targets que precisam de OpenSSL, use a crate openssl-sys com vendoring:

[dependencies]
openssl = { version = "0.10", features = ["vendored"] }

Build musl falha com dependências C

Instale as bibliotecas estáticas ou use vendoring nas dependências.

Próximos Passos

Com cross-compilation dominada:

Se você faz cross-compilation em Go, confira o golang.com.br para comparar a abordagem do GOOS/GOARCH com targets Rust.


Última atualização: 23 de fevereiro de 2026. Para gerenciar targets e toolchains, consulte o Guia Completo do Rustup.