---
title: "Zig Build System: Guia Completo do build.zig | Zig Brasil"
url: "https://ziglang.com.br/tutoriais/zig-build-system/"
markdown_url: "https://ziglang.com.br/tutoriais/zig-build-system.MD"
description: "Domine o Zig Build System com este guia prático. Cross-compilation, dependências, integração C e exemplos reais do build.zig. Tutorial em português."
date: "2026-02-09"
author: ""
---

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

Domine o Zig Build System com este guia prático. Cross-compilation, dependências, integração C e exemplos reais do build.zig. Tutorial em português.


O Zig Build System é uma das features mais poderosas da linguagem Zig. Diferente de C e C++ que dependem de ferramentas externas como Make, CMake, Autotools ou Meson, **Zig vem com um sistema de build integrado**, escrito na própria linguagem. Isso significa que você usa Zig para configurar como Zig compila seu projeto — sem DSLs, sem dependências externas, sem "mágica".

Neste tutorial completo, você vai aprender tudo sobre o `build.zig`: desde a estrutura básica até cenários avançados como cross-compilation, integração com C e build steps customizados.

> **Pré-requisito:** Ter o Zig instalado. Se ainda não instalou, siga nosso [Guia de Instalação do Zig](/tutoriais/como-instalar-zig/).

## O que é o Zig Build System? Por que Não Usar Make/CMake?

### O Problema dos Build Systems Tradicionais

Se você vem de C ou C++, provavelmente já sofreu com ferramentas de build:

| Ferramenta | Problema |
|---|---|
| **Make** | Sintaxe arcaica, tabs obrigatórios, difícil de portar entre plataformas |
| **CMake** | Linguagem própria (CMakeLists.txt) complexa e verbosa |
| **Autotools** | Configure/Makefile.am — extremamente complexo |
| **Meson** | Dependência de Python, outra DSL para aprender |
| **Bazel** | Pesado, complexo, curva de aprendizado íngreme |

Todos esses sistemas compartilham um problema fundamental: **são ferramentas separadas da linguagem**, com suas próprias linguagens de configuração, bugs e limitações.

### A Solução do Zig

O Zig Build System resolve isso de forma elegante:

- **Escrito em Zig** — é código Zig normal, não uma DSL
- **Integrado ao compilador** — nenhuma ferramenta externa necessária
- **Cross-compilation nativa** — compila para qualquer plataforma sem configuração extra
- **Cache inteligente** — recompila apenas o que mudou
- **Execução concorrente** — build steps rodam em paralelo automaticamente
- **Compila C/C++ também** — substitui gcc/clang como compilador C/C++

```
# Sem Zig: você precisa de TUDO isso
sudo apt install build-essential cmake autotools-dev python3-meson ninja-build

# Com Zig: uma única ferramenta
zig build
```

## Anatomia do build.zig — Estrutura Básica

O `build.zig` é um arquivo Zig normal com uma função pública especial chamada `build`. O Zig Build System chama essa função passando um ponteiro `*std.Build` que permite configurar o processo de compilação.

### Estrutura Mínima

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

pub fn build(b: *std.Build) void {
    // Aqui você configura como o projeto é compilado
    const exe = b.addExecutable(.{
        .name = "meu-programa",
        .root_module = b.createModule(.{
            .root_source_file = b.path("src/main.zig"),
            .target = b.graph.host,
        }),
    });

    b.installArtifact(exe);
}
```

Vamos decompor cada parte:

| Elemento | Descrição |
|---|---|
| `pub fn build(b: *std.Build)` | Ponto de entrada do build system |
| `b.addExecutable(...)` | Cria um executável |
| `.name = "meu-programa"` | Nome do binário resultante |
| `b.createModule(...)` | Cria um módulo de compilação |
| `.root_source_file = b.path("src/main.zig")` | Arquivo raiz do código |
| `.target = b.graph.host` | Compilar para a máquina atual |
| `b.installArtifact(exe)` | Registra o executável para instalação |

### Como o Build System Funciona

O Zig Build System é baseado em um **DAG (Directed Acyclic Graph)** — um grafo direcionado acíclico de "steps" (etapas):

```
install (step padrão)
└─ install meu-programa
   └─ compile exe meu-programa
```

Quando você executa `zig build`, o build runner:

1. Executa a função `build()` para construir o grafo
2. Resolve dependências entre steps
3. Executa steps concorrentemente respeitando as dependências
4. Usa cache para evitar recompilação desnecessária

### Diretórios Gerados

Após `zig build`, dois diretórios são criados:

```
meu-projeto/
├── build.zig          # Configuração do build
├── src/
│   └── main.zig       # Seu código
├── .zig-cache/        # Cache de compilação (NÃO commitar)
└── zig-out/           # Artefatos de saída
    └── bin/
        └── meu-programa
