---
title: "Cross-Compilation com Zig: Compile para Qualquer Plataforma"
url: "https://ziglang.com.br/tutoriais/zig-cross-compilation/"
markdown_url: "https://ziglang.com.br/tutoriais/zig-cross-compilation.MD"
description: "Aprenda a usar cross-compilation em Zig para compilar para Linux, Windows, macOS, ARM e mais de 30 alvos diferentes."
date: "2026-02-20"
author: "Zig Brasil"
---

# Cross-Compilation com Zig: Compile para Qualquer Plataforma

Aprenda a usar cross-compilation em Zig para compilar para Linux, Windows, macOS, ARM e mais de 30 alvos diferentes.


Uma das capacidades mais impressionantes da **zig lang** é a cross-compilation embutida. Enquanto outras linguagens exigem toolchains complexas para compilar para plataformas diferentes, a **linguagem Zig** permite compilar para mais de 30 alvos diferentes com um único comando, sem instalar nada extra. Neste tutorial, vamos explorar como usar esse recurso poderoso na prática.

## O Que é Cross-Compilation

Cross-compilation (compilação cruzada) é o processo de compilar código em uma plataforma para ser executado em outra. Por exemplo, você está no macOS e quer gerar um executável para Linux, ou está no Linux e precisa de um binário para Windows.

Cenários comuns onde cross-compilation é essencial:

- **Distribuição de software**: Gerar binários para todas as plataformas dos seus usuários a partir de uma única máquina de desenvolvimento.
- **Sistemas embarcados**: Compilar para ARM, RISC-V ou outros processadores a partir do seu desktop x86.
- **CI/CD**: Construir releases multiplataforma em um pipeline de integração contínua.
- **Servidores**: Compilar no seu Mac para deploy em servidores Linux.

## A Vantagem Única do Zig

Em C e C++, cross-compilation é notoriamente difícil. Você precisa instalar toolchains específicas, configurar sysroots, encontrar headers e bibliotecas para a plataforma alvo, e lidar com incompatibilidades. Com Zig, tudo isso é desnecessário.

Zig inclui no próprio compilador:

- **Linker embutido**: Não depende de linkers externos.
- **Headers C da libc**: Para todas as plataformas suportadas.
- **Backend LLVM**: Gera código nativo otimizado para qualquer alvo.
- **Sem dependências externas**: Um único binário do Zig é tudo que você precisa.

## Listando Alvos Disponíveis

Para ver todos os alvos que Zig suporta, use o comando:

```bash
zig targets
```

Esse comando retorna um JSON extenso com todas as combinações de CPU e sistema operacional. Os alvos mais comuns incluem:

| Alvo | Descrição |
|---|---|
| `x86_64-linux` | Linux 64-bit (servidores, desktops) |
| `x86_64-windows` | Windows 64-bit |
| `x86_64-macos` | macOS Intel |
| `aarch64-linux` | Linux ARM 64-bit (Raspberry Pi 4, servidores ARM) |
| `aarch64-macos` | macOS Apple Silicon (M1/M2/M3) |
| `wasm32-freestanding` | WebAssembly |
| `arm-linux-gnueabihf` | Linux ARM 32-bit (Raspberry Pi antigo) |
| `riscv64-linux` | Linux RISC-V 64-bit |

Para filtrar rapidamente os alvos disponíveis:

```bash
zig targets | python3 -c "import sys,json; t=json.load(sys.stdin); print('\n'.join(t['arch']))"
```

## Compilação Cruzada na Prática

Vamos criar um programa simples e compilá-lo para diferentes plataformas.

```zig
// main.zig
const std = @import("std");
const builtin = @import("builtin");

pub fn main() !void {
    const stdout = std.io.getStdOut().writer();

    try stdout.print("Olá do Zig!\n", .{});
    try stdout.print("Arquitetura: {s}\n", .{@tagName(builtin.cpu.arch)});
    try stdout.print("Sistema: {s}\n", .{@tagName(builtin.os.tag)});
    try stdout.print("Tamanho do ponteiro: {} bytes\n", .{@sizeOf(usize)});
}
```

