Cross-Compile Falha em Zig — Resolver Erros de Compilação Cruzada

Cross-Compile Falha em Zig — Resolver Erros de Compilação Cruzada

Uma das grandes vantagens do Zig é a cross-compilation nativa. Quando ela falha, geralmente há uma causa específica e solucionável. Este guia cobre os problemas mais comuns.

Erro: “unknown target”

Causa: O target especificado não é reconhecido pelo Zig.

Solução:

# Listar todos os targets disponíveis
zig targets | head -100

# Formato correto: arch-os-abi
zig build -Dtarget=aarch64-linux-gnu       # Linux ARM64
zig build -Dtarget=x86_64-windows-msvc     # Windows x64
zig build -Dtarget=x86_64-macos-none       # macOS x64
zig build -Dtarget=wasm32-freestanding-none # WASM

Verifique a lista completa com zig targets e use o formato exato arch-os-abi.

Erro: “unable to find libc”

Causa: O target requer libc mas os headers não estão disponíveis.

Solução:

// No build.zig — linkar libc explicitamente
exe.linkLibC();

// Ou usar a libc bundled do Zig
// Zig inclui headers de libc para a maioria dos targets
# Verificar se o target tem libc bundled
zig build -Dtarget=aarch64-linux-gnu
# Zig inclui headers glibc para Linux

# Para targets sem libc bundled, pode ser necessário:
zig build -Dtarget=aarch64-linux-musl  # musl é frequentemente mais fácil

Erro: “missing system library”

Causa: Seu código depende de bibliotecas do sistema que não existem no target.

Solução:

// PROBLEMA: biblioteca do sistema não disponível para o target
exe.linkSystemLibrary("openssl");

// SOLUÇÃO 1: Compilar a dependência como parte do build
exe.addCSourceFiles(.{
    .files = &.{ "vendor/openssl/ssl.c" },
});

// SOLUÇÃO 2: Usar alternativa pura Zig
// Exemplo: std.crypto em vez de OpenSSL

// SOLUÇÃO 3: Condicional por target
const target = b.standardTargetOptions(.{});
if (target.result.os.tag == .linux) {
    exe.linkSystemLibrary("rt");
}

Erro: Headers C Não Encontrados

Causa: @cImport usa headers específicos da plataforma host, não do target.

Solução:

// No build.zig — especificar caminhos de headers
exe.addIncludePath(b.path("include/cross"));

// Ou usar headers específicos por plataforma
const target_os = target.result.os.tag;
if (target_os == .windows) {
    exe.addIncludePath(b.path("include/win32"));
} else if (target_os == .macos) {
    exe.addIncludePath(b.path("include/macos"));
}

Problema: Binário Não Executa no Target

Causa: Linkagem dinâmica com bibliotecas que não existem no sistema alvo.

# Verificar dependências do binário
# No Linux:
ldd ./meu-app

# SOLUÇÃO: Compilar com linkagem estática
// No build.zig — forçar linkagem estática
exe.linkage = .static;

// Ou usar musl para Linux (sempre estático)
// zig build -Dtarget=x86_64-linux-musl

Problema: WASM Cross-Compilation

# Compilar para WASM
zig build -Dtarget=wasm32-freestanding

# Se usar libc:
zig build -Dtarget=wasm32-wasi  # WASI inclui libc mínima
// No build.zig para WASM
const exe = b.addExecutable(.{
    .name = "app",
    .root_source_file = b.path("src/main.zig"),
    .target = b.resolveTargetQuery(.{
        .cpu_arch = .wasm32,
        .os_tag = .freestanding,
    }),
});

// Exportar funções para JavaScript
exe.export_symbol_names = &.{"processar"};

Problema: macOS Cross-Compilation

# Compilar PARA macOS a partir de Linux/Windows
zig build -Dtarget=x86_64-macos
zig build -Dtarget=aarch64-macos  # Apple Silicon

# Problemas comuns:
# - Frameworks do sistema (Cocoa, Metal) não estão disponíveis
# - Code signing é necessário para executar em macOS real

Para aplicações que usam frameworks Apple, cross-compilation pura não é suficiente. Considere usar CI com runners macOS.

Problema: Windows Cross-Compilation

# Compilar PARA Windows a partir de Linux/macOS
zig build -Dtarget=x86_64-windows

# Gerar .exe e .pdb (debug symbols)
zig build -Dtarget=x86_64-windows -Doptimize=ReleaseSafe
// Código condicional por plataforma
const builtin = @import("builtin");

const separador = if (builtin.os.tag == .windows) '\\' else '/';

Diagnóstico de Cross-Compilation

# Ver detalhes do que o compilador está fazendo
zig build -Dtarget=aarch64-linux --verbose

# Verificar o target que está sendo usado
zig build -Dtarget=aarch64-linux --verbose 2>&1 | grep target

# Listar targets suportados com filtro
zig targets 2>&1 | python3 -c "import sys,json; print('\n'.join(json.load(sys.stdin)['arch']))"

Checklist para Cross-Compilation

  1. Verifique se o target está correto: arch-os-abi
  2. Use linkLibC() se precisar de libc
  3. Prefira musl sobre glibc para Linux (mais portável)
  4. Use linkagem estática quando possível
  5. Evite dependências de sistema (linkSystemLibrary) em cross-compilation
  6. Teste o binário no target real ou em um emulador (QEMU)

Veja Também

Continue aprendendo Zig

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