```

| Diretório | Propósito | Git? |
|---|---|---|
| `.zig-cache/` | Cache de compilação (intermediários) | ❌ Adicionar ao .gitignore |
| `zig-out/` | Binários e artefatos finais | ❌ Adicionar ao .gitignore |

## Criando um Projeto do Zero com `zig init`

A forma mais rápida de criar um projeto Zig é usar `zig init`:

```bash
mkdir meu-projeto && cd meu-projeto
zig init
```

Saída:

```
info: created build.zig
info: created build.zig.zon
info: created src/main.zig
info: created src/root.zig
info: see `zig build --help` for a menu of options
```

### Estrutura Gerada

```
meu-projeto/
├── build.zig          # Configuração do build system
├── build.zig.zon      # Metadados do pacote (nome, versão, deps)
└── src/
    ├── main.zig       # Ponto de entrada do executável
    └── root.zig       # Ponto de entrada da biblioteca
```

### O build.zig Gerado

O `zig init` cria um `build.zig` completo com as práticas recomendadas:

```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(.{});

    // Biblioteca
    const lib = b.addLibrary(.{
        .name = "meu-projeto",
        .linkage = .static,
        .root_module = b.createModule(.{
            .root_source_file = b.path("src/root.zig"),
            .target = target,
            .optimize = optimize,
        }),
    });
    b.installArtifact(lib);

    // Executável
    const exe = b.addExecutable(.{
        .name = "meu-projeto",
        .root_module = b.createModule(.{
            .root_source_file = b.path("src/main.zig"),
            .target = target,
            .optimize = optimize,
        }),
    });
    b.installArtifact(exe);

    // Step "run"
    const run_cmd = b.addRunArtifact(exe);
    run_cmd.step.dependOn(b.getInstallStep());
    if (b.args) |args| {
        run_cmd.addArgs(args);
    }
    const run_step = b.step("run", "Run the application");
    run_step.dependOn(&run_cmd.step);

    // Step "test"
    const lib_unit_tests = b.addTest(.{
        .root_module = b.createModule(.{
            .root_source_file = b.path("src/root.zig"),
            .target = target,
            .optimize = optimize,
        }),
    });
    const run_lib_unit_tests = b.addRunArtifact(lib_unit_tests);

    const exe_unit_tests = b.addTest(.{
        .root_module = b.createModule(.{
            .root_source_file = b.path("src/main.zig"),
            .target = target,
            .optimize = optimize,
        }),
    });
    const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests);

    const test_step = b.step("test", "Run unit tests");
    test_step.dependOn(&run_lib_unit_tests.step);
    test_step.dependOn(&run_exe_unit_tests.step);
}
```

### Comandos Básicos

Com o projeto criado, você pode usar:

```bash
# Compilar
zig build

# Compilar e executar
zig build run

# Rodar testes (veja nosso guia de [testes em Zig](/tutoriais/testes-zig/))
zig build test

# Ver sumário detalhado
zig build --summary all

# Ver opções disponíveis
zig build --help

# Passar argumentos para o programa
zig build run -- arg1 arg2

# Limpar cache
rm -rf .zig-cache zig-out
```

### O build.zig.zon

O arquivo `build.zig.zon` (Zig Object Notation) contém metadados do projeto:

```zig
.{
    .name = .@"meu-projeto",
    .version = "0.1.0",
    .fingerprint = 0x...,  // hash automático
    .minimum_zig_version = "0.15.0",
    .dependencies = .{},
    .paths = .{
        "build.zig",
        "build.zig.zon",
        "src",
    },
}
```

| Campo | Descrição |
|---|---|
| `.name` | Nome do pacote |
| `.version` | Versão semântica |
| `.fingerprint` | Hash único do pacote (gerado automaticamente) |
| `.minimum_zig_version` | Versão mínima do Zig necessária |
| `.dependencies` | Dependências externas |
| `.paths` | Arquivos incluídos no pacote |

## Configurando Targets e Modos de Build

### Standard Options

As funções `standardTargetOptions` e `standardOptimizeOption` expõem opções na linha de comando:

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

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

    b.installArtifact(exe);
}
```

Agora o usuário pode configurar target e otimização via `-D`:

```bash
# Build padrão (debug, máquina local)
zig build

# Release otimizado para velocidade
zig build -Doptimize=ReleaseFast

# Release otimizado para tamanho
zig build -Doptimize=ReleaseSmall

# Release seguro (checks em runtime)
zig build -Doptimize=ReleaseSafe

# Cross-compile para Windows
zig build -Dtarget=x86_64-windows

# Cross-compile para ARM Linux
zig build -Dtarget=aarch64-linux-gnu
```

### Modos de Otimização

| Modo | Descrição | Checks de Segurança | Velocidade | Tamanho |
|---|---|---|---|---|
| `Debug` | Padrão para desenvolvimento | ✅ Todos ativos | Normal | Grande |
| `ReleaseSafe` | Release com segurança | ✅ Todos ativos | Alta | Médio |
| `ReleaseFast` | Máxima velocidade | ❌ Desativados | Máxima | Médio |
| `ReleaseSmall` | Binário mínimo | ❌ Desativados | Alta | Mínimo |

### Opções Customizadas

Você pode criar opções personalizadas com `b.option`:

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

    // Opção booleana customizada
    const enable_logging = b.option(
        bool,
        "logging",
        "Habilitar logging detalhado",
    ) orelse false;

    // Opção de string customizada
    const versao = b.option(
        []const u8,
        "version",
        "Versão do aplicativo",
    ) orelse "0.1.0";

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

    // Passar opções para o código via @import("config")
    const options = b.addOptions();
    options.addOption(bool, "logging_enabled", enable_logging);
    options.addOption([]const u8, "version", versao);
    exe.root_module.addOptions("config", options);

    b.installArtifact(exe);
}
```

No código Zig, acesse as opções:

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

pub fn main() !void {
    if (config.logging_enabled) {
        std.debug.print("Versão: {s}\n", .{config.version});
    }
}
```

Uso na linha de comando:

```bash
zig build -Dlogging=true -Dversion=1.0.0
```

## Adicionando Dependências (Packages)

O sistema de pacotes do Zig usa o `build.zig.zon` para declarar dependências.

### Adicionando uma Dependência com `zig fetch`

O comando `zig fetch --save` é a forma mais fácil de adicionar uma dependência:

```bash
# Sintaxe: zig fetch --save <url-do-tarball>
zig fetch --save https://github.com/zigtools/zls/archive/refs/tags/0.13.0.tar.gz
```

Isso atualiza automaticamente o `build.zig.zon`:

```zig
.{
    .name = .@"meu-projeto",
    .version = "0.1.0",
    .dependencies = .{
        .zls = .{
            .url = "https://github.com/zigtools/zls/archive/refs/tags/0.13.0.tar.gz",
            .hash = "1220abc123...",  // hash de integridade
        },
    },
    .paths = .{
        "build.zig",
        "build.zig.zon",
        "src",
    },
}
```

### Usando a Dependência no build.zig

Após declarar a dependência no `build.zig.zon`, use-a no `build.zig`:

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

    // Obter a dependência
    const dep = b.dependency("nome-do-pacote", .{
        .target = target,
        .optimize = optimize,
    });

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

    // Adicionar o módulo da dependência
    exe.root_module.addImport("nome-do-modulo", dep.module("nome-do-modulo"));

    b.installArtifact(exe);
}
```

### Exemplo Prático: Adicionando uma Biblioteca de Logging

Vamos adicionar a biblioteca `logz` como exemplo:

**1. Buscar a dependência:**

```bash
zig fetch --save git+https://github.com/chung-leong/logz
```

**2. Configurar no build.zig:**

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

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

    // Importar a dependência logz
    const logz = b.dependency("logz", .{
        .target = target,
        .optimize = optimize,
    });
    exe.root_module.addImport("logz", logz.module("logz"));

    b.installArtifact(exe);
}
```

**3. Usar no código:**

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

pub fn main() !void {
    var logger = logz.Logger.init(.{});
    logger.info("Aplicação iniciada", .{});
}
```

### Dependências Locais (Path)

Para dependências em disco (monorepos, desenvolvimento local):

```zig
// build.zig.zon
.{
    .name = .@"meu-projeto",
    .version = "0.1.0",
    .dependencies = .{
        .minha_lib = .{
            .path = "../minha-lib",
        },
    },
    .paths = .{
        "build.zig",
        "build.zig.zon",
        "src",
    },
}
```

## Cross-Compilation — Compilar para Outras Plataformas

Uma das maiores forças do Zig é a **cross-compilation trivial**. Enquanto em C/C++ configurar cross-compilation pode levar horas (ou dias), com Zig é um flag. Para um guia aprofundado, veja nosso tutorial dedicado de [cross-compilation com Zig](/tutoriais/zig-cross-compilation/).

### Compilar para Outra Plataforma

```bash
# Compilar para Windows (a partir de Linux/macOS)
zig build -Dtarget=x86_64-windows