Agora, compile para diferentes alvos a partir de qualquer plataforma:

### Compilar para Linux x86_64

```bash
zig build-exe main.zig -target x86_64-linux
```

### Compilar para Windows x86_64

```bash
zig build-exe main.zig -target x86_64-windows
```

Isso gera um arquivo `.exe` que pode ser executado diretamente no Windows, sem precisar de nenhuma ferramenta do Windows instalada.

### Compilar para macOS ARM (Apple Silicon)

```bash
zig build-exe main.zig -target aarch64-macos
```

### Compilar para Raspberry Pi (ARM Linux)

```bash
zig build-exe main.zig -target aarch64-linux
```

Para Raspberry Pi mais antigos (32-bit):

```bash
zig build-exe main.zig -target arm-linux-gnueabihf
```

### Compilar com Otimização

Para builds de release, adicione a flag de otimização:

```bash
zig build-exe main.zig -target x86_64-linux -O ReleaseSmall
zig build-exe main.zig -target x86_64-linux -O ReleaseFast
zig build-exe main.zig -target x86_64-linux -O ReleaseSafe
```

| Modo | Descrição |
|---|---|
| `Debug` | Padrão. Informações de debug, sem otimização |
| `ReleaseSafe` | Otimizado, mantém verificações de segurança |
| `ReleaseFast` | Máxima performance, remove verificações |
| `ReleaseSmall` | Menor binário possível |

## Cross-Compilation com o Build System

Para projetos maiores, use o `build.zig` para configurar cross-compilation de forma programática. Se você ainda não conhece o build system, veja o tutorial [Zig Build System: Guia Completo](/tutoriais/zig-build-system/).

```zig
// build.zig
const std = @import("std");

pub fn build(b: *std.Build) void {
    // Permite que o usuário escolha o alvo via linha de comando
    const target = b.standardTargetOptions(.{});
    const optimize = b.standardOptimizeOption(.{});

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

    b.installArtifact(exe);
}
```

Agora você pode compilar para qualquer alvo:

```bash
zig build -Dtarget=x86_64-linux -Doptimize=ReleaseFast
zig build -Dtarget=x86_64-windows -Doptimize=ReleaseSmall
zig build -Dtarget=aarch64-macos -Doptimize=ReleaseFast
```

### Build para Múltiplos Alvos

Você pode criar um step personalizado que compila para todos os alvos de uma vez:

```zig
// build.zig
const std = @import("std");

const alvos = [_]std.Target.Query{
    .{ .cpu_arch = .x86_64, .os_tag = .linux },
    .{ .cpu_arch = .x86_64, .os_tag = .windows },
    .{ .cpu_arch = .aarch64, .os_tag = .linux },
    .{ .cpu_arch = .aarch64, .os_tag = .macos },
};

pub fn build(b: *std.Build) void {
    const optimize = b.standardOptimizeOption(.{});

    for (alvos) |t| {
        const nome = std.fmt.allocPrint(b.allocator, "meu-app-{s}-{s}", .{
            @tagName(t.cpu_arch.?),
            @tagName(t.os_tag.?),
        }) catch "meu-app";

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

        b.installArtifact(exe);
    }
}
```

Execute com:
```bash
zig build -Doptimize=ReleaseFast
```

Isso gera quatro binários no diretório `zig-out/bin/`, um para cada plataforma.

## Zig como Cross-Compiler C: `zig cc`

Uma das funcionalidades mais revolucionárias do Zig é poder ser usado como um compilador C cross-platform, substituindo `gcc` ou `clang`.

### Compilando C com `zig cc`

```c
// hello.c
#include <stdio.h>

int main() {
    printf("Hello from C, compiled with Zig!\n");
    return 0;
}
```

