Troubleshooting
The build panics about the Zig cache
Zig cache is not writable. Set ZIG_GLOBAL_CACHE_DIR and ZIG_LOCAL_CACHE_DIR,
or enable direnv (see .envrc) for a portable setup.
The build checks for a writable cache directory before doing anything else. Set
both variables explicitly, or use the committed .envrc:
export ZIG_GLOBAL_CACHE_DIR="$PWD/.zig-cache-global"
export ZIG_LOCAL_CACHE_DIR="$PWD/.zig-cache"
The ./zig wrapper sets both for you.
A nested build fails with exit code 127
error: the following command exited with error code 127:
env ZAZA_EXAMPLES=package-producer ./zig build install
./zig is missing. It is gitignored, so a fresh clone does not have one. Run
./setup.sh, which creates it.
Affected targets: package-consumer, cross-compile-cli, rust-interop, and
example-matrix.
CMake complains that the cache directory does not match
CMake Error: The current CMakeCache.txt directory .../deps/json/build/Debug/CMakeCache.txt
is different than the directory .../deps/json/build/Debug where CMakeCache.txt was created.
CMake caches absolute paths. If the checkout moved, or the build tree was copied from another machine, every cached path is wrong. Delete the build tree for the dependency and rebuild:
rm -rf deps/<name>/build
The JUCE examples keep their build tree inside the example directory:
rm -rf examples/juce/build
rm -rf examples/zaza-juce/build
Source checkouts under deps/ are unaffected, so this does not force a re-clone.
A build seems to hang while configuring
It is probably resolving dependencies. Zig resolves everything declared in the graph before running any step, so enabling all examples means fetching JUCE, curl, mbedtls, zlib, spdlog, and fmt. Scope the build:
ZAZA_EXAMPLES=<name> zig build <target>
run-cpp fails on a file that compiles fine elsewhere
run-cpp invokes zig c++ by name, so Zig must be on PATH, and it passes no
include directories of its own. A file that includes a project header will fail:
examples/hello_zaza/src/main.cpp:2:10: fatal error: 'hello_zaza.h' file not found
Pass the flags yourself, after the source path:
zig build run-cpp -- src/simple_example.cpp -O2
ZAZA_PRESET=asan or ZAZA_PRESET=lto fails to link
Both are toolchain-dependent rather than broken. asan needs the AddressSanitizer
runtime to be available to the linker. lto needs the toolchain to be using LLD.
Neither is guaranteed on a given machine.
The C++20 modules example cannot find a compiler
The example does not use zig c++, because zig c++ rejects -x c++-module and
ignores -fmodule-output. It uses /opt/homebrew/opt/llvm/bin/clang++ by
default. Point it elsewhere:
ZAZA_MODULES_CXX=/path/to/clang++ zig build cxx20-modules-run
Benchmarks
benchmarks/ holds one benchmark. It generates a synthetic C++ project, builds
it with zig build and with CMake plus Ninja, and times the real processes:
zig build --build-file benchmarks/build.zig bench
It runs on 0.14.1 and 0.15.2. On 0.16.0 the step fails with a message, because
the harness uses std.process.Child.run, which 0.16 removed. Nothing in
zig build test or zig build example-matrix reaches this build file.
Four earlier files here (performance_benchmark.zig, memory_benchmark.zig,
scalability_benchmark.zig, cmake_comparison.zig) computed their results from
hardcoded constants instead of measuring anything, and did not compile. They
were deleted. See benchmarks/README.md for the details, and do not restore
them from history.
A tracked file changed after a build
Two files at the repo root are generated output and gitignored: CMakeLists.txt
and build/CMakeLists.txt. They are rewritten by whichever CMake-exporting
example built last. Leave them out of commits.
Note that the top-level build/ directory itself holds real tracked Zig sources
that build.zig imports. Only the generated CMake output inside it is ignored.
Which Zig versions actually work
0.14.1, 0.15.2 and 0.16.0. All three are verified against the full test suite:
Build Summary: 43/43 steps succeeded; 87/87 tests passed
The sources use spellings valid in all three. Where no shared spelling exists,
a if (comptime @hasDecl(...)) picks one: the std.Io filesystem move,
ArrayList.writer, Compile's add*/link* forwarders, and std.json's
unmanaged ObjectMap. Other versions may work and are not tested. setup.sh
warns when it sees one.