# Compilar para Linux ARM (Raspberry Pi)
zig build -Dtarget=aarch64-linux-gnu

# Compilar para macOS Intel (a partir de ARM)
zig build -Dtarget=x86_64-macos

# Compilar para macOS ARM (Apple Silicon)
zig build -Dtarget=aarch64-macos

# Compilar para WebAssembly
zig build -Dtarget=wasm32-wasi

# Compilar para FreeBSD
zig build -Dtarget=x86_64-freebsd
```

### Targets Disponíveis

Para ver todos os targets suportados:

```bash
# Listar arquiteturas suportadas
zig targets | head -50

# Ou usar zig build-exe diretamente
zig build-exe --help | grep "target"
```

Alguns targets populares:

| Target | Descrição |
|---|---|
| `x86_64-linux-gnu` | Linux 64-bit (glibc) |
| `x86_64-linux-musl` | Linux 64-bit (musl libc, estático) |
| `aarch64-linux-gnu` | Linux ARM 64-bit (Raspberry Pi 4+) |
| `x86_64-windows` | Windows 64-bit |
| `aarch64-macos` | macOS Apple Silicon |
| `x86_64-macos` | macOS Intel |
| `wasm32-wasi` | WebAssembly (WASI) |
| `riscv64-linux-gnu` | Linux RISC-V 64-bit |

### Build para Múltiplos Targets (Release)

Para projetos que precisam distribuir binários para várias plataformas, crie um step customizado:

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

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

    // Targets para os quais queremos compilar
    const targets: []const std.Target.Query = &.{
        .{ .cpu_arch = .x86_64, .os_tag = .linux, .abi = .gnu },
        .{ .cpu_arch = .x86_64, .os_tag = .linux, .abi = .musl },
        .{ .cpu_arch = .aarch64, .os_tag = .linux, .abi = .gnu },
        .{ .cpu_arch = .x86_64, .os_tag = .windows },
        .{ .cpu_arch = .aarch64, .os_tag = .macos },
        .{ .cpu_arch = .x86_64, .os_tag = .macos },
    };

    // Step "release" que compila para todos os targets
    const release_step = b.step("release", "Build para todas as plataformas");

    for (targets) |t| {
        const exe = b.addExecutable(.{
            .name = "meu-app",
            .root_module = b.createModule(.{
                .root_source_file = b.path("src/main.zig"),
                .target = b.resolveTargetQuery(t),
                .optimize = optimize,
            }),
        });

        const install = b.addInstallArtifact(exe, .{});
        release_step.dependOn(&install.step);
    }
}
```

Uso:

```bash
# Build release para todas as plataformas de uma vez
zig build release -Doptimize=ReleaseFast --summary all
```

Saída:

```
zig-out/
└── bin/
    ├── meu-app              # Linux x86_64 (glibc)
    ├── meu-app              # Linux x86_64 (musl)
    ├── meu-app              # Linux ARM64
    ├── meu-app.exe          # Windows x86_64
    └── meu-app              # macOS (2 variantes)
```

### Zig como Compilador C/C++ Cross-Platform

O `zig cc` funciona como um **drop-in replacement** para gcc/clang, com cross-compilation embutida:

```bash
# Compilar C para a máquina local
zig cc -o programa main.c

# Compilar C para ARM Linux (a partir de qualquer plataforma!)
zig cc -target aarch64-linux-gnu -o programa main.c

# Compilar C++ para Windows
zig c++ -target x86_64-windows -o programa.exe main.cpp
```

Isso é tão poderoso que empresas como **Uber** usam `zig cc` apenas como compilador C/C++ cross-platform, sem nem escrever código Zig.

## Integrando Bibliotecas C no Build

Uma das maiores vantagens do Zig é a integração transparente com código C. O `build.zig` permite compilar e linkar código C diretamente.

### Exemplo 1: Compilar Código C com Zig

Suponha que temos um arquivo C simples:

**`src/mathutils.c`:**
```c
#include "mathutils.h"

int soma(int a, int b) {
    return a + b;
}

double raiz_quadrada(double x) {
    return __builtin_sqrt(x);
}
```

**`src/mathutils.h`:**
```c
#ifndef MATHUTILS_H
#define MATHUTILS_H

int soma(int a, int b);
double raiz_quadrada(double x);

#endif
```

