---
title: "Zig para FreeBSD e NetBSD: Cross-Compilation para Sistemas BSD"
url: "https://ziglang.com.br/artigos/zig-cross-compilation-freebsd-netbsd/"
markdown_url: "https://ziglang.com.br/artigos/zig-cross-compilation-freebsd-netbsd.MD"
description: "Aprenda a compilar projetos Zig para FreeBSD e NetBSD. Cross-compilation, zig cc, libc integrada e deploy em servidores BSD."
date: "2026-04-27"
author: ""
---

# Zig para FreeBSD e NetBSD: Cross-Compilation para Sistemas BSD

Aprenda a compilar projetos Zig para FreeBSD e NetBSD. Cross-compilation, zig cc, libc integrada e deploy em servidores BSD.


Um dos maiores diferenciais da [linguagem Zig](/artigos/por-que-aprender-zig/) é sua capacidade de cross-compilation integrada ao compilador. Diferente de outras linguagens onde configurar uma toolchain para compilar para outro sistema operacional pode levar horas, Zig torna o processo trivial — e em 2026, o suporte a **FreeBSD** e **NetBSD** atingiu maturidade de produção.

Neste artigo, vamos explorar como compilar projetos Zig para sistemas BSD, usar `zig cc` como cross-compiler C para BSD, e configurar pipelines de [CI/CD](/artigos/zig-docker-containers/) que geram binários para múltiplos targets BSD.

## Por Que BSD Importa para Desenvolvedores Zig

FreeBSD e NetBSD são sistemas operacionais amplamente usados em infraestrutura de produção. Netflix, WhatsApp e Sony (PlayStation) usam FreeBSD em seus servidores e dispositivos. NetBSD é conhecido por rodar em praticamente qualquer hardware existente.

Para desenvolvedores de [sistemas e ferramentas de baixo nível](/artigos/zig-embarcados-iot/), poder compilar para BSD a partir de qualquer máquina de desenvolvimento — seja Linux, macOS ou Windows — é essencial. Zig elimina a necessidade de ter uma máquina BSD disponível para compilar.

### O Que Mudou em 2026

O suporte a BSD no Zig evoluiu significativamente:

- **aarch64-freebsd** e **x86_64-freebsd** são agora targets testados nativamente no CI do Zig
- **aarch64-netbsd** e **x86_64-netbsd** também ganharam testes nativos no CI
- Zig agora inclui headers de sistema e libc para FreeBSD 14.0+ e NetBSD 10.1+
- O formato `abilists` compacto permite que o compilador conheça todos os símbolos públicos da libc de cada target

## Compilando Zig para FreeBSD

### Exemplo Básico

Compilar um programa Zig para FreeBSD é tão simples quanto adicionar o flag `-target`:

```zig
// src/main.zig — servidor HTTP simples
const std = @import("std");

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    var server = std.http.Server.init(allocator, .{
        .reuse_address = true,
    });
    defer server.deinit();

    const address = std.net.Address.parseIp("0.0.0.0", 8080) catch unreachable;
    try server.listen(address);

    std.log.info("Servidor rodando na porta 8080", .{});

    while (true) {
        var response = try server.accept(.{
            .allocator = allocator,
        });
        defer response.deinit();

        try response.headers.append("Content-Type", "text/plain");
        try response.do();
        try response.writeAll("Zig rodando em FreeBSD!");
        try response.finish();
    }
}
```

Para compilar esse servidor para FreeBSD x86_64:

```bash
# Compilar para FreeBSD x86_64
zig build-exe src/main.zig -target x86_64-freebsd -O ReleaseSafe

# Compilar para FreeBSD ARM64 (ex: servidor ARM)
zig build-exe src/main.zig -target aarch64-freebsd -O ReleaseSafe

# Verificar o binário gerado
file main
# main: ELF 64-bit LSB executable, x86-64, version 1 (FreeBSD)
```

### Usando o Build System

Para projetos maiores que usam o [build system do Zig](/artigos/zig-build-system-guia/), a configuração de targets BSD é feita no `build.zig`:

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