```bash
# Compilar para a plataforma local
zig cc hello.c -o hello

# Cross-compilar para Linux
zig cc hello.c -o hello-linux -target x86_64-linux-gnu

# Cross-compilar para Windows
zig cc hello.c -o hello.exe -target x86_64-windows-gnu

# Cross-compilar para ARM
zig cc hello.c -o hello-arm -target aarch64-linux-gnu
```

### Usando `zig cc` como Drop-in Replacement

Muitos projetos C usam Makefiles ou CMake. Você pode substituir o compilador por `zig cc` sem alterar nada no projeto:

```bash
# Com Make
CC="zig cc" make

# Com CMake
cmake -DCMAKE_C_COMPILER="zig cc" -DCMAKE_CXX_COMPILER="zig c++" ..

# Com autotools/configure
CC="zig cc" CXX="zig c++" ./configure --host=aarch64-linux-gnu
```

Isso é especialmente útil para compilar bibliotecas C/C++ que seu projeto Zig vai consumir via `@cImport`. Para saber mais sobre como integrar código C, consulte o tutorial de [interoperabilidade C em Zig](/tutoriais/zig-c-interoperabilidade/).

### Exemplo Prático: Compilar SQLite para ARM

```bash
# Baixar o código-fonte do SQLite
curl -O https://www.sqlite.org/2024/sqlite-amalgamation-3450000.zip
unzip sqlite-amalgamation-3450000.zip
cd sqlite-amalgamation-3450000

# Compilar para ARM Linux
zig cc -O2 shell.c sqlite3.c -o sqlite3-arm \
    -target aarch64-linux-gnu \
    -lpthread -ldl -lm
```

Isso gera um binário SQLite funcional para ARM Linux, compilado no seu desktop x86.

## CI/CD: GitHub Actions Multiplataforma

Uma aplicação prática muito comum de cross-compilation é gerar releases para múltiplas plataformas no CI/CD.

### Workflow do GitHub Actions

```yaml
# .github/workflows/release.yml
name: Release Multiplataforma

on:
  push:
    tags: ['v*']

jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        target:
          - x86_64-linux
          - x86_64-windows
          - aarch64-linux
          - aarch64-macos
          - x86_64-macos

    steps:
      - uses: actions/checkout@v4

      - name: Instalar Zig
        uses: goto-bus-stop/setup-zig@v2
        with:
          version: 0.13.0

      - name: Compilar
        run: zig build -Dtarget=${{ matrix.target }} -Doptimize=ReleaseFast

      - name: Upload Artefato
        uses: actions/upload-artifact@v4
        with:
          name: build-${{ matrix.target }}
          path: zig-out/bin/

  release:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/download-artifact@v4

      - name: Criar Release
        uses: softprops/action-gh-release@v1
        with:
          files: build-*/meu-app*
```

Com esse workflow, cada tag `v*` gera automaticamente binários para cinco plataformas, tudo em runners Linux. Não é necessário usar macOS runners para compilar para macOS ou Windows runners para compilar para Windows.

### Script de Release Local

Para criar releases localmente sem CI/CD:

```bash
#!/bin/bash
# release.sh
VERSION=$1
TARGETS=(
    "x86_64-linux"
    "x86_64-windows"
    "aarch64-linux"
    "aarch64-macos"
    "x86_64-macos"
)

mkdir -p releases/$VERSION

for TARGET in "${TARGETS[@]}"; do
    echo "Compilando para $TARGET..."
    zig build -Dtarget=$TARGET -Doptimize=ReleaseFast

    # Copiar binário com nome descritivo
    cp zig-out/bin/meu-app* "releases/$VERSION/meu-app-$TARGET"
done

echo "Binários gerados em releases/$VERSION/"
ls -la releases/$VERSION/
```

## Linkagem Estática vs Dinâmica

Por padrão, Zig produz binários com linkagem estática da musl libc no Linux, resultando em executáveis portáteis que rodam em qualquer distribuição.