**`build.zig`:**
```zig
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_module = b.createModule(.{
            .root_source_file = b.path("src/main.zig"),
            .target = target,
            .optimize = optimize,
            .link_libc = true,
        }),
    });

    // Adicionar código C
    exe.addCSourceFile(.{
        .file = b.path("src/mathutils.c"),
        .flags = &.{ "-std=c11", "-Wall" },
    });

    // Adicionar diretório de headers
    exe.addIncludePath(b.path("src"));

    b.installArtifact(exe);
}
```

**`src/main.zig`** — chamando o código C:
```zig
const c = @cImport({
    @cInclude("mathutils.h");
});
const std = @import("std");

pub fn main() void {
    const resultado = c.soma(10, 20);
    std.debug.print("10 + 20 = {d}\n", .{resultado});

    const raiz = c.raiz_quadrada(144.0);
    std.debug.print("sqrt(144) = {d}\n", .{raiz});
}
```

### Exemplo 2: Linkar com Biblioteca do Sistema

Para usar bibliotecas instaladas no sistema (como zlib, OpenSSL, SQLite):

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

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

    const exe = b.addExecutable(.{
        .name = "compressor",
        .root_module = b.createModule(.{
            .root_source_file = b.path("src/main.zig"),
            .target = target,
            .optimize = optimize,
        }),
    });

    // Linkar com zlib do sistema
    exe.linkSystemLibrary("z");

    // Linkar com a libc (necessário para libs do sistema)
    exe.linkLibC();

    b.installArtifact(exe);
}
```

No código Zig:

```zig
const c = @cImport({
    @cInclude("zlib.h");
});
const std = @import("std");

pub fn main() void {
    // Usa funções da zlib diretamente
    const version = c.zlibVersion();
    std.debug.print("zlib versão: {s}\n", .{
        std.mem.span(version),
    });
}
```

### Exemplo 3: Múltiplos Arquivos C

Para projetos com vários arquivos C:

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

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

    const exe = b.addExecutable(.{
        .name = "projeto-misto",
        .root_module = b.createModule(.{
            .root_source_file = b.path("src/main.zig"),
            .target = target,
            .optimize = optimize,
            .link_libc = true,
        }),
    });

    // Adicionar múltiplos arquivos C de uma vez
    exe.addCSourceFiles(.{
        .files = &.{
            "src/parser.c",
            "src/lexer.c",
            "src/utils.c",
        },
        .flags = &.{
            "-std=c11",
            "-Wall",
            "-Wextra",
            "-O2",
        },
    });

    exe.addIncludePath(b.path("include"));

    b.installArtifact(exe);
}
```

### Exemplo 4: Biblioteca Estática C

Criar uma biblioteca estática que mistura C e Zig:

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

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

    // Criar biblioteca estática
    const lib = b.addLibrary(.{
        .name = "minha-lib",
        .linkage = .static,
        .root_module = b.createModule(.{
            .root_source_file = b.path("src/lib.zig"),
            .target = target,
            .optimize = optimize,
            .link_libc = true,
        }),
    });

    // Adicionar código C à biblioteca
    lib.addCSourceFile(.{
        .file = b.path("src/backend.c"),
        .flags = &.{"-std=c11"},
    });

    lib.addIncludePath(b.path("include"));

    // Instalar a biblioteca e headers
    b.installArtifact(lib);
    lib.installHeader(b.path("include/minha-lib.h"), "minha-lib.h");
}
```

> Para um tutorial completo sobre interoperabilidade Zig-C, leia [Zig para Programadores C: Guia de Migração](/tutoriais/zig-para-programadores-c/).

## Build Steps Customizados

O poder real do Zig Build System aparece quando você cria steps customizados para tarefas como geração de código, processamento de assets ou execução de ferramentas.

### Adicionando um Step "run"

O step mais comum é adicionar um comando `run` para executar o programa compilado:

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

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

    // Step "run" — executa o programa compilado
    const run_cmd = b.addRunArtifact(exe);
    run_cmd.step.dependOn(b.getInstallStep());

    // Permitir passar argumentos via linha de comando
    if (b.args) |args| {
        run_cmd.addArgs(args);
    }

    const run_step = b.step("run", "Executar a aplicação");
    run_step.dependOn(&run_cmd.step);
}
```

```bash
# Executa o programa
zig build run

# Passa argumentos
zig build run -- --porta 8080 --verbose
```

### Executando Ferramentas do Sistema