pub fn build(b: *std.Build) void {
    // Target padrão (máquina local)
    const target = b.standardTargetOptions(.{});
    const optimize = b.standardOptimizeOption(.{});

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

    b.installArtifact(exe);

    // Steps dedicados para cada target BSD
    const freebsd_x86 = b.resolveTargetQuery(.{
        .cpu_arch = .x86_64,
        .os_tag = .freebsd,
    });

    const freebsd_arm = b.resolveTargetQuery(.{
        .cpu_arch = .aarch64,
        .os_tag = .freebsd,
    });

    const netbsd_x86 = b.resolveTargetQuery(.{
        .cpu_arch = .x86_64,
        .os_tag = .netbsd,
    });

    // Executáveis para cada plataforma
    const exe_freebsd_x86 = b.addExecutable(.{
        .name = "meu-servidor-freebsd-x86",
        .root_source_file = b.path("src/main.zig"),
        .target = freebsd_x86,
        .optimize = .ReleaseSafe,
    });

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

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

    // Step "bsd" compila todos os targets BSD
    const bsd_step = b.step("bsd", "Compilar para todos os targets BSD");
    bsd_step.dependOn(&b.addInstallArtifact(exe_freebsd_x86, .{}).step);
    bsd_step.dependOn(&b.addInstallArtifact(exe_freebsd_arm, .{}).step);
    bsd_step.dependOn(&b.addInstallArtifact(exe_netbsd, .{}).step);
}
```

Agora, basta rodar:

```bash
# Compilar para todos os targets BSD
zig build bsd

# Ou especificar target via linha de comando
zig build -Dtarget=x86_64-freebsd
```

## Compilando Zig para NetBSD

O processo para NetBSD é idêntico, mudando apenas o target:

```bash
# NetBSD x86_64
zig build-exe src/main.zig -target x86_64-netbsd -O ReleaseSafe

# NetBSD ARM64
zig build-exe src/main.zig -target aarch64-netbsd -O ReleaseSafe
```

### Diferenças entre FreeBSD e NetBSD como Targets

Embora a experiência do desenvolvedor seja a mesma, há diferenças nas syscalls e APIs disponíveis:

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

pub fn getPlatformInfo() []const u8 {
    return switch (builtin.os.tag) {
        .freebsd => "FreeBSD — kqueue, jails, ZFS nativo",
        .netbsd => "NetBSD — portabilidade extrema, rump kernels",
        .linux => "Linux — epoll, cgroups, namespaces",
        else => "Plataforma desconhecida",
    };
}

// Adaptar comportamento por SO em comptime
pub fn createEventLoop() !void {
    if (comptime builtin.os.tag == .freebsd or builtin.os.tag == .netbsd) {
        // BSD usa kqueue para I/O assíncrono
        std.log.info("Usando kqueue para event loop", .{});
    } else if (comptime builtin.os.tag == .linux) {
        // Linux usa epoll (ou io_uring)
        std.log.info("Usando epoll/io_uring para event loop", .{});
    }
}
```

Para entender mais sobre I/O assíncrono em Zig, veja o artigo sobre [io_uring e async](/artigos/zig-io-uring-async/) e os [padrões de concorrência](/artigos/zig-concorrencia-padroes-avancados/).

## Usando zig cc como Cross-Compiler C para BSD

Um caso de uso extremamente poderoso é usar `zig cc` para compilar projetos C existentes para BSD. O Zig embarca sua própria libc e headers de sistema para cada target suportado, eliminando a necessidade de instalar toolchains separadas.

### Compilando um Projeto C para FreeBSD

```bash
# Compilar um arquivo C para FreeBSD
zig cc -target x86_64-freebsd -O2 -o servidor servidor.c

# Compilar com linkagem a bibliotecas do sistema
zig cc -target x86_64-freebsd -O2 -lm -lpthread -o app main.c utils.c

# Compilar código C++ para FreeBSD
zig c++ -target x86_64-freebsd -O2 -std=c++17 -o app main.cpp
```

### Integração com Projetos C Existentes via Makefile

