My personal notes for building zig 0.12.0-dev.xxxx on an M2 Max.
This setup should work on any M1 or M2 Mac, but you must check other models yourself. Currently it also works on an Intel Mac, with one small difference: homebrew has a different default path there.
DO YOU REALLY NEED TO BUILD FROM SOURCE?
"First of all, if your goal is to install a specific version of Zig, you can find pre-built tarballs on the download page. You could also try installing Zig from a package manager. Finally, there is zig-bootstrap to cross-compile an installation of Zig from source for any target. When using zig-bootstrap, be sure to check out the git tag corresponding to the version you want to build, as master branch is not kept in any coherent state."
https://github.com/ziglang/zig/wiki/Building-Zig-From-Source
https://github.com/ziglang/zig/wiki/Troubleshooting-Build-Issues.
BUILDING FROM SOURCE ON A MAC
Below, I describe how to build using the Homebrew package manager + cmake with a few Mac-specific flags. There may be better and less common methods, but this is what most Mac developers are likely to use.
MY TEST MACHINE
➜ ~ system_profiler SPHardwareDataType | grep "Chip:" | cut -c 13-30
system_profiler SPHardwareDataType | grep "Memory:" | cut -c 15-19
system_profiler SPHardwareDataType | grep " Total Number of Cores:" | cut -c 7-66
Apple M2 Max
96 GB
Total Number of Cores: 12 (8 performance and 4 efficiency)
➜
➜ ~ sw_vers; clang --version
ProductName: macOS
ProductVersion: 13.5
BuildVersion: 22G74
Homebrew clang version 16.0.6
Target: arm64-apple-darwin22.6.0
Thread model: posix
InstalledDir: /opt/homebrew/opt/llvm/bin
MY BUILD ENVIRONMENT
I use the latest major version of macOS. Generally I also update to the latest minor version + any security updates. The two previous major versions of macOS should work (but I don't test that).
The latest version of XCode Command Line Tools must be installed. They are part of the latest Apple XCode IDE, but can also be installed separately.
Use Homebrew to install Mac-specific dependencies 'zlib' and 'zstd'. Then install LLVM 16.0 or later. Note! Don't allow brew update to LLVM 17 before zig is ready - that will break your zig build! Tip: you can prevent brew from automatically updating to latest with 'brew pin llvm'.
> brew install zlib; brew install zstd; brew install llvm;
Make sure Homebrew LLVM is first in your path by adding this line to your shell profile (probably '.zshrc'). Restart you shell or source the profile after saving the file.
export PATH=/opt/homebrew/opt/llvm/bin:$PATH
Note! On an Intel Mac use "/usr/local/opt" instead of "/opt/homebrew/opt/".
INSTALL THE LATEST ZIG VERSION
Get the latest source code from the zig Github repo. If you want to send pull requests, consider creating your own fork.
> git clone [email protected]:ziglang/zig.git
Go to the folder where you cloned Zig and pull the latest code. Create an empty build folder, then clean both global and local zig cache.
> git pull
> rm -rf build; mkdir build; rm -rf ~/.cache/zig; rm -rf zig-cache
Specify that you want to use a statically linked homebrew-installed LLVM. Also add a special flag for the 'zstd' dependency. These Mac-specific build flags are currently necessary. The 'make -j9' parameter is optional but makes builds faster if you have enough CPU cores.
Now build and install a zig binary.
> cd build; cmake .. -DCMAKE_PREFIX_PATH="$(brew --prefix llvm);$(brew --prefix zstd)" -DZIG_STATIC_LLVM=on; make -j9; make install
For macOS and cmake, there are currently 44 build warnings. The build process is under active development and these are still expected. At the end, a successful build should look similar to this:
... build details omitted
/Users/jonas/src/zig/zig/build/zig2.c:2897543:23: warning: incompatible pointer types passing 'uintptr_t *' (aka 'unsigned long *') to parameter of type 'uint64_t *' (aka 'unsigned long long *') [-Wincompatible-pointer-types]
t5.f1 = zig_subo_u64(&t5.f0, t4, t0, UINT8_C(64));
^~~~~~
/Users/jonas/src/zig/zig/stage1/zig.h:670:43: note: passing argument to parameter 'res' here
static inline bool zig_subo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8_t bits) {
^
44 warnings generated.
[ 94%] Linking CXX executable zig2
[ 94%] Built target zig2
[100%] Building stage3
[100%] Built target stage3
[ 36%] Built target zigcpp
[ 47%] Built target zig-wasm2c
[ 68%] Built target zig1
[ 94%] Built target zig2
[100%] Built target stage3
Install the project...
-- Install configuration: "Debug"
Now add an alias for your Zig binary. Change the line below to use your path and put it in '.zshrc'. Absolute path is required, the last part must be 'build/stage3/bin/zig'.
alias zig=/Users/jonas/src/zig/zig/build/stage3/bin/zig
CHECK THAT IT WORKS
Verify that your zig alias points at the the binary you just built.
➜ build git:(master) stage3/bin/zig version
0.12.0-dev.60+a190582b2
➜ build git:(master) cd
➜ ~ which zig
zig: aliased to /Users/jonas/src/zig/zig/build/stage3/bin/zig
➜ ~ zig version
0.12.0-dev.60+a190582b2
Test your new binary with a simple sanity check. Note! Run tests from your build folder, so tests can find the source code.
➜ build git:(master) zig build test-behavior -Dskip-non-native --summary all
Build Summary: 30/30 steps succeeded
... detailed output omitted
There should be no errors. To see if any tests were skipped, you can run this.
➜ zig test ../test/behavior.zig -I../test
... details of skipped tests omitted
1695 passed; 100 skipped; 0 failed.
If you feel ambitious, check if all behavior tests, regardless of platform, run without errors. This takes much longer. There is currently only one failure, and that could be a test artifact.
➜ build git:(master) zig build test-behavior
run test behavior-x86_64-macos-none-Debug-selfhosted: error: the following command terminated with signal 10 (expected exited with code 0):
... detailed output omitted