Gerenciador de Pacotes do Zig — Guia Completo
O gerenciador de pacotes do Zig é uma peça fundamental do ecossistema, integrado diretamente ao sistema de build. Diferente de gerenciadores de pacotes centralizados como npm ou crates.io, o sistema do Zig adota uma abordagem descentralizada baseada em URLs e hashes, garantindo reprodutibilidade total das builds sem depender de um registro central único.
Arquitetura do Sistema de Pacotes
O gerenciamento de pacotes no Zig é feito através de dois arquivos que trabalham em conjunto:
build.zig.zon: Declara as dependências do projeto, incluindo URLs e hashes de integridadebuild.zig: Configura como as dependências são usadas no processo de compilação
Essa separação permite que o sistema de build seja flexível enquanto as dependências permanecem declarativas e verificáveis.
Estrutura do build.zig.zon
O arquivo build.zig.zon usa o formato ZON (Zig Object Notation), que é essencialmente um subconjunto da sintaxe de inicializadores do Zig:
.{
.name = "meu-projeto",
.version = "1.0.0",
.minimum_zig_version = "0.13.0",
.dependencies = .{
.httpz = .{
.url = "https://github.com/zig-community/httpz/archive/refs/tags/v0.2.0.tar.gz",
.hash = "1220a1b2c3d4e5f6...",
},
.zap = .{
.url = "git+https://github.com/zigzap/zap.git#v0.5.0",
.hash = "1220f1e2d3c4b5a6...",
},
.minha_lib_local = .{
.path = "../minha-lib",
},
},
.paths = .{
"build.zig",
"build.zig.zon",
"src",
"LICENSE",
"README.md",
},
}
Campos Importantes
.name: Nome do pacote, usado como identificador.version: Versão semântica do pacote.minimum_zig_version: Versão mínima do compilador necessária.dependencies: Mapa de dependências com URLs ou caminhos locais.paths: Arquivos incluídos quando o pacote é consumido como dependência
Adicionando Dependências
Via Comando fetch
A forma mais simples de adicionar uma dependência é usando zig fetch:
# Adicionar dependência e calcular hash automaticamente
zig fetch --save https://github.com/exemplo/lib/archive/refs/tags/v1.0.0.tar.gz
# O comando adiciona automaticamente ao build.zig.zon
Manualmente
Você pode adicionar dependências manualmente ao build.zig.zon. Para calcular o hash:
zig fetch https://github.com/exemplo/lib/archive/refs/tags/v1.0.0.tar.gz
# Retorna o hash que deve ser colocado no campo .hash
Dependências Git
O Zig suporta repositórios Git diretamente:
.minha_dep = .{
.url = "git+https://github.com/usuario/repo.git#tag-ou-commit",
.hash = "1220...",
},
Dependências Locais
Para desenvolvimento com bibliotecas locais:
.minha_lib = .{
.path = "../caminho/para/lib",
},
Usando Dependências no build.zig
Após declarar as dependências no build.zig.zon, use-as no build.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 = "minha-app",
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});
// Importar dependência
const httpz = b.dependency("httpz", .{
.target = target,
.optimize = optimize,
});
// Adicionar módulo ao executável
exe.root_module.addImport("httpz", httpz.module("httpz"));
// Para bibliotecas C empacotadas como dependências Zig
const sqlite = b.dependency("sqlite", .{
.target = target,
.optimize = optimize,
});
exe.linkLibrary(sqlite.artifact("sqlite3"));
b.installArtifact(exe);
}
No código fonte, use normalmente:
const httpz = @import("httpz");
const std = @import("std");
pub fn main() !void {
var server = try httpz.Server.init(std.heap.page_allocator, .{ .port = 8080 });
defer server.deinit();
// ...
}
Criando Pacotes para Publicação
Para criar um pacote Zig que outros possam usar como dependência, siga estas práticas:
Estrutura Recomendada
minha-lib/
├── build.zig
├── build.zig.zon
├── src/
│ ├── lib.zig # Ponto de entrada do módulo
│ └── internal/
│ └── utils.zig
├── tests/
│ └── test_lib.zig
├── LICENSE
└── README.md
build.zig para uma Biblioteca
const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
// Expor módulo para consumidores
_ = b.addModule("minha-lib", .{
.root_source_file = b.path("src/lib.zig"),
.target = target,
.optimize = optimize,
});
// Testes
const tests = b.addTest(.{
.root_source_file = b.path("src/lib.zig"),
.target = target,
.optimize = optimize,
});
const run_tests = b.addRunArtifact(tests);
const test_step = b.step("test", "Executar testes");
test_step.dependOn(&run_tests.step);
}
build.zig.zon para Publicação
.{
.name = "minha-lib",
.version = "0.1.0",
.minimum_zig_version = "0.13.0",
.dependencies = .{},
.paths = .{
"build.zig",
"build.zig.zon",
"src",
"LICENSE",
},
}
Publicação
Como o sistema é descentralizado, publique seu pacote em qualquer serviço de hospedagem Git:
- GitHub/GitLab: Crie releases com tags semânticas
- Tar archives: Hospede em qualquer servidor HTTP
- Registros comunitários: Use plataformas como aquila ou astrolabe.pm
Registros de Pacotes Comunitários
Embora o Zig não tenha um registro central oficial, a comunidade mantém diretórios de pacotes:
- aquila: Registro e busca de pacotes Zig
- astrolabe.pm: Catálogo de pacotes com busca e metadados
- GitHub Topics: Busque por repositórios com a tag “zig-package”
Esses recursos são ótimos para descobrir bibliotecas do ecossistema como frameworks web, bibliotecas de criptografia e drivers de banco de dados.
Cache e Reprodutibilidade
O gerenciador de pacotes mantém um cache local em ~/.cache/zig/ (Linux) ou equivalente. As dependências são baixadas uma única vez e reutilizadas entre builds.
A verificação de hash garante que:
- Dependências não podem ser alteradas após publicação sem que o hash mude
- Builds são reproduzíveis em qualquer máquina
- Ataques de supply chain são detectáveis
# Limpar cache se necessário
rm -rf ~/.cache/zig/p/
# Forçar re-download de dependências
zig build --fetch
Dependências Transitivas
O sistema resolve automaticamente dependências transitivas. Se seu projeto depende de A, e A depende de B, o Zig resolve toda a árvore de dependências e garante que não haja conflitos de versão.
Boas Práticas
- Use tags semânticas para versionar seus pacotes
- Declare
.pathsexplicitamente para controlar o que é incluído no pacote - Especifique
minimum_zig_versionpara ajudar consumidores - Teste com múltiplas versões do compilador usando zigup
- Documente o módulo público com doc comments no código fonte
- Mantenha dependências mínimas para reduzir a árvore de dependências
Próximos Passos
Com o gerenciador de pacotes dominado, explore as bibliotecas disponíveis no ecossistema Zig. Consulte nossos tutoriais para projetos práticos que utilizam dependências externas e veja como projetos reais gerenciam pacotes nos cases de sucesso.