Cross-Compilation em Zig — O que é e Como Usar

Cross-Compilation em Zig — O que é e Como Usar

Definição

Cross-compilation (compilação cruzada) é a capacidade de compilar código em uma máquina (host) para ser executado em uma plataforma diferente (target). Zig foi projetado desde o início para suportar cross-compilation de forma nativa, sem necessidade de instalar toolchains adicionais. Basta passar o flag -target para compilar para mais de 30 arquiteturas e sistemas operacionais.

Isso contrasta com C/C++, onde cross-compilation tipicamente exige instalar cross-toolchains específicas, configurar sysroots e lidar com incompatibilidades entre versões.

Por que Cross-Compilation Importa

  1. Desenvolvimento embarcado: Compilar para ARM, RISC-V ou MIPS diretamente do seu PC x86.
  2. Distribuição multiplataforma: Gerar binários para Linux, macOS e Windows a partir de uma única máquina.
  3. CI/CD simplificado: Build pipelines podem gerar todos os artefatos em uma única plataforma.
  4. Sem toolchains extras: O Zig já inclui tudo necessário para cross-compilation.

Exemplo Prático

Cross-Compilation Básica

# Compilar para Linux x86_64 (a partir de qualquer plataforma)
zig build-exe src/main.zig -target x86_64-linux-gnu

# Compilar para macOS ARM (Apple Silicon)
zig build-exe src/main.zig -target aarch64-macos

# Compilar para Windows x86_64
zig build-exe src/main.zig -target x86_64-windows-gnu

# Compilar para ARM embarcado (bare metal)
zig build-exe src/main.zig -target arm-freestanding-none

# Compilar para WebAssembly
zig build-exe src/main.zig -target wasm32-freestanding

Via build.zig

const std = @import("std");

pub fn build(b: *std.Build) void {
    // standardTargetOptions permite -Dtarget= na linha de comando
    const target = b.standardTargetOptions(.{});
    const optimize = b.standardOptimizeOption(.{});

    const exe = b.addExecutable(.{
        .name = "app",
        .root_source_file = b.path("src/main.zig"),
        .target = target,
        .optimize = optimize,
    });
    b.installArtifact(exe);
}

// Uso:
// zig build -Dtarget=aarch64-linux-gnu
// zig build -Dtarget=x86_64-windows-gnu -Doptimize=ReleaseFast

Código Condicional por Plataforma

const std = @import("std");
const builtin = @import("builtin");

pub fn main() void {
    const os_nome = switch (builtin.os.tag) {
        .linux => "Linux",
        .macos => "macOS",
        .windows => "Windows",
        .freestanding => "Bare Metal",
        else => "Outro",
    };

    const arch_nome = switch (builtin.cpu.arch) {
        .x86_64 => "x86_64",
        .aarch64 => "AArch64",
        .arm => "ARM",
        .riscv64 => "RISC-V 64",
        .wasm32 => "WebAssembly",
        else => "Outra",
    };

    std.debug.print("Plataforma: {s} / {s}\n", .{ os_nome, arch_nome });
}

Targets Suportados (Principais)

ArquiteturaSistemas
x86_64Linux, macOS, Windows, FreeBSD
aarch64Linux, macOS (Apple Silicon)
armLinux, freestanding (embarcado)
riscv64Linux, freestanding
wasm32freestanding, wasi
mipsLinux
powerpc64Linux

Armadilhas Comuns

  • ABI do sistema: -gnu e -musl produzem binários diferentes. Use -musl para binários estáticos portáveis no Linux.
  • Bibliotecas do sistema: Cross-compilation com linkSystemLibrary pode falhar se a biblioteca não estiver disponível para o target.
  • Paths do host: Cuidado ao usar caminhos absolutos em comptime — eles são do host, não do target.
  • Endianness: Algumas arquiteturas são big-endian. Código que assume little-endian pode ter bugs.
  • Testar no target: Compilar é metade do trabalho — teste o binário na plataforma-alvo.

Termos Relacionados

  • Target Triple — Formato de especificação de plataforma
  • build.zig — Configuração de cross-compilation no build
  • Release Modes — Otimizações por modo de build
  • LLVM — Backend que gera código para múltiplas arquiteturas

Tutoriais Relacionados

Continue aprendendo Zig

Explore mais tutoriais e artigos em português para dominar a linguagem Zig.