Build System Reworked

signa111 pts0 comments

Devlog<br>Zig Programming Language

Download

Learn

News

Source<br>Join a Community

ZSF

Devlog

Devlog

This page contains a curated list of recent changes to main branch Zig.

Also available as an<br>RSS feed.

This page contains entries for the year 2026. Other years are available in<br>the Devlog archive page.

May 26, 2026<br>Build System Reworked

Author: Andrew Kelley<br>Big branch just landed: separate the maker process from the configurer process<br>This devlog entry is essentially a preview of the upcoming release notes, but serves as an advanced notice to those who want to help test out the new features and provide feedback that will guide the Zig project moving forward.<br>Before, build.zig files plus the build system implementation were all compiled into one bloated process, in Debug mode. After build.zig logic finished constructing a build graph in memory, the “build runner” code executed it.<br>Now, build.zig files are compiled into a small process (the “configurer”) in debug mode. After this logic finishes constructing a build graph in memory, it is serialized to a binary configuration file. The parent zig build process is aware of this file and caches it for next time. While waiting for all that, it asynchronously compiles the build graph execution process (the “maker”) in release mode. Once the configuration file is available and the maker process is finished compiling, the maker process is executed, passing it the configuration file. The maker process only needs to be compiled once per zig version thanks to the global cache. The maker process then executes the build graph, which is contained within the serialized configuration file.<br>The primary motivation of this change was to make zig build faster, in three ways:<br>Only the user’s build.zig logic will be compiled with each change, rather than the entire build system along with it. This is starting to become more valuable now that we have introduced --watch, --fuzz and --webui. The build system can grow more features without making zig build take longer.

Now the build system can skip rerunning the build.zig logic entirely when it knows nothing will change, for example if you add -freference-trace to your zig build command line, it now avoids re-running your build.zig logic redundantly, using the same configuration as last time.

Now the process that actually executes the build graph is compiled with optimizations enabled.

To demonstrate points 2 and 3, here is the difference between running zig build --help before and after:<br>Benchmark 1 (34 runs): master/zig build -h<br>measurement mean ± σ min … max outliers delta<br>wall_time 150ms ± 5.52ms 145ms … 165ms 4 (12%) 0%<br>peak_rss 84.8MB ± 275KB 84.2MB … 85.1MB 0 ( 0%) 0%<br>cpu_cycles 593M ± 4.01M 588M … 608M 2 ( 6%) 0%<br>instructions 995M ± 52.5K 995M … 995M 0 ( 0%) 0%<br>cache_references 25.8M ± 165K 25.4M … 26.1M 0 ( 0%) 0%<br>cache_misses 651K ± 20.1K 619K … 697K 0 ( 0%) 0%<br>branch_misses 918K ± 7.44K 906K … 935K 0 ( 0%) 0%<br>Benchmark 2 (348 runs): branch/zig build -h<br>measurement mean ± σ min … max outliers delta<br>wall_time 14.3ms ± 744us 13.2ms … 23.3ms 8 ( 2%) ⚡- 90.4% ± 0.4%<br>peak_rss 78.5MB ± 562KB 77.1MB … 81.4MB 7 ( 2%) ⚡- 7.4% ± 0.2%<br>cpu_cycles 24.1M ± 821K 22.8M … 27.1M 3 ( 1%) ⚡- 95.9% ± 0.1%<br>instructions 43.7M ± 23.8K 43.7M … 43.8M 56 (16%) ⚡- 95.6% ± 0.0%<br>cache_references 1.46M ± 14.6K 1.40M … 1.50M 19 ( 5%) ⚡- 94.3% ± 0.1%<br>cache_misses 142K ± 4.87K 127K … 157K 2 ( 1%) ⚡- 78.1% ± 0.4%<br>branch_misses 126K ± 1.37K 120K … 129K 12 ( 3%) ⚡- 86.3% ± 0.1%<br>It’s dramatic because before, build.zig logic was being executed with each zig build command, but now, the build system uses the cached, serialized configuration instead.<br>Aside from performance, I expect third-party tooling such as ZLS to benefit from consuming the serialized configuration file rather than maintaining a fork of the build runner.<br>This changeset heavily reworks the internal mechanism of the zig build system, however, it is mostly non-breaking from an API perspective, with the exceptions noted in the PR linked above.<br>For most people I’m guessing this is the main breaking change they’ll hit:<br>if (b.args) |args| {<br>run_cmd.addArgs(args);

⬇️<br>run_cmd.addPassthruArgs();

This removes a capability from build scripts since they can no longer observe those arguments. In exchange, it means that when changing those arguments, build scripts no longer must be rebuilt from source.<br>If you’re someone who wants to influence the direction of Zig, this is a good time to upgrade your projects to the development version and try out these changes. We’ll be releasing 0.17.0 within a couple weeks from now. However, if you don’t have time, and you find out that 0.17.0 broke your build, don’t worry, there will be plenty of opportunity to get fixes in for the 0.17.1 tag as well.

April 08, 2026<br>Incremental compilation with LLVM

Author: Matthew Lugg<br>I’ve been spending a bit of time working on personal projects after merging my type resolution changes last month, but I did find the time...

build process system from configuration maker

Related Articles