Open-Source Wikis

/

Zig

/

Features

/

Cross compilation

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:

  1. A backend that can emit code for the target ISA.
  2. Linker support for the target's object format.
  3. A C compiler when consuming .c inputs (clang).
  4. A libc and a C++ runtime for the target ABI.
  5. The right preprocessor headers (stdarg.h, intrinsics, target-specific).
  6. A compiler-rt for soft-fp / division / atomics where the target needs it.
  7. 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.create chooses a backend (LLVM vs self-hosted) per src/target.zig capability tables.
  • lib/std/zig/LibCDirs.zig resolves which bundled libc tree to expose as the include path.
  • src/link.zig picks the right link.File subclass.
  • src/codegen.zig dispatches 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.yaml runs the test suite on aarch64, loongarch64, riscv64, s390x, x86_64-linux, x86_64-freebsd, x86_64-windows, and aarch64-windows.

Caveats

  • Some targets are LLVM-only at this commit (the self-hosted backend may be incomplete or skeleton). src/target.zig and src/codegen.zig gate this.
  • Cross-linking against system-installed libraries (e.g. linking against the host's libssl.so while targeting another OS) is not what zig ships 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.

Cross compilation – Zig wiki | Factory