```makefile
# Makefile para cross-compilation BSD com zig cc
CC = zig cc
CXX = zig c++

FREEBSD_TARGET = x86_64-freebsd
NETBSD_TARGET = x86_64-netbsd

CFLAGS = -O2 -Wall -Wextra
SRC = src/main.c src/utils.c src/network.c

.PHONY: freebsd netbsd all

all: freebsd netbsd

freebsd:
	$(CC) -target $(FREEBSD_TARGET) $(CFLAGS) $(SRC) -o build/app-freebsd

netbsd:
	$(CC) -target $(NETBSD_TARGET) $(CFLAGS) $(SRC) -o build/app-netbsd
```

Isso é particularmente útil para quem está [migrando projetos de C para Zig](/artigos/migrar-projeto-c-para-zig/) gradualmente — você pode compilar a parte C do projeto com `zig cc` e a parte nova com Zig nativo, tudo no mesmo pipeline de build.

### Integração com a Interoperabilidade C de Zig

Projetos que usam a [interoperabilidade C do Zig](/artigos/zig-interoperabilidade-c/) para chamar bibliotecas C nativas funcionam perfeitamente com targets BSD:

```zig
const c = @cImport({
    @cInclude("sys/sysctl.h");
    @cInclude("sys/types.h");
});

pub fn getSystemInfo(allocator: std.mem.Allocator) ![]const u8 {
    var size: usize = 0;
    // sysctl está disponível em FreeBSD e NetBSD
    const name = [_]c_int{ c.CTL_KERN, c.KERN_OSRELEASE };
    _ = c.sysctl(&name, name.len, null, &size, null, 0);

    const buf = try allocator.alloc(u8, size);
    _ = c.sysctl(&name, name.len, buf.ptr, &size, null, 0);

    return buf[0..size];
}
```

## Pipeline de CI/CD Multi-Target com BSD

Para projetos que precisam gerar releases para múltiplos sistemas operacionais, um pipeline automatizado é essencial. Aqui está um exemplo usando o [Docker com Zig](/artigos/zig-docker-containers/):

```yaml
# .gitea/workflows/release.yml
name: Release Multi-Plataforma
on:
  push:
    tags: ['v*']

jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        target:
          - x86_64-linux
          - aarch64-linux
          - x86_64-freebsd
          - aarch64-freebsd
          - x86_64-netbsd
    steps:
      - uses: actions/checkout@v4

      - name: Instalar Zig
        run: |
          wget -q https://ziglang.org/download/0.16.0/zig-linux-x86_64-0.16.0.tar.xz
          tar xf zig-linux-x86_64-0.16.0.tar.xz
          echo "$PWD/zig-linux-x86_64-0.16.0" >> $GITHUB_PATH

      - name: Compilar para ${{ matrix.target }}
        run: zig build -Dtarget=${{ matrix.target }} -Doptimize=ReleaseSafe

      - name: Upload artefato
        uses: actions/upload-artifact@v4
        with:
          name: build-${{ matrix.target }}
          path: zig-out/bin/*
```

Este pipeline compila seu projeto para Linux, FreeBSD e NetBSD automaticamente a cada nova tag. Veja o guia sobre [cross-compilation](/artigos/zig-cross-compilation-guia/) para configurações mais avançadas.

## Considerações sobre Alocação de Memória em BSD

Os [allocators do Zig](/artigos/zig-alocacao-memoria-estrategias/) funcionam de forma consistente entre Linux e BSD, mas há nuances a considerar:

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

pub fn createOptimalAllocator() std.mem.Allocator {
    // page_allocator usa mmap em todos os Unix-like (Linux, FreeBSD, NetBSD)
    // O comportamento é consistente entre plataformas
    return std.heap.page_allocator;
}

// Para aplicações de alta performance em servidores BSD
pub fn serverAllocator() std.heap.GeneralPurposeAllocator(.{
    .thread_safe = true,
    // Habilitar safety em produção para detectar bugs
    .safety = builtin.mode == .Debug or builtin.mode == .ReleaseSafe,
}) {
    return .{};
}
```

O `page_allocator` do Zig usa `mmap` tanto em Linux quanto em BSD, garantindo comportamento consistente. Para cenários de alta performance, como [processamento de dados](/artigos/zig-processamento-dados-parsing-serializacao/) ou [networking](/artigos/zig-networking-sockets-tcp-udp/), os mesmos padrões de [alocação](/artigos/zig-alocacao-memoria-estrategias/) se aplicam.

## Comparação: Cross-Compilation para BSD em Diferentes Linguagens

| Aspecto | Zig | Go | Rust | C/C++ |
|---------|-----|-----|------|-------|
| Setup necessário | Nenhum (embutido) | `GOOS=freebsd` | Instalar target + linker | Toolchain completa |
| Suporte FreeBSD | Nativo, CI testado | Nativo | Via rustup target | Manual |
| Suporte NetBSD | Nativo, CI testado | Parcial | Tier 3 (sem CI) | Manual |
| Libc incluída | Sim (headers + abilists) | Sim (Go runtime) | Depende do target | Não |
| Cross-compile C | Sim (zig cc) | Via CGO (complexo) | Via cc-rs (complexo) | Toolchain externa |
| Binário estático | Padrão | Padrão | Com musl | Com musl |

Para uma comparação mais detalhada entre Zig e outras linguagens, veja os artigos [Zig vs Rust](/artigos/zig-vs-rust/), [Zig vs Go](/artigos/zig-vs-go/) e o [comparativo completo](/artigos/zig-rust-go-comparativo/).

Desenvolvedores que usam [Rust](https://rustlang.com.br) <a href="https://rustlang.com.br" target="_blank" rel="noopener" onclick="umami.track('portfolio-site-click', { destination: 'rustlang.com.br' })">rustlang.com.br</a> notarão que o suporte BSD no Zig é significativamente mais simples, sem necessidade de instalar targets adicionais via rustup. Já quem vem de [Go](https://golang.com.br) <a href="https://golang.com.br" target="_blank" rel="noopener" onclick="umami.track('portfolio-site-click', { destination: 'golang.com.br' })">golang.com.br</a> encontrará uma experiência similar, mas com o bônus de poder cross-compilar código C junto.

## Deploy em Servidores FreeBSD

Após compilar, enviar o binário para um servidor FreeBSD é direto:

```bash
# Compilar localmente (de qualquer SO)
zig build -Dtarget=x86_64-freebsd -Doptimize=ReleaseSafe

# Enviar para o servidor
scp zig-out/bin/meu-servidor usuario@servidor-freebsd:/usr/local/bin/

# No servidor FreeBSD — criar service rc.d
ssh usuario@servidor-freebsd << 'EOF'
cat > /usr/local/etc/rc.d/meu-servidor << 'RC'
#!/bin/sh
# PROVIDE: meu_servidor
# REQUIRE: NETWORKING
# KEYWORD: shutdown

. /etc/rc.subr

name="meu_servidor"
rcvar="meu_servidor_enable"
command="/usr/local/bin/meu-servidor"
pidfile="/var/run/${name}.pid"

load_rc_config $name
run_rc_command "$1"
RC
chmod +x /usr/local/etc/rc.d/meu-servidor
echo 'meu_servidor_enable="YES"' >> /etc/rc.conf
service meu_servidor start
EOF
```

## Perguntas Frequentes

### Preciso de uma máquina FreeBSD para compilar para FreeBSD?

Não. Esse é o grande diferencial do Zig: o compilador inclui todos os headers e informações de libc necessários para gerar binários FreeBSD e NetBSD a partir de qualquer sistema operacional. Basta usar `-target x86_64-freebsd` ou `-target aarch64-freebsd`.

### O zig cc funciona como substituto do clang no FreeBSD?

Sim, para a maioria dos casos. `zig cc` é um wrapper sobre o backend LLVM que inclui libc e headers de sistema. Projetos C que compilam com clang ou gcc normalmente compilam com `zig cc` sem alterações — inclusive para targets BSD.

### Quais versões de FreeBSD e NetBSD são suportadas?

O Zig 0.16 suporta oficialmente FreeBSD 14.0+ e NetBSD 10.1+. O compilador inclui headers e abilists destas versões. Versões mais antigas podem funcionar, mas não são testadas no CI oficial.

### Posso usar bibliotecas nativas do FreeBSD como jails ou ZFS?

Sim, via `@cImport` do Zig. Você pode importar headers do FreeBSD e chamar APIs nativas como `jail_attach()`, funções de `libzfs`, ou qualquer API disponível nos headers incluídos. A [interoperabilidade C](/artigos/zig-interoperabilidade-c/) do Zig facilita esse processo.