Você pode executar qualquer ferramenta do sistema como um build step:

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

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

    // Step para gerar documentação
    const docs = b.addSystemCommand(&.{
        "echo", "Gerando documentação...",
    });
    const doc_step = b.step("docs", "Gerar documentação");
    doc_step.dependOn(&docs.step);

    // Step para formatar código
    const fmt = b.addSystemCommand(&.{
        "zig", "fmt", "src/",
    });
    const fmt_step = b.step("fmt", "Formatar código Zig");
    fmt_step.dependOn(&fmt.step);
}
```

### Executando Ferramentas Escritas em Zig

Para ferramentas mais complexas, você pode compilar e executar uma ferramenta Zig como parte do build:

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

    // Ferramenta de geração de código (compilada em Zig)
    const codegen = b.addExecutable(.{
        .name = "codegen",
        .root_module = b.createModule(.{
            .root_source_file = b.path("tools/codegen.zig"),
            .target = b.graph.host,  // roda na máquina de build
        }),
    });

    // Executar a ferramenta para gerar um arquivo
    const codegen_step = b.addRunArtifact(codegen);
    codegen_step.addArg("--input-file");
    codegen_step.addFileArg(b.path("schema/api.json"));
    codegen_step.addArg("--output-file");
    const generated = codegen_step.addOutputFileArg("generated_api.zig");

    // Usar o arquivo gerado no executável principal
    const exe = b.addExecutable(.{
        .name = "app",
        .root_module = b.createModule(.{
            .root_source_file = b.path("src/main.zig"),
            .target = target,
            .optimize = optimize,
        }),
    });

    // O código gerado fica disponível via @import("api")
    exe.root_module.addAnonymousImport("api", .{
        .root_source_file = generated,
    });

    b.installArtifact(exe);
}
```

### Gerando Arquivos com `@embedFile`

Embutir arquivos gerados no binário em tempo de compilação:

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

    // Gerar um arquivo de versão
    const wf = b.addWriteFiles();
    _ = wf.add("version.txt", b.option(
        []const u8,
        "version",
        "Versão do aplicativo",
    ) orelse "dev");

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

    // Disponibilizar para @embedFile
    exe.root_module.addAnonymousImport("version", .{
        .root_source_file = wf.files.items[0].getPath(),
    });

    b.installArtifact(exe);
}
```

No código:

```zig
const version = @embedFile("version");

pub fn main() void {
    std.debug.print("Versão: {s}\n", .{version});
}
```

## Exemplos Práticos

### Exemplo 1: Projeto com Testes Completos

Um projeto real com testes de unidade para múltiplos módulos:

**Estrutura:**
```
meu-projeto/
├── build.zig
├── build.zig.zon
├── src/
│   ├── main.zig
│   ├── parser.zig
│   ├── lexer.zig
│   └── utils.zig
└── tests/
    ├── parser_test.zig
    └── lexer_test.zig
```

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

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

    // Módulo compartilhado
    const meu_modulo = b.createModule(.{
        .root_source_file = b.path("src/parser.zig"),
        .target = target,
        .optimize = optimize,
    });

    // === Executável ===
    const exe = b.addExecutable(.{
        .name = "meu-parser",
        .root_module = b.createModule(.{
            .root_source_file = b.path("src/main.zig"),
            .target = target,
            .optimize = optimize,
        }),
    });
    exe.root_module.addImport("parser", meu_modulo);
    b.installArtifact(exe);

    // === Step "run" ===
    const run_cmd = b.addRunArtifact(exe);
    run_cmd.step.dependOn(b.getInstallStep());
    if (b.args) |args| run_cmd.addArgs(args);
    const run_step = b.step("run", "Executar o parser");
    run_step.dependOn(&run_cmd.step);

    // === Testes ===
    const test_step = b.step("test", "Rodar todos os testes");

    // Testes do parser
    const parser_tests = b.addTest(.{
        .root_module = b.createModule(.{
            .root_source_file = b.path("tests/parser_test.zig"),
            .target = target,
            .optimize = optimize,
        }),
    });
    parser_tests.root_module.addImport("parser", meu_modulo);
    const run_parser_tests = b.addRunArtifact(parser_tests);
    test_step.dependOn(&run_parser_tests.step);

    // Testes do lexer
    const lexer_tests = b.addTest(.{
        .root_module = b.createModule(.{
            .root_source_file = b.path("tests/lexer_test.zig"),
            .target = target,
            .optimize = optimize,
        }),
    });
    const run_lexer_tests = b.addRunArtifact(lexer_tests);
    test_step.dependOn(&run_lexer_tests.step);

    // Testes inline no código-fonte
    const src_tests = b.addTest(.{
        .root_module = b.createModule(.{
            .root_source_file = b.path("src/parser.zig"),
            .target = target,
            .optimize = optimize,
        }),
    });
    const run_src_tests = b.addRunArtifact(src_tests);
    test_step.dependOn(&run_src_tests.step);
}
```

Uso:

