---
title: "Build System do Zig: Guia Completo do build.zig"
url: "https://ziglang.com.br/artigos/zig-build-system-guia/"
markdown_url: "https://ziglang.com.br/artigos/zig-build-system-guia.MD"
description: "Domine o build.zig: steps, opções, dependências com build.zig.zon, compilação condicional e integração com projetos C/C++. Guia prático com exemplos."
date: "2026-03-29"
author: ""
---

# Build System do Zig: Guia Completo do build.zig

Domine o build.zig: steps, opções, dependências com build.zig.zon, compilação condicional e integração com projetos C/C++. Guia prático com exemplos.


# Build System do Zig: Guia Completo do build.zig

O build system de Zig é único — em vez de arquivos declarativos como Makefiles ou CMakeLists.txt, você escreve a lógica de build em **Zig puro**. Isso significa que tem acesso a toda a expressividade da linguagem: condicionais, loops, [comptime](/artigos/comptime-zig-metaprogramacao/) e até chamadas de rede, tudo dentro do build script.

Neste guia, vamos explorar o `build.zig` em profundidade: desde a estrutura básica até dependências externas com `build.zig.zon`, steps customizados e integração com projetos C/C++.

> Se é novo em Zig, comece com [Por que aprender Zig](/artigos/por-que-aprender-zig/) e o [cheatsheet do build system](/cheatsheets/build-system/).

## Estrutura Básica do build.zig

Todo projeto Zig começa com um `build.zig` na raiz:

```zig
const std = @import("std");

pub fn build(b: *std.Build) void {
    // Opções padrão de target e otimização
    const target = b.standardTargetOptions(.{});
    const optimize = b.standardOptimizeOption(.{});

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

    // Instalar o artefato
    b.installArtifact(exe);

    // Step de "run" para executar o programa
    const run_cmd = b.addRunArtifact(exe);
    run_cmd.step.dependOn(b.getInstallStep());

    const run_step = b.step("run", "Executar o aplicativo");
    run_step.dependOn(&run_cmd.step);
}
```

Execute com:

```bash
zig build        # Compila
zig build run    # Compila e executa
zig build -Doptimize=ReleaseFast  # Build otimizado
```

> O `standardTargetOptions` é o que habilita a poderosa [cross-compilation do Zig](/artigos/zig-cross-compilation-guia/) — basta passar `-Dtarget=aarch64-linux`.

## Steps: O Grafo de Build

O build system funciona como um **grafo direcionado acíclico (DAG)** de steps. Cada step pode depender de outros, e o Zig executa apenas o que é necessário:

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

    // Step 1: Compilar a lib
    const lib = b.addStaticLibrary(.{
        .name = "minha-lib",
        .root_source_file = b.path("src/lib.zig"),
        .target = target,
        .optimize = optimize,
    });

    // Step 2: Compilar o executável (depende da lib)
    const exe = b.addExecutable(.{
        .name = "meu-app",
        .root_source_file = b.path("src/main.zig"),
        .target = target,
        .optimize = optimize,
    });
    exe.linkLibrary(lib);

    // Step 3: Testes unitários
    const unit_tests = b.addTest(.{
        .root_source_file = b.path("src/lib.zig"),
        .target = target,
        .optimize = optimize,
    });
    const run_tests = b.addRunArtifact(unit_tests);

    // Steps acessíveis pela CLI
    b.installArtifact(exe);

    const test_step = b.step("test", "Rodar testes unitários");
    test_step.dependOn(&run_tests.step);

    const run_step = b.step("run", "Executar o app");
    const run_exe = b.addRunArtifact(exe);
    run_exe.step.dependOn(b.getInstallStep());
    run_step.dependOn(&run_exe.step);
}
```

Agora `zig build test` roda testes e `zig build run` executa. Cada step só compila o necessário — muito mais rápido que Makefiles tradicionais.

> Para mais sobre testes, veja o [guia completo de testes em Zig](/artigos/zig-testes-guia-completo/).

## Build Options: Configuração Flexível

Defina opções customizáveis via CLI para compilação condicional:

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

    // Opção booleana
    const enable_logging = b.option(
        bool,
        "enable-logging",
        "Habilitar logs detalhados",
    ) orelse false;

    // Opção de enum
    const Backend = enum { sqlite, postgres, mysql };
    const backend = b.option(
        Backend,
        "backend",
        "Selecionar backend de banco de dados",
    ) orelse .sqlite;

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

    // Passar opções para o código via build options
    const options = b.addOptions();
    options.addOption(bool, "enable_logging", enable_logging);
    options.addOption(Backend, "backend", backend);
    exe.root_module.addOptions("config", options);

    b.installArtifact(exe);
}
```