```bash
# Linkagem estática (padrão no Linux com musl)
zig build-exe main.zig -target x86_64-linux-musl

# Linkagem dinâmica (usa glibc do sistema)
zig build-exe main.zig -target x86_64-linux-gnu
```

A vantagem da linkagem estática com musl é que o binário resultante não tem nenhuma dependência externa. Você pode copiar o executável para qualquer máquina Linux e ele simplesmente funciona, sem se preocupar com versões de glibc.

```bash
# Verificar dependências do binário
file meu-app
# meu-app: ELF 64-bit LSB executable, x86-64, statically linked

ldd meu-app
# not a dynamic executable (é estático!)
```

## Cross-Compilation de Projetos Mistos (Zig + C)

Zig se integra perfeitamente com código C, e a cross-compilation funciona igualmente bem para projetos mistos.

```zig
// build.zig para projeto Zig + C
const std = @import("std");

pub fn build(b: *std.Build) void {
    const target = b.standardTargetOptions(.{});
    const optimize = b.standardOptimizeOption(.{});

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

    // Adicionar código-fonte C
    exe.addCSourceFiles(.{
        .files = &.{
            "vendor/sqlite3.c",
            "vendor/miniz.c",
        },
        .flags = &.{
            "-DSQLITE_OMIT_LOAD_EXTENSION",
            "-O2",
        },
    });

    // Adicionar diretório de includes
    exe.addIncludePath(b.path("vendor/"));

    // Linkar biblioteca do sistema
    exe.linkLibC();

    b.installArtifact(exe);
}
```

Agora, `zig build -Dtarget=aarch64-linux` compila tanto o código Zig quanto o código C para ARM, tudo de uma vez.

## Verificando o Binário Gerado

Após a cross-compilation, é útil verificar se o binário foi gerado corretamente:

```bash
# Verificar o tipo do arquivo
file meu-app
# meu-app: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV)

# Verificar o tamanho
ls -lh meu-app

# Para Windows, verificar com file também
file meu-app.exe
# meu-app.exe: PE32+ executable (console) x86-64, for MS Windows
```

## Dicas e Boas Práticas

1. **Teste em emuladores**: Use QEMU para testar binários ARM no seu desktop x86: `qemu-aarch64 ./meu-app-arm`.
2. **Use Docker para validação**: Teste binários Linux em containers Docker para garantir compatibilidade.
3. **Cuidado com syscalls específicas**: Algumas chamadas de sistema são específicas de uma plataforma. Use `builtin.os.tag` para condicionais de plataforma.
4. **Prefira musl para distribuição**: Binários estáticos com musl são mais portáteis que glibc dinâmico.
5. **Automatize no CI**: Configure cross-compilation no GitHub Actions para gerar releases automaticamente.

```zig
// Código condicional por plataforma
const std = @import("std");
const builtin = @import("builtin");

pub fn obterDiretorioConfig() []const u8 {
    return switch (builtin.os.tag) {
        .windows => "C:\\ProgramData\\MeuApp",
        .macos => "/Library/Application Support/MeuApp",
        .linux => "/etc/meuapp",
        else => "/tmp/meuapp",
    };
}
```

## Conclusão

A cross-compilation embutida é um dos maiores trunfos do Zig. Em vez de configurar toolchains complexas ou depender de containers Docker para compilar para outras plataformas, Zig resolve tudo com um único binário e uma flag `-target`. Seja para distribuir software multiplataforma, compilar para sistemas embarcados ou otimizar pipelines de CI/CD, a capacidade de cross-compilation do Zig transforma tarefas que costumavam ser dolorosas em operações triviais.

## Leia Também

- [Zig Build System: Guia Completo](/tutoriais/zig-build-system)
- [Zig para Programadores C: Guia de Transição](/tutoriais/zig-para-programadores-c)
- [Como Instalar Zig: Guia Passo a Passo](/tutoriais/como-instalar-zig)
