---
title: "Migrar de Makefile para build.zig"
url: "https://ziglang.com.br/tutoriais/migrar-makefile-para-build-zig/"
markdown_url: "https://ziglang.com.br/tutoriais/migrar-makefile-para-build-zig.MD"
description: "Guia completo para substituir Makefile por build.zig. Conversão de targets, flags, dependências, compilação condicional e scripts de build para o sistema de build integrado de Zig."
date: "2026-02-21"
author: "Zig Brasil"
---

# Migrar de Makefile para build.zig

Guia completo para substituir Makefile por build.zig. Conversão de targets, flags, dependências, compilação condicional e scripts de build para o sistema de build integrado de Zig.


## Introdução

O sistema de build de Zig é uma das suas features mais poderosas. Em vez de aprender uma linguagem de build separada (Make), você escreve a lógica de build em Zig — a mesma linguagem do seu projeto. Isso elimina bugs de Makefile, simplifica cross-compilation, e torna o build reproduzível.

Este guia mostra como converter um Makefile típico para `build.zig`. Para CMake, veja [Migrar de CMake para build.zig](/tutoriais/migrar-cmake-para-build-zig/). Para o sistema de build em geral, consulte [Zig Build System](/tutoriais/zig-build-system/).

## Pré-requisitos

- Zig instalado (versão 0.13+). Veja [Como Instalar Zig](/tutoriais/como-instalar-zig/)
- Projeto C/C++ existente com Makefile
- Familiaridade básica com Zig

## Exemplo Básico: Projeto C Simples

### Makefile Original

```makefile
CC = gcc
CFLAGS = -Wall -Wextra -O2 -std=c11
LDFLAGS = -lm -lpthread

SRCS = src/main.c src/utils.c src/parser.c
OBJS = $(SRCS:.c=.o)
TARGET = meu-programa

all: $(TARGET)

$(TARGET): $(OBJS)
	$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)

%.o: %.c
	$(CC) $(CFLAGS) -c $< -o $@

clean:
	rm -f $(OBJS) $(TARGET)

install: $(TARGET)
	cp $(TARGET) /usr/local/bin/

.PHONY: all clean install
```

### build.zig Equivalente

```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 = "meu-programa",
        .target = target,
        .optimize = optimize,
    });

    exe.addCSourceFiles(.{
        .files = &.{
            "src/main.c",
            "src/utils.c",
            "src/parser.c",
        },
        .flags = &.{
            "-Wall",
            "-Wextra",
            "-std=c11",
        },
    });

    exe.addIncludePath(b.path("include"));
    exe.linkLibC();
    exe.linkSystemLibrary("m");
    exe.linkSystemLibrary("pthread");

    b.installArtifact(exe);

    // Equivalente a "make run"
    const run_cmd = b.addRunArtifact(exe);
    run_cmd.step.dependOn(b.getInstallStep());

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

## Mapeamento de Conceitos

| Makefile | build.zig |
|----------|-----------|
| `CC = gcc` | Automático (Zig gerencia) |
| `CFLAGS = -Wall` | `.flags = &.{"-Wall"}` |
| `LDFLAGS = -lm` | `exe.linkSystemLibrary("m")` |
| `SRCS = ...` | `exe.addCSourceFiles(...)` |
| Target `all` | `b.installArtifact(exe)` |
| Target `clean` | `zig build --clean` (automático) |
| Target `install` | `b.installArtifact(exe)` + `zig build install` |
| `ifdef DEBUG` | `const optimize = b.standardOptimizeOption(.{})` |
| `.PHONY` | Não necessário |

## Compilação Condicional

### Makefile

```makefile
ifdef DEBUG
CFLAGS += -g -DDEBUG
else
CFLAGS += -O2 -DNDEBUG
endif
```

### build.zig

```zig
const optimize = b.standardOptimizeOption(.{});

// O modo é controlado via linha de comando:
// zig build -Doptimize=Debug
// zig build -Doptimize=ReleaseFast