```bash
# Rodar todos os testes
zig build test --summary all

# Saída esperada:
# Build Summary: 7/7 steps succeeded
# test success
# ├─ run test (parser_test) success
# ├─ run test (lexer_test) success
# └─ run test (parser inline) success
```

### Exemplo 2: Servidor HTTP com Múltiplos Targets

Um projeto mais realista: servidor HTTP com build para várias plataformas + Docker:

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

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

    // === Executável principal ===
    const exe = b.addExecutable(.{
        .name = "servidor",
        .root_module = b.createModule(.{
            .root_source_file = b.path("src/main.zig"),
            .target = target,
            .optimize = optimize,
        }),
    });
    b.installArtifact(exe);

    // === Step "run" ===
    const run_cmd = b.addRunArtifact(exe);
    run_cmd.step.dependOn(b.getInstallStep());
    if (b.args) |args| run_cmd.addArgs(args);
    const run_step = b.step("run", "Iniciar o servidor");
    run_step.dependOn(&run_cmd.step);

    // === Step "test" ===
    const unit_tests = b.addTest(.{
        .root_module = b.createModule(.{
            .root_source_file = b.path("src/main.zig"),
            .target = target,
            .optimize = optimize,
        }),
    });
    const run_tests = b.addRunArtifact(unit_tests);
    const test_step = b.step("test", "Rodar testes unitários");
    test_step.dependOn(&run_tests.step);

    // === Step "release" — build para múltiplas plataformas ===
    const release_targets: []const std.Target.Query = &.{
        .{ .cpu_arch = .x86_64, .os_tag = .linux, .abi = .musl },
        .{ .cpu_arch = .aarch64, .os_tag = .linux, .abi = .musl },
        .{ .cpu_arch = .x86_64, .os_tag = .macos },
        .{ .cpu_arch = .aarch64, .os_tag = .macos },
        .{ .cpu_arch = .x86_64, .os_tag = .windows },
    };

    const release_step = b.step("release", "Build para todas as plataformas");

    for (release_targets) |t| {
        const rel_exe = b.addExecutable(.{
            .name = "servidor",
            .root_module = b.createModule(.{
                .root_source_file = b.path("src/main.zig"),
                .target = b.resolveTargetQuery(t),
                .optimize = .ReleaseSafe,
            }),
        });
        const install = b.addInstallArtifact(rel_exe, .{});
        release_step.dependOn(&install.step);
    }

    // === Step "docker" — compilar para Linux musl (container Alpine) ===
    const docker_exe = b.addExecutable(.{
        .name = "servidor",
        .root_module = b.createModule(.{
            .root_source_file = b.path("src/main.zig"),
            .target = b.resolveTargetQuery(.{
                .cpu_arch = .x86_64,
                .os_tag = .linux,
                .abi = .musl,
            }),
            .optimize = .ReleaseSafe,
        }),
    });
    const docker_install = b.addInstallArtifact(docker_exe, .{});
    const docker_step = b.step("docker", "Build para container Docker (Linux musl)");
    docker_step.dependOn(&docker_install.step);
}
```

Uso:

```bash
# Desenvolvimento local
zig build run

# Testes
zig build test

# Build para Docker (binário estático Linux)
zig build docker --summary all

# Release para todas as plataformas
zig build release --summary all

# Ver todas as opções disponíveis
zig build --help
```

### Exemplo 3: Projeto Misto Zig + C com Dependência Externa

Um projeto que mistura Zig e C, com uma dependência externa:

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

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

    // Dependência externa (declarada no build.zig.zon)
    const clap = b.dependency("clap", .{
        .target = target,
        .optimize = optimize,
    });

    // Executável principal
    const exe = b.addExecutable(.{
        .name = "ferramenta",
        .root_module = b.createModule(.{
            .root_source_file = b.path("src/main.zig"),
            .target = target,
            .optimize = optimize,
            .link_libc = true,
        }),
    });

    // Adicionar dependência Zig
    exe.root_module.addImport("clap", clap.module("clap"));

    // Adicionar código C
    exe.addCSourceFiles(.{
        .files = &.{"src/legacy/processador.c"},
        .flags = &.{"-std=c11"},
    });
    exe.addIncludePath(b.path("src/legacy"));

    // Linkar com SQLite do sistema
    exe.linkSystemLibrary("sqlite3");

    b.installArtifact(exe);

    // Steps run e test...
    const run_cmd = b.addRunArtifact(exe);
    run_cmd.step.dependOn(b.getInstallStep());
    if (b.args) |args| run_cmd.addArgs(args);

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

## Dicas e Boas Práticas

### 1. Sempre Use `standardTargetOptions` e `standardOptimizeOption`

Isso dá flexibilidade ao usuário do seu projeto:

```zig
// ✅ Bom — flexível
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});

