Zig 0.17 já está disponível: seu build.zig precisa de mudanças, a compilação incremental funciona em x86_64-linux com apenas uma flag e ZLS ainda não é compatível. Essas três coisas importam se você mantém um projeto em Zig. Além disso, @bitCast pode mudar de comportamento sem que o compilador avise. A versão reúne cinco meses de trabalho de 206 contribuidores em 925 commits, e quase todo esse esforço se concentrou no build system e no linker.
O que é Zig e em que se diferencia de Rust?
Zig é uma linguagem de programação de propósito geral e uma toolchain para programação de sistemas, orientada a software robusto, ótimo e reutilizável. Compete no mesmo terreno que C, C++ e Rust, embora com uma filosofia distinta.
Rust garante a segurança de memória em tempo de compilação através de seu borrow checker. Zig não tem borrow checker: oferece alocadores explícitos, execução de código em tempo de compilação com comptime e verificações de segurança em tempo de execução nos modos de compilação seguros. Em troca, oferece uma linguagem mais pequena e interoperabilidade direta com C. Sua toolchain também compila C e C++ de forma cruzada com zig cc. Se você se pergunta zig vs rust, a escolha se reduz a quanto controle manual você quer e quantas garantias prefere delegar ao compilador.
Zig ainda não chega à 1.0, assim que cada versão menor pode quebrar código. Por isso cada atualização precisa de um guia de migração. O projeto é financiado pela Zig Software Foundation, uma organização sem fins lucrativos, e seu código-fonte agora vive em Codeberg em vez de GitHub.
O que muda em zig build com Zig 0.17?
zig build não executa mais seu build.zig no mesmo processo que corre o build. O antigo build runner se separa em duas peças:
- O configurer executa seu
build.zige gera o grafo de build. - O maker fica responsável pela gestão de pacotes e executa esse grafo.
Na prática, isso tem três efeitos:
- O maker se compila uma única vez. Ele é construído com otimizações na primeira vez que você usa Zig após instalá-lo, e não precisa recompilar quando você edita
build.zig. - A configuração pode ser pulada. Se nada relevante mudou,
zig buildpode omitir seubuild.zigcompletamente. - A configuração agora é um dado. O grafo de build é serializado em um formato binário compacto que ferramentas externas podem ler. Para vê-lo, passe
--print-configurationazig builde ele o imprimirá como.zonna saída padrão.
Esse último ponto é a base do novo Build Server Protocol. Se você passar --listen=-, o build system expõe um protocolo que permite a um cliente conectado inspecionar o grafo de build completo, receber notificações quando um passo começa e termina, e pedir que passos concretos sejam executados. É pensado para IDEs e ferramentas de terceiros. Como consequência, não é mais possível substituir o build runner: esse caso de uso agora é coberto pelo protocolo.
O que você precisa mudar em build.zig?
As release notes listam explicitamente as mudanças de API do build system. Estes são os que mais provavelmente afetarão um projeto típico.
Argumentos do passo Run. Os scripts de build não conseguem mais inspecionar os argumentos que são passados ao programa. Em troca, modificar esses argumentos não força mais a recompilação de build.zig:
-if (b.args) |args| {
- run_cmd.addArgs(args);
-}
+run_cmd.addPassthruArgs();
Caminhos do passo Fmt. Agora são listas de LazyPath e são criadas com b.pathList:
- const fmt_include_paths = &.{ "lib", "src", "test", "tools", "build.zig", "build.zig.zon" };
+ const fmt_include_paths = b.pathList(&.{ "lib", "src", "test", "tools", "build.zig", "build.zig.zon" });
Renomeações e remoções:
b.build_root(um Directory) passa a serb.root(um Path).LazyPath.getDisplayNamepassa a serformat, que é usado com"{f}".LazyPath.basenameé removido, porque seu valor não é conhecido até a fase de make.- Os helpers de argumentos do passo
Runsão unificados em uma única variante terminada em2. Por exemplo,addArtifactArgeaddPrefixedArtifactArgpassam a seraddArtifactArg2, eaddFileArgeaddPrefixedFileArgpassam a seraddFileArg2. O mesmo padrão se aplica aos argumentos de arquivo de saída, conteúdo de arquivo, diretório, diretório de saída e dep-file. ConfigHeader.Options.include_guard_overridepassa a serinclude_guard.- As opções que recebem um caminho agora devem indicar que tipo de caminho é:
addOptionPathpara um arquivo,addOptionPathDirectorypara um diretório, ouaddOptionPathUntrackedpara excluí-lo do rastreamento de dependências.
Tradução de C. @cImport é eliminado; já era deprecado na 0.16. std.Build.Step.TranslateC é deprecado em favor do pacote oficial translate-c. Primeiro adicione a dependência:
zig fetch --save git+https://codeberg.org/ziglang/translate-c
Depois substitua b.addTranslateC(...) pelo Translator do pacote:
+const Translator = @import("translate_c").Translator;
...
- const translate_c = b.addTranslateC(.{
- .root_source_file = b.path("src/c.h"),
+ const translate_c = b.dependency("translate_c", .{});
+
+ const translator: Translator = .init(translate_c, .{
+ .c_source_file = b.path("src/c.h"),
.target = target,
.optimize = optimize,
});
...
- .module = translate_c.createModule(),
+ .module = translator.mod,
Efeitos colaterais na configuração. Zig agora detecta quando sua lógica de configuração faz algo que o cache não consegue rastrear. Chamar findProgram, por exemplo, “envenena” o cache de configuração, e isso força a execução de build.zig em cada build. Se você só precisa do programa em tempo de build, use findProgramLazy: retorna um LazyPath e deixa o cache intacto. Se sua configuração lê arquivos ou diretórios, declare essa dependência com std.Build.dependOnFileContents ou uma de suas variantes, e o cache continuará funcionando.
Como ativar a compilação incremental em Zig?
Execute o build com estes dois flags:
zig build -fincremental --watch
O sistema de build monitora seus arquivos-fonte e faz uma recompilação incremental cada vez que eles mudam. De acordo com as release notes, a incremental compilation já funciona para a maioria dos projetos que têm como alvo x86_64-linux. É o resultado de muitas correções de bugs e do melhor suporte no novo linker ELF que chegou na versão anterior.
As release notes estabelecem três condições:
- Por enquanto requer
--watch. Usar compilação incremental sem o modo watch figura como trabalho futuro. - Na prática é apenas para Linux x86_64. O novo linker ELF é a peça que torna isso possível. No Mac e aarch64 é preciso esperar um novo linker Mach-O e um backend aarch64 próprio, ambos planejados para versões futuras.
- O novo linker continua desativado por padrão. Ainda não alcança totalmente o linker ELF legado em funcionalidade, mas é ativado automaticamente quando você usa compilação incremental, assim como na 0.16.
Se você quer entender como funciona por dentro, as release notes recomendam este artigo de Matthew Lugg, membro da equipe principal de Zig: Inside Zig's Incremental Compilation | mlugg.co.uk
ZLS funciona com Zig 0.17?
Não: no momento da publicação desta nota (outubro de 2026), ZLS não funciona com Zig 0.17. As release notes indicam que a separação entre configurer e maker é uma mudança incompatível que impede que ZLS, o language server de Zig, funcione com esta versão. As equipes de Zig e ZLS trabalham juntas para ampliar o Build Server Protocol, de modo que ZLS recupere suas funcionalidades e com o tempo as supere.
Se seu fluxo no editor depende de ZLS para autocompletar, navegação de código ou diagnósticos, não atualize ainda seu ambiente principal. Verifique o status do projeto em ZLS language server - zigtools antes de mudar.
O que pode quebrar sem que o compilador te avise?
@bitCast é a mudança mais perigosa da 0.17, porque pode quebrar código sem gerar nenhum erro de compilação. Agora é definida como a reinterpretação da representação lógica de bits de um valor.
- O que continua igual: os casts entre inteiros, e entre inteiros e
packed structoupacked union. - O que muda: os casts que envolvem arrays ou vetores têm uma semântica nova. As release notes advertem que isso pode quebrar código existente sem erros de compilação. A nova definição é independente do endianness e coincide em grande medida com o comportamento anterior em arquiteturas little-endian.
Antes de atualizar, procure em seu código as chamadas a @bitCast que envolvam arrays ou vetores e revise-as uma por uma.
Os casts com extern struct ou extern union agora são um erro de compilação. Se o que você busca é type punning, as release notes recomendam @ptrCast ou uma extern union.
Que mais mudou na linguagem?
As mudanças a seguir falham de forma visível na compilação, então o compilador te levará direto a elas:
- A multiplicação de arrays (
a ** b) foi removida. Use@splat, por exemplovar result: [n]u8 = @splat(0);. void{}foi removido. Escreva{}.- A captura em
errdefer |err|foi removida. As notas sugerem dividir a função em duas e tratar o erro comcatchna função externa. i0foi removido. Quase com certeza você pode substituí-lo poru0.@backingInte@fromBackingIntsubstituem@intFromEnume@enumFromInt.zig fmtfaz esta atualização automaticamente.@hasDeclagora retornatrueapenas para declarações públicas, mesmo quando é chamado do mesmo arquivo.- Novos builtins:
@divCeil, e@SpirvTypepara targets SPIR-V.
A biblioteca padrão tem sua própria lista de mudanças:
std.builtiné descontinuada a favor destd.lang.OptimizeModepassa a serOptimize, com as tagsdebug,safe,fastesmall. Os nomes antigos continuam existindo, mas as comparações com==contra eles deixam de compilar.StackFallbackAllocatorpassa a se chamarBufferFirstAllocator.std.heap.DebugAllocatoré descontinuado a favor do novoSafeAllocator, que é thread-safe.std.fmt.allocPrint(arena, …)passa a serarena.print(…).
Vale a pena atualizar agora?
Depende de sua configuração:
- Atualize se você compila principalmente para x86_64-linux, não depende de ZLS e quer recompilações rápidas. A compilação incremental é a recompensa, e as mudanças em
build.zigsão mecânicas. - Aguarde se seu fluxo no editor depende de ZLS, ou se você usa passos
Runcom response files. As release notes listam isso como uma regressão conhecida desta versão. - Em qualquer caso, revise seus
@bitCastantes de publicar qualquer binário compilado com a 0.17.
A versão também aproxima Zig da 1.0. A equipe tomou decisões sobre cerca de 150 propostas da linguagem neste ciclo: aceitou cerca de 25 e rejeitou cerca de 125. O backend de WebAssembly já passa em 100% dos testes de comportamento em relação ao backend de LLVM, embora ainda não seja o padrão em modo debug porque falta suporte de informações de depuração.
Você pode baixar esta versão em Download ⚡ Zig Programming Language ou instalá-la com um gerenciador de pacotes, seguindo o guia do projeto.
E você? Em qual projeto você vai testar primeiro a compilação incremental?
- Sim, já
- Quando ZLS for compatível
- Fico na 0.16 por enquanto
- Ainda não uso Zig (conte-nos o que te freia)
Comente abaixo ou, se este artigo chegou até você por email, responda diretamente ao email: sua resposta é publicada aqui.
Relacionado: Lightpanda: O Headless Browser Feito para Agentes de IA (Não para Humanos)
