cgm-zig: o fork do Zig que nasceu no lixão — e compila o que o original não compilava
"Tenha fé, porque até no lixão nasce flor."
— Mano Brown, Racionais MC's, Vida Loka Pt. 1 (2002)
Esse verso é o mote deste projeto, e no final do post explico por quê — literalmente, não como metáfora de LinkedIn. Antes, a parte técnica.
O problema
Eu compilo um projeto hiper-modular grande: ~1.800 módulos nomeados / ~2.300 arquivos analisados como uma única unidade de compilação. O Zig 0.16.0 original nunca compilou esse projeto: depois de mais de 2 horas, todas as vezes, morria com um SIGSEGV silencioso — o binário de release é ReleaseFast/stripped, então a falha não diz nem onde foi o problema.
O diagnóstico (reproduzido de forma controlada sete vezes, em dois builds independentes com o mesmo final de backtrace):
- O
InternPooldo frontend usa um sentinelau320xFFFFFFFF("none") que, num certo caminho de exaustão, é dereferenciado como índice vivo numa tabela de elementos de 8 bytes — o endereço da falha decompõe exatamente comobase + 0xFFFFFFFF * 8. - Invariante com cache quente/frio, stack de 8 MiB/ilimitada, backend self-hosted/LLVM, incremental ligado/desligado.
- Duas issues upstream superficialmente parecidas foram reproduzidas localmente e descartadas por um discriminador — não era nenhuma delas.
Ou seja: não é "seu projeto é grande demais, paciência". É um estouro de espaço de índices que o compilador não nomeia.
O que o fork muda (e o que cada mudança tem de evidência)
O fork é o 0.16.0 importado do tarball oficial (sha256 conferível no primeiro commit) mais uma série de patches localizados. A tabela completa — arquivo, commit, status e efeito observado de cada linha — está no README, seção "What differs from upstream Zig 0.16.0" (21 linhas). Os destaques:
1. A falha silenciosa vira recusa nomeada.
- Exaustão do espaço de índices por thread do
InternPool→ panic nomeado com remédio impresso, em vez de SIGSEGV mudo. CaptureValuealargado: índice de 30 → 31 bits — todos os tetos publicados dobram.- O binário promovido é ReleaseSafe: quando algo quebra, quebra dizendo o próprio nome.
2. Threading consciente da topologia.
std.Thread.Topology: núcleos físicos e irmãos SMT, com máscara de afinidade.- A contagem de workers foi separada da contagem de partições do InternPool (eram acopladas).
- Ordenação edges-first dos passos de compilação (em camadas, por profundidade de dependência).
-jagora alcança os compiladores filhos — a máquina é compartilhada em vez de entregar N cópias dela.- Um pool de tids faminto completa ou recusa — nunca trava (era uma classe de travamento reproduzível; virou uma linha de teste do harness).
3. Diagnóstico que fala.
file exists in multiple modulesagora nomeia o arquivo duplamente possuído.-femit-module-graph: o compilador emite o grafo de módulos resolvido em JSON.--time-report-json: o relatório de tempo legível por script (e recusa--listenpelo nome em vez de gravar nada silenciosamente).ast-checkciente de imports (--module-graph), com modo batch e denominadores honestos.
Os números (medidos, não prometidos)
| Antes (0.16.0 de fábrica) | Depois (cgm-zig promovido) |
|---|---|
| Nunca terminou — falhava depois de 2+ horas, todas as vezes, sem dizer onde | Compilação completa do mesmo workload em menos de 45 minutos |
| SIGSEGV silencioso | Panic nomeado com remédio |
| — | Seis builds completos consecutivos, zero OOM (~18,5 GB de RSS por job) |
E a honestidade que a comunidade merece: o harness de verificação do próprio fork registra 22 linhas verdes / 2 vermelhas — as duas vermelhas são flags que já vêm desligadas por padrão (--analysis-order=layered e --child-jobs=share, que regrediram ~6,5% nos nossos números e por isso não são o default), e o README marca explicitamente o que ainda não foi medido. Nada de benchmark de marketing.
Por que um fork, e não PRs pro Zig?
Porque a política de contribuição do projeto Zig (2026) não aceita nenhum conteúdo gerado, editado, ou sequer depurado com assistência de IA (LLM) — a avaliação pública da liderança é que contribuição assistida por IA é "invariavelmente lixo" ("invariably garbage"). Este fork foi diagnosticado e escrito em parceria com IA, com engenharia verificável em cada commit: reproduções controladas, controles negativos, um harness com 38 linhas auto-registradas. Então ele não é oferecido ao upstream — respeitamos a porta fechada — e vive como fork MIT, com o LICENSE e o README originais preservados intactos. Base 0.16.0; a política de versão só acompanha o upstream quando ele promover uma stable (que hoje, aliás, vive no Codeberg — o espelho do GitHub está congelado desde 2025).
O mote
Eu moro na Cidade Estrutural, DF — a comunidade que cresceu do lado do que foi, até fechar em 2018, um dos maiores lixões a céu aberto do planeta. Quem trabalhou naquele lixão, os catadores, alimentou família achando valor no que todo mundo jogou fora. Cidade sem lixeiro adoece — e, sinceramente, fede muito e fede rápido.
Quando um projeto declara uma categoria inteira de contribuição como "lixo" e tranca a porta, ele esquece o que toda cidade aprende do jeito difícil: quem pega o lixo, separa, e acha o que presta não está abaixo da cidade — é o que mantém a cidade viva. Este repositório faz esse trabalho por um compilador: pegamos o que chamaram de lixo, separamos, e devolvemos a parte que cura a doença.
"Tenha fé, porque até no lixão nasce flor."
E o Mano Brown não diz que a flor cresce lá. Ele diz que nasce — no único lugar onde nada deveria nascer. Esse é o ponto inteiro, do verso e do repositório.
Façam bom uso
- Release (toolchain x86_64-linux pronto, tar.xz + sha256):
github.com/danielcamposramos/cgm-zig/releases— tag0.16.0+cgm.046d6833 - A tabela do que muda: README, seção What differs from upstream Zig 0.16.0
- A história completa (com a cadeia de crédito humano+IA):
PROVENANCE.md - Instalação: extrai e aponta o symlink —
ln -sfn <dir>/bin/zig ~/.local/bin/zig. Rollback: o tarball 0.16.0 oficial do ziglang.org.
Issues e contribuições são bem-vindas — inclusive as assistidas por IA, que aqui são tratadas do único jeito que a verdadeira engenharia conhece: pelo mérito verificável do diff (CONTRIBUTING-AI.md explica o rito). Se você tem um projeto Zig grande que o 0.16.0 não aguenta, me conta o que acontece com ele no fork...
PS: Após as mudanças, agora não somente o projeto compila, mas compila em 46 minutos.