Target Triple em Zig — O que é e Como Usar

Target Triple em Zig — O que é e Como Usar

Definição

Um target triple (tripla de destino) é uma string no formato arquitetura-sistema_operacional-abi que especifica a plataforma para a qual o código deve ser compilado. O Zig usa target triples para identificar o ambiente de execução do binário gerado — incluindo a CPU, o sistema operacional e a interface binária de aplicação (ABI).

Exemplos: x86_64-linux-gnu, aarch64-macos-none, arm-freestanding-none.

Por que Target Triples Importam

  1. Cross-compilation: Especificam exatamente para qual plataforma compilar.
  2. Portabilidade: O mesmo código Zig pode gerar binários para dezenas de plataformas.
  3. Reprodutibilidade: O target triple garante que o binário é idêntico em qualquer máquina de build.
  4. Condicionais de plataforma: O código pode usar @import("builtin") para tomar decisões baseadas no target.

Formato

<arquitetura>-<sistema_operacional>-<abi>
ComponenteExemplosDescrição
Arquiteturax86_64, aarch64, arm, riscv64, wasm32ISA do processador
Sistema Operacionallinux, macos, windows, freestandingSO do target
ABIgnu, musl, none, eabiInterface binária de aplicação

Exemplo Prático

Compilação com Target Triple

# Linux x86_64 com glibc
zig build-exe main.zig -target x86_64-linux-gnu

# Linux x86_64 com musl (binário estático)
zig build-exe main.zig -target x86_64-linux-musl

# macOS Apple Silicon
zig build-exe main.zig -target aarch64-macos-none

# Windows 64-bit
zig build-exe main.zig -target x86_64-windows-gnu

# ARM embarcado (sem SO)
zig build-exe main.zig -target thumb-freestanding-none

# WebAssembly
zig build-exe main.zig -target wasm32-wasi-none

Detectando o Target em Código

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

pub fn main() void {
    // Informações sobre o target em tempo de compilação
    std.debug.print("Arch: {s}\n", .{@tagName(builtin.cpu.arch)});
    std.debug.print("OS: {s}\n", .{@tagName(builtin.os.tag)});

    // Condicional de plataforma
    if (builtin.os.tag == .windows) {
        std.debug.print("Executando no Windows\n", .{});
    } else if (builtin.os.tag == .linux) {
        std.debug.print("Executando no Linux\n", .{});
    }
}

Listar Targets Disponíveis

# Listar todas as arquiteturas, SOs e ABIs suportados
zig targets | head -50

# O comando retorna JSON com todos os targets disponíveis

Targets Comuns

Target TripleUso
x86_64-linux-gnuDesktop/servidor Linux
x86_64-linux-muslLinux com binário estático
aarch64-linux-gnuLinux em ARM64 (Raspberry Pi 4, servidores ARM)
aarch64-macos-nonemacOS Apple Silicon
x86_64-macos-nonemacOS Intel
x86_64-windows-gnuWindows 64-bit
wasm32-freestanding-noneWebAssembly
arm-freestanding-noneMicrocontroladores ARM

Como o Target Triple se Relaciona com build.zig

No sistema de build, o target triple é configurado via standardTargetOptions, que expõe a flag -Dtarget para o usuário do zig build:

// Em build.zig
const target = b.standardTargetOptions(.{});

// O usuário passa o target assim:
// zig build -Dtarget=x86_64-linux-musl

Você também pode fixar o target diretamente no código, útil para projetos que sempre produzem um binário específico:

const target = b.resolveTargetQuery(.{
    .cpu_arch = .aarch64,
    .os_tag = .linux,
    .abi = .musl,
});

Boas Práticas

  • Use musl para distribuição Linux: Binários com x86_64-linux-musl rodam em qualquer distro Linux sem depender da versão da glibc instalada.
  • Teste o binário no target real ou em emulador: Compilar para ARM não garante que o código funciona — lógica de ponteiros, alinhamento e endianness podem diferir.
  • Use zig targets para descobrir targets válidos: O comando lista todas as combinações suportadas em JSON. Filtre com jq para encontrar arquiteturas específicas.
  • Documente os targets suportados: Em projetos de biblioteca, liste explicitamente quais targets foram testados, pois código com @cImport pode não funcionar em todos os targets.

Armadilhas Comuns

  • gnu vs musl: gnu usa glibc (dinâmico por padrão); musl gera binários estáticos. Para máxima portabilidade no Linux, use musl.
  • freestanding: Significa sem SO — para embarcados ou WebAssembly. Não tem acesso a syscalls do OS.
  • Target inválido: Nem toda combinação é válida. arm-windows-gnu pode não ser suportado.
  • Native: Omitir -target compila para a plataforma atual (native).
  • Endianness inesperada: Algumas arquiteturas como MIPS e PowerPC podem ser big-endian. Use builtin.cpu.arch.endian() para detectar e adaptar o código.
  • ABI freestanding e stdlib: Em targets freestanding, a biblioteca padrão Zig fica muito limitada — sem acesso a std.fs, std.net, e similares.

Termos Relacionados

Tutoriais Relacionados

Continue aprendendo Zig

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