ziglang/zig
Cross compilation
Purpose
zig is famous for being a turnkey cross-compiler: zig build-exe -target x86_64-windows-gnu hello.zig works on a Linux laptop with no Windows SDK installed; zig cc -target aarch64-linux-musl ... works the same way for C. This page traces what makes that work.
What "cross compilation" needs
For any (host, target), the toolchain must provide:
- A backend that can emit code for the target ISA.
- Linker support for the target's object format.
- A C compiler when consuming
.cinputs (clang). - A libc and a C++ runtime for the target ABI.
- The right preprocessor headers (
stdarg.h, intrinsics, target-specific). - A compiler-rt for soft-fp / division / atomics where the target needs it.
- A target descriptor (CPU model, features, calling convention) that all of the above agree on.
zig ships all of this in one binary.
How each piece is provided
| Need | Where it comes from |
|---|---|
| Backend | src/codegen/llvm.zig (LLVM, all archs) or src/codegen/<arch>/CodeGen.zig (self-hosted). See Code generation backends. |
| Linker | src/link/<format>.zig plus src/link/Lld.zig. See Linkers. |
| C compiler | src/zig_clang_*.cpp glue + bundled clang. |
| libc | lib/libc/{glibc,musl,mingw,wasi,darwin,freebsd,netbsd}/. See Bundled libraries. |
| libc++ etc. | lib/libcxx/, lib/libcxxabi/, lib/libunwind/, lib/libtsan/. |
| Headers | lib/include/ (clang resource), lib/libc/include/ (POSIX), per-flavor headers. |
| compiler-rt | lib/compiler_rt/. See Compiler runtime. |
| Target descriptor | lib/std/Target.zig + lib/std/Target/<arch>.zig (CPU feature tables) generated by tools/update_cpu_features.zig. |
Selection at run time
src/main.zig parses -target <triple> (or -Dtarget=... in build.zig). The triple is resolved to a std.Target via lib/std/zig/target.zig. From there:
Compilation.createchooses a backend (LLVM vs self-hosted) persrc/target.zigcapability tables.lib/std/zig/LibCDirs.zigresolves which bundled libc tree to expose as the include path.src/link.zigpicks the rightlink.Filesubclass.src/codegen.zigdispatches to the per-arch backend.
CPU features
CPU model selection (-mcpu=...) is encoded as a base model plus a feature set. The feature tables under lib/std/Target/ are huge — they enumerate every architectural extension known to LLVM. They are regenerated by tools/update_cpu_features.zig (~76 KB) from LLVM's tablegen dumps.
Cross-compilation tests
test/c_abi/exercises the calling-convention path on a matrix of targets.test/standalone/includes self-contained projects that exercise specific cross targets.- The CI matrix in
.forgejo/workflows/ci.yamlruns the test suite onaarch64,loongarch64,riscv64,s390x,x86_64-linux,x86_64-freebsd,x86_64-windows, andaarch64-windows.
Caveats
- Some targets are LLVM-only at this commit (the self-hosted backend may be incomplete or skeleton).
src/target.zigandsrc/codegen.ziggate this. - Cross-linking against system-installed libraries (e.g. linking against the host's
libssl.sowhile targeting another OS) is not whatzigships for; the bundled trees are for libc and the C++ runtime, not arbitrary third-party libraries.
Key source files
| File | Purpose |
|---|---|
lib/std/Target.zig |
Target descriptor used everywhere. |
lib/std/Target/ |
Per-arch CPU feature tables. |
lib/std/zig/target.zig |
Triple parsing and host detection. |
lib/std/zig/LibCDirs.zig |
Where the libc include paths live. |
src/target.zig |
Compiler-side capability tables. |
src/codegen.zig |
Backend dispatch. |
src/link.zig |
Linker dispatch. |
tools/update_cpu_features.zig |
CPU feature table generator. |
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.