zig build em Zig — O que é e Como Usar
Definição
zig build é o comando principal do sistema de build integrado do Zig. Ele compila e executa o arquivo build.zig do projeto para determinar quais artefatos gerar, quais testes rodar e quais dependências resolver. Diferente de ferramentas como Make ou CMake, o sistema de build do Zig é parte da própria toolchain e usa a linguagem Zig para configuração.
Por que zig build Importa
- Tudo em um: Compilação, testes, instalação e execução em um único sistema.
- Portável: Funciona identicamente em qualquer plataforma onde Zig está instalado.
- Cross-compilation: Basta passar
-Dtarget=para compilar para outra plataforma. - Reprodutível: O mesmo
build.zig+build.zig.zonproduz o mesmo resultado.
Exemplo Prático
Comandos Básicos
# Compilar o projeto (gera artefatos em zig-out/)
zig build
# Compilar e executar
zig build run
# Executar testes
zig build test
# Listar todos os steps disponíveis
zig build --help
Cross-Compilation
# Compilar para Linux x86_64
zig build -Dtarget=x86_64-linux-gnu
# Compilar para macOS ARM
zig build -Dtarget=aarch64-macos
# Compilar para Windows
zig build -Dtarget=x86_64-windows-gnu
# Build otimizado
zig build -Doptimize=ReleaseFast
build.zig Mínimo para Entender o Fluxo
const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
// Step "build" — compilar o executável
const exe = b.addExecutable(.{
.name = "app",
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});
b.installArtifact(exe);
// Step "run" — executar o programa
const run = b.addRunArtifact(exe);
run.step.dependOn(b.getInstallStep());
if (b.args) |args| {
run.addArgs(args);
}
b.step("run", "Executar o aplicativo").dependOn(&run.step);
// Step "test" — rodar testes
const testes = b.addTest(.{
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});
b.step("test", "Rodar testes").dependOn(&b.addRunArtifact(testes).step);
}
Opções Comuns
| Opção | Descrição |
|---|---|
-Dtarget=TRIPLA | Definir plataforma-alvo |
-Doptimize=MODO | Modo de otimização (Debug, ReleaseSafe, ReleaseFast, ReleaseSmall) |
--help | Listar steps e opções disponíveis |
-j N | Número de jobs paralelos |
--verbose | Mostrar comandos executados |
-- ARGS | Passar argumentos ao programa (com step “run”) |
Armadilhas Comuns
- Sem build.zig: O comando falha se não houver
build.zigno diretório atual ou ancestral. - Cache agressivo: O Zig faz cache de compilação. Use
zig build --summary allpara verificar o que foi recompilado. - Argumentos do programa: Para passar argumentos ao executável, use
zig build run -- arg1 arg2. - Diretório de saída: Artefatos ficam em
zig-out/. Este diretório deve estar no.gitignore.
Termos Relacionados
- build.zig — Arquivo de configuração do build
- build.zig.zon — Manifesto de dependências
- zig test — Comando para executar testes
- Cross-Compilation — Compilar para outra plataforma
- Release Modes — Modos de otimização
- Target Triple — Especificação de plataforma
Steps Personalizados
O sistema de build do Zig permite criar steps customizados para tarefas arbitrárias — geração de código, execução de ferramentas externas, publicação de artefatos, etc. Cada step pode depender de outros, formando um grafo de dependências que o zig build executa em ordem.
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",
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});
b.installArtifact(exe);
// Step de linting/formatação personalizado
const fmt_step = b.step("fmt", "Formatar código-fonte");
const fmt = b.addFmt(.{ .paths = &.{"src"} });
fmt_step.dependOn(&fmt.step);
// Step de documentação
const docs_step = b.step("docs", "Gerar documentação");
const docs = b.addInstallDirectory(.{
.source_dir = exe.getEmittedDocs(),
.install_dir = .prefix,
.install_subdir = "docs",
});
docs_step.dependOn(&docs.step);
}
Comparação com Make e CMake
Diferente do Make, o build.zig é tipado e verificado em tempo de compilação — não há strings mágicas ou erros de sintaxe difíceis de depurar. Diferente do CMake, o sistema de build usa a mesma linguagem que o código-fonte, eliminando a necessidade de aprender uma DSL separada. O resultado é um sistema de build que é ao mesmo tempo poderoso e familiar para quem já sabe Zig.
Além disso, o sistema de build do Zig tem cross-compilation integrada de verdade. Em CMake, cross-compilar requer toolchain files complexos. Em Zig, basta -Dtarget=aarch64-linux-musl e o compilador cuida do resto — incluindo a libc.
Modos de Otimização
# Debug (padrão): sem otimizações, checks de segurança habilitados
zig build
# ReleaseSafe: com otimizações, checks de segurança mantidos
zig build -Doptimize=ReleaseSafe
# ReleaseFast: otimizações máximas, sem checks de segurança
zig build -Doptimize=ReleaseFast
# ReleaseSmall: otimizado para menor tamanho binário
zig build -Doptimize=ReleaseSmall
Para distribuição, ReleaseSafe é geralmente a melhor escolha — oferece performance próxima de ReleaseFast com a segurança de detectar comportamento indefinido em produção.