// Para defines customizados:
const debug = b.option(bool, "debug", "Ativar modo debug") orelse false;
if (debug) {
    exe.defineCMacro("DEBUG", null);
}
```

## Múltiplos Targets

### Makefile

```makefile
all: programa lib-estatica lib-dinamica

programa: $(OBJS)
	$(CC) -o $@ $^ $(LDFLAGS)

lib-estatica: $(LIB_OBJS)
	ar rcs libminha.a $^

lib-dinamica: $(LIB_OBJS)
	$(CC) -shared -o libminha.so $^
```

### build.zig

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

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

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

    // Executável que usa a biblioteca
    const exe = b.addExecutable(.{
        .name = "programa",
        .root_source_file = b.path("src/main.zig"),
        .target = target,
        .optimize = optimize,
    });
    exe.linkLibrary(lib);
    b.installArtifact(exe);
}
```

## Dependências Externas

### Makefile

```makefile
CFLAGS += $(shell pkg-config --cflags openssl)
LDFLAGS += $(shell pkg-config --libs openssl)
```

### build.zig

```zig
exe.linkSystemLibrary("ssl");
exe.linkSystemLibrary("crypto");
```

## Cross-compilation

### Makefile

```makefile
# Requer toolchain externo configurado manualmente
CC_ARM = arm-linux-gnueabihf-gcc
arm: CC = $(CC_ARM)
arm: all
```

### build.zig

```bash
# Integrado, sem configuração extra:
zig build -Dtarget=arm-linux-gnueabihf
zig build -Dtarget=aarch64-linux-gnu
zig build -Dtarget=x86_64-windows-gnu
zig build -Dtarget=x86_64-macos
```

Veja [Cross-compilation em Zig](/tutoriais/zig-cross-compilation/) para detalhes.

## Testes

### Makefile

```makefile
test: $(TEST_OBJS)
	$(CC) -o test_runner $^ -lcmocka
	./test_runner
```

### build.zig

```zig
const testes = b.addTest(.{
    .root_source_file = b.path("src/main.zig"),
    .target = target,
    .optimize = optimize,
});

const run_testes = b.addRunArtifact(testes);
const test_step = b.step("test", "Executar testes");
test_step.dependOn(&run_testes.step);
```

```bash
zig build test
```

Veja [Testes Unitários](/receitas/zig-teste-unitario-basico/) e [Testes com Allocator](/receitas/zig-teste-com-allocator/).

## Projeto Misto C + Zig

O cenário mais comum na migração é ter código C e Zig juntos:

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

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

    // Código C existente
    exe.addCSourceFiles(.{
        .files = &.{
            "src/legado/parser.c",
            "src/legado/utils.c",
        },
        .flags = &.{ "-std=c11", "-Wall" },
    });

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

    b.installArtifact(exe);
}
```

Veja [Interoperabilidade C-Zig](/tutoriais/zig-c-interoperabilidade/) e [Chamar Funções C de Zig](/receitas/zig-chamar-funcao-c/).

## Vantagens do build.zig sobre Makefile

1. **Linguagem real**: build.zig é código Zig — tem tipos, funções, loops, condicionais
2. **Cross-compilation trivial**: Flag de linha de comando, sem toolchain externo
3. **Cache automático**: Zig gerencia cache de compilação
4. **Sem dependências**: Não precisa de `make`, `autotools`, `pkg-config`
5. **Reproduzível**: Sem variações entre sistemas operacionais
6. **Debugável**: Build.zig pode ser debugado como qualquer código Zig

## Conclusão

Migrar de Makefile para build.zig simplifica significativamente o processo de build, especialmente para projetos que precisam de cross-compilation ou que misturam código C e Zig. A curva de aprendizado é mínima se você já conhece Zig.

Para migrar de CMake, veja [Migrar de CMake para build.zig](/tutoriais/migrar-cmake-para-build-zig/). Para a estratégia completa de migração de projeto C, consulte [Como Migrar um Projeto C para Zig](/artigos/migrar-projeto-c-para-zig/).