No código Zig:

```zig
// src/main.zig
const config = @import("config");

pub fn main() void {
    if (config.enable_logging) {
        // Logs detalhados habilitados
        std.debug.print("Logging ativado\n", .{});
    }

    switch (config.backend) {
        .sqlite => initSqlite(),
        .postgres => initPostgres(),
        .mysql => initMysql(),
    }
}
```

Use na CLI:

```bash
zig build -Denable-logging=true -Dbackend=postgres
```

Isso substitui o `#ifdef` do C e os feature flags do Cargo (Rust) — tudo resolvido em [comptime](/glossario/comptime/) com type safety. Se você vem de <a href="https://python.dev.br/" target="_blank" rel="noopener" onclick="umami.track('portfolio-site-click', { destination: 'python.dev.br' })">Python</a>, pense nas build options como variáveis de ambiente do `setup.py`, mas com verificação em tempo de compilação.

## Dependências com build.zig.zon

O `build.zig.zon` é o gerenciador de pacotes do Zig. Diferente do `go.mod` ou `Cargo.toml`, usa a sintaxe ZON (Zig Object Notation):

```zig
// build.zig.zon
.{
    .name = "meu-projeto",
    .version = "0.1.0",
    .dependencies = .{
        .zap = .{
            .url = "https://github.com/zigzap/zap/archive/refs/tags/v0.7.0.tar.gz",
            .hash = "1220aabff7e77a3a21e46738bd8e4016e8d0347ae0b5a8f6e3e5e68b1f42a1e35c3f",
        },
        .clap = .{
            .url = "https://github.com/Hejsil/zig-clap/archive/refs/tags/0.8.0.tar.gz",
            .hash = "122062d301569d9b5288ac2ea13c24ca7b3f41398cba2f41d73947f7a5e624e78b49",
        },
    },
    .paths = .{"."},
}
```

> Para detalhes sobre ZON, veja o [glossário de zon](/glossario/zon/) e o [package manager do Zig](/ecossistema/zig-pkg-manager/).

Depois, use as dependências no `build.zig`:

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

    // Buscar dependência
    const zap = b.dependency("zap", .{
        .target = target,
        .optimize = optimize,
    });

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

    // Adicionar módulo da dependência
    exe.root_module.addImport("zap", zap.module("zap"));

    b.installArtifact(exe);
}
```

Para adicionar uma dependência:

```bash
zig fetch --save https://github.com/zigzap/zap/archive/refs/tags/v0.7.0.tar.gz
```

Saiba mais sobre `zig fetch` no [glossário](/glossario/zig-fetch/).

## Integração com Projetos C/C++

O build system brilha na [interoperabilidade com C](/artigos/zig-interoperabilidade-c/). Você pode compilar código C/C++ diretamente:

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

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

    // Compilar arquivos C junto com Zig
    exe.addCSourceFiles(.{
        .files = &.{
            "vendor/utils.c",
            "vendor/parser.c",
        },
        .flags = &.{
            "-std=c11",
            "-Wall",
            "-Wextra",
            "-O2",
        },
    });

    // Adicionar include paths
    exe.addIncludePath(b.path("vendor/include"));

    // Linkar com bibliotecas do sistema
    exe.linkSystemLibrary("pthread");
    exe.linkLibC();

    b.installArtifact(exe);
}
```

Isso torna o Zig uma **alternativa ao GCC/Clang como compilador C** — muitos projetos usam `zig cc` como drop-in replacement. Veja como isso se aplica na [migração de projetos C para Zig](/artigos/migrar-projeto-c-para-zig/).

## Steps Customizados

Crie steps que executam scripts, geram código ou fazem validações:

```zig
pub fn build(b: *std.Build) void {
    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);

    // Step customizado: gerar documentação
    const docs_step = b.step("docs", "Gerar documentação");
    const docs_cmd = b.addSystemCommand(&.{
        "zig", "doc", "src/lib.zig",
    });
    docs_step.dependOn(&docs_cmd.step);

    // Step customizado: limpar artefatos
    const clean_step = b.step("clean", "Limpar build artifacts");
    const clean_cmd = b.addRemoveDirTree(b.path("zig-out"));
    clean_step.dependOn(&clean_cmd.step);

    // Step de benchmark
    const bench = b.addExecutable(.{
        .name = "bench",
        .root_source_file = b.path("src/bench.zig"),
        .target = target,
        .optimize = .ReleaseFast,
    });
    const bench_run = b.addRunArtifact(bench);
    const bench_step = b.step("bench", "Rodar benchmarks");
    bench_step.dependOn(&bench_run.step);
}
```

