Traditional cross-compilation means installing a different toolchain for every target. Building for Windows? Install MinGW and pray the linker doesn't shit itself. ARM targets? Download some vendor's custom GCC that may or may not work with your project.
Zig downloads as one file. Everything's included - libc for every platform, cross-compilation support, the whole deal.
Target Specification
Zig uses architecture-os-abi
format. Simple enough:
zig build -Dtarget=x86_64-windows # Windows
zig build -Dtarget=aarch64-linux # ARM64 Linux
zig build -Dtarget=wasm32-freestanding # WebAssembly
zig build -Dtarget=arm-linux-musleabihf # ARM with musl
Run zig targets
to see what's supported. The list is massive.
Where It Actually Breaks
CLI Tools for Multiple Platforms
Used to need separate CI runners for each OS. Now one Linux runner builds everything:
zig build -Dtarget=x86_64-windows
zig build -Dtarget=aarch64-macos
zig build -Dtarget=x86_64-linux
Except Windows Defender flags your static binaries as malware. macOS won't run unsigned binaries without scary warnings. ARM64 builds work in QEMU but crash on real ARM hardware - emulation hides memory access bugs.
WebAssembly
Skip Emscripten. Zig compiles to WASM directly:
zig build-lib src/main.zig -target wasm32-freestanding -dynamic
No 500KB runtime overhead. But debugging WASM still sucks - browser tools show assembly, not your source. printf() doesn't exist, memory model is restrictive.
Embedded
Traditional embedded toolchains are vendor-specific hell. Zig works bare metal:
zig build-exe src/main.zig -target thumb-freestanding -mcpu cortex_m4
Still need to fight linker scripts and memory layouts. Hardware debugging requires expensive probes.
What Actually Happens
When you run zig build -Dtarget=aarch64-linux
, Zig picks the right libc, configures the linker, and generates the right machine code. Everything transparent.
Cross-Compiling C/C++ Code
Use zig cc
as a GCC replacement:
export CC=\"zig cc -target aarch64-linux-gnu\"
export CXX=\"zig c++ -target aarch64-linux-gnu\"
./configure && make
Works for simple C projects. Complex ones with autotools break in new and exciting ways. You'll spend more time debugging configure scripts than actual code.
Cross-compilation beats the old toolchain nightmare, but it's not magic. Platform bugs still exist, Windows Defender still flags your binaries, and timing issues still only show up on real hardware.