// ❌ Ruim — hardcoded
.target = b.graph.host,
// sem opção de otimização
```

### 2. Adicione `--summary all` ao Desenvolvimento

```bash
# Ver o que o build system fez
zig build --summary all

# Saída típica:
# Build Summary: 5/5 steps succeeded
# install success
# └─ install app success
#    └─ compile exe app Debug native success 1s MaxRSS:136M
```

### 3. Use `--watch` para Recompilação Automática

```bash
# Recompila automaticamente quando arquivos mudam
zig build --watch
```

### 4. Configure o `.gitignore`

```gitignore
# Zig build artifacts
.zig-cache/
zig-out/
```

### 5. Separe Build Steps por Responsabilidade

```zig
pub fn build(b: *std.Build) void {
    // Steps claramente separados:
    // - "run" — executar em desenvolvimento
    // - "test" — rodar testes
    // - "release" — build de produção
    // - "docker" — build para containers
    // - "docs" — gerar documentação
    // - "fmt" — formatar código
    // - "bench" — rodar benchmarks
}
```

### 6. Documente Suas Opções

```bash
# Qualquer opção definida com b.option() aparece no --help
zig build --help

# Project-Specific Options:
#   -Dlogging=[bool]     Habilitar logging detalhado
#   -Dversion=[string]   Versão do aplicativo
#   -Dport=[u16]         Porta do servidor (default: 8080)
```

### 7. Referência Rápida de Comandos

| Comando | Descrição |
|---|---|
| `zig init` | Criar projeto novo |
| `zig build` | Compilar |
| `zig build run` | Compilar e executar |
| `zig build test` | Rodar testes |
| `zig build --summary all` | Build com sumário detalhado |
| `zig build --watch` | Recompilação automática |
| `zig build --help` | Ver opções disponíveis |
| `zig build -Dtarget=...` | Cross-compilation |
| `zig build -Doptimize=...` | Selecionar modo de otimização |
| `zig fetch --save <url>` | Adicionar dependência |
| `zig build --fetch` | Baixar dependências |

### 8. Erros Comuns e Soluções

| Erro | Causa | Solução |
|---|---|---|
| `FileNotFound: src/main.zig` | Arquivo fonte não existe | Verificar caminho em `b.path()` |
| `error: DependencyNotFound` | Dependência não baixada | Executar `zig build --fetch` |
| `error: LibCNotFound` | libc não encontrada | Adicionar `.link_libc = true` ao módulo ou `exe.linkLibC()` |
| Compilação lenta | Cache corrompido | Remover `.zig-cache/` e recompilar |
| Cross-compile falha com libc | Biblioteca do sistema não disponível para target | Usar `.abi = .musl` para builds estáticos |

## Resumo

O Zig Build System é uma das razões pelas quais Zig se destaca como linguagem de sistemas moderna:

| Característica | Zig Build System | Make/CMake |
|---|---|---|
| **Linguagem** | Zig (a mesma do projeto) | DSL própria |
| **Cross-compilation** | Um flag (`-Dtarget=...`) | Dias de configuração |
| **Dependências externas** | Zero (integrado ao compilador) | Make, Python, CMake, Ninja... |
| **Cache** | Automático e inteligente | Manual ou básico |
| **Concorrência** | Automática | Manual com `-j` |
| **Compila C/C++** | Sim, nativamente | Apenas com configuração adicional |
| **Gerenciamento de pacotes** | `build.zig.zon` + `zig fetch` | Nenhum (ou conan, vcpkg...) |

O `build.zig` é código Zig — você tem toda a expressividade da linguagem para configurar seu build. Sem templates mágicos, sem DSLs para aprender, sem dependências para instalar.

## Próximos Passos

Agora que você domina o Zig Build System:

1. 📦 [Como Instalar o Zig](/tutoriais/como-instalar-zig/) — se ainda não instalou.
2. 🔄 [Zig para Programadores C: Guia de Migração](/tutoriais/zig-para-programadores-c/) — para integrar código C existente.
3. ⚡ [Comptime em Zig: O Poder da Execução em Tempo de Compilação](/tutoriais/comptime-em-zig/) — para metaprogramação avançada.
4. 📖 [Documentação oficial do Build System](https://ziglang.org/learn/build-system/) — referência completa com mais exemplos.

---

*Tem dúvidas ou sugestões sobre o Zig Build System? Compartilhe com a comunidade Zig Brasil!*