Agora:

```bash
zig build docs    # Gera documentação
zig build clean   # Limpa artefatos
zig build bench   # Roda benchmarks
```

## Compilação Condicional por Plataforma

O build system tem acesso completo às informações do target:

```zig
pub fn build(b: *std.Build) void {
    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,
    });

    // Linking condicional por OS
    if (target.result.os.tag == .linux) {
        exe.linkSystemLibrary("io_uring");
    } else if (target.result.os.tag == .macos) {
        exe.linkFramework("CoreFoundation");
    } else if (target.result.os.tag == .windows) {
        exe.linkSystemLibrary("ws2_32");
    }

    // Arquivo fonte condicional
    if (target.result.cpu.arch == .aarch64) {
        exe.addCSourceFile(.{
            .file = b.path("src/neon_simd.c"),
            .flags = &.{},
        });
    }

    b.installArtifact(exe);
}
```

Isso é muito mais legível que os `#ifdef _WIN32` do C ou condicionais complexas em CMake. Para SIMD especificamente, veja nosso [guia de SIMD em Zig](/artigos/zig-simd-processamento-vetorial/).

> Para comparação, o sistema de build do Go (`go build`) é mais simples mas menos flexível. Saiba mais em <a href="https://golang.com.br/" target="_blank" rel="noopener" onclick="umami.track('portfolio-site-click', { destination: 'golang.com.br' })">golang.com.br</a>. Já o Cargo do Rust oferece features semelhantes — explore em <a href="https://rustlang.com.br/" target="_blank" rel="noopener" onclick="umami.track('portfolio-site-click', { destination: 'rustlang.com.br' })">rustlang.com.br</a>.

## Múltiplos Artefatos

Projetos maiores produzem vários binários e bibliotecas:

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

    // Biblioteca compartilhada
    const lib = b.addSharedLibrary(.{
        .name = "minha-lib",
        .root_source_file = b.path("src/lib.zig"),
        .target = target,
        .optimize = optimize,
    });
    b.installArtifact(lib);

    // Biblioteca estática
    const static_lib = b.addStaticLibrary(.{
        .name = "minha-lib",
        .root_source_file = b.path("src/lib.zig"),
        .target = target,
        .optimize = optimize,
    });
    b.installArtifact(static_lib);

    // Executável CLI
    const cli = b.addExecutable(.{
        .name = "minha-cli",
        .root_source_file = b.path("src/cli.zig"),
        .target = target,
        .optimize = optimize,
    });
    cli.linkLibrary(static_lib);
    b.installArtifact(cli);

    // Servidor
    const server = b.addExecutable(.{
        .name = "meu-servidor",
        .root_source_file = b.path("src/server.zig"),
        .target = target,
        .optimize = optimize,
    });
    server.linkLibrary(static_lib);
    b.installArtifact(server);
}
```

## Dicas e Boas Práticas

1. **Use `standardTargetOptions` e `standardOptimizeOption`** — habilitam flags padrão de CLI
2. **Separe lib e exe** — facilita testes e reutilização
3. **Documente seus steps** — a descrição aparece em `zig build --help`
4. **Use `build.zig.zon` para dependências** — não faça git submodules
5. **Teste o build para múltiplos targets** — aproveite a [cross-compilation](/glossario/cross-compilation/)
6. **Use [release modes](/glossario/release-modes/)** adequados — `ReleaseFast` para performance, `ReleaseSafe` para produção com safety checks

> Para ferramentas de debug e profiling, veja o [ecossistema de debug tools](/ecossistema/zig-debug-tools/) e [profiling](/ecossistema/zig-profiling-tools/).

## Conclusão

O build system do Zig é poderoso porque é **código Zig real** — não uma DSL limitada. Você define targets, options, steps e dependências com a mesma linguagem que escreve seu software. Combinado com a [interoperabilidade C nativa](/artigos/zig-interoperabilidade-c/) e o gerenciamento de pacotes via `build.zig.zon`, é uma das experiências de build mais coesas do ecossistema de linguagens de sistemas.

Para se aprofundar, explore o [overview do build system](/ecossistema/zig-build-system-overview/), o [glossário de build.zig](/glossario/build-zig/) e o [cheatsheet do build system](/cheatsheets/build-system/). E se está planejando sua carreira com Zig, confira o [roadmap de desenvolvedor](/carreira/roadmap-desenvolvedor-zig/) e as [ferramentas de produtividade](/artigos/zig-devtools-produtividade/).
