Documentation Index
Fetch the complete documentation index at: https://mintlify.com/ziglang/zig/llms.txt
Use this file to discover all available pages before exploring further.
Zig’s target system provides fine-grained control over the platform, architecture, ABI, and other target-specific settings for your build.
Target Overview
A target in Zig consists of:
- CPU Architecture - x86_64, aarch64, riscv64, etc.
- Operating System - linux, windows, macos, freestanding, etc.
- ABI - gnu, musl, msvc, etc.
- Object Format - elf, coff, macho, wasm, etc.
//! All the details about the machine that will be executing code.
//! Unlike `Query` which might leave some things as "default" or "host", this
//! data is fully resolved into a concrete set of OS versions, CPU features,
//! etc.
cpu: Cpu,
os: Os,
abi: Abi,
ofmt: ObjectFormat,
dynamic_linker: DynamicLinker = DynamicLinker.none,
Specifying Targets
Standard Target Options
The most common way to configure targets:
const target = b.standardTargetOptions(.{});
This allows users to specify targets via command line:
zig build -Dtarget=x86_64-linux-gnu
zig build -Dtarget=aarch64-macos
zig build -Dtarget=wasm32-wasi
zig build -Dtarget=riscv64-linux-musl
Default Target
Set a default target when none is specified:
const target = b.standardTargetOptions(.{
.default_target = .{
.ofmt = if (only_c) .c else null,
},
});
Explicit Target
Resolve a specific target directly:
const target = b.resolveTargetQuery(std.Target.Query.parse(.{
.arch_os_abi = "wasm32-wasi",
.cpu_features = "baseline-extended_const+nontrapping_bulk_memory_len0",
}) catch unreachable);
Target Components
CPU Architecture
Supported architectures include:
// Common architectures
.x86_64 // 64-bit x86
.x86 // 32-bit x86
.aarch64 // 64-bit ARM
.arm // 32-bit ARM
.riscv64 // 64-bit RISC-V
.riscv32 // 32-bit RISC-V
.wasm32 // WebAssembly 32-bit
.wasm64 // WebAssembly 64-bit
// Additional architectures
.powerpc64
.powerpc
.mips64
.mips
.sparc64
.s390x
.hexagon
.avr
.msp430
.bpf
.nvptx64
.spirv64
Operating Systems
pub const Tag = enum {
freestanding,
other,
contiki,
fuchsia,
hermit,
managarm,
haiku,
hurd,
illumos,
linux,
plan9,
rtems,
serenity,
dragonfly,
freebsd,
netbsd,
openbsd,
driverkit,
ios,
maccatalyst,
macos,
tvos,
visionos,
watchos,
windows,
uefi,
@"3ds",
ps3,
ps4,
ps5,
vita,
emscripten,
wasi,
amdhsa,
amdpal,
cuda,
mesa3d,
nvcl,
opencl,
opengl,
vulkan,
Darwin OS Detection
pub inline fn isDarwin(tag: Tag) bool {
return switch (tag) {
.driverkit,
.ios,
.maccatalyst,
.macos,
.tvos,
.visionos,
.watchos,
=> true,
else => false,
};
}
ABI (Application Binary Interface)
lib/std/Target.zig:739-766
pub const Abi = enum {
none,
gnu,
gnuabin32,
gnuabi64,
gnueabi,
gnueabihf,
gnuf32,
gnusf,
gnux32,
eabi,
eabihf,
ilp32,
android,
androideabi,
musl,
muslabin32,
muslabi64,
musleabi,
musleabihf,
muslf32,
muslsf,
muslx32,
msvc,
itanium,
simulator,
ohos,
ohoseabi,
- elf - Executable and Linkable Format (Linux, BSDs)
- coff - Common Object File Format (Windows)
- macho - Mach-O (macOS, iOS)
- wasm - WebAssembly
- c - C source code output
- hex - Intel HEX format
- raw - Raw binary
- spirv - SPIR-V (GPU shaders)
- plan9 - Plan 9 object format
OS Version Ranges
Version Range System
lib/std/Target.zig:372-377
pub const VersionRange = union {
none: void,
semver: std.SemanticVersion.Range,
hurd: HurdVersionRange,
linux: LinuxVersionRange,
windows: WindowsVersion.Range,
Windows Versions
lib/std/Target.zig:220-250
pub const WindowsVersion = enum(u32) {
nt4 = 0x04000000,
win2k = 0x05000000,
xp = 0x05010000,
ws2003 = 0x05020000,
vista = 0x06000000,
win7 = 0x06010000,
win8 = 0x06020000,
win8_1 = 0x06030000,
win10 = 0x0A000000,
win10_th2 = 0x0A000001,
win10_rs1 = 0x0A000002,
win10_rs2 = 0x0A000003,
win10_rs3 = 0x0A000004,
win10_rs4 = 0x0A000005,
win10_rs5 = 0x0A000006,
win10_19h1 = 0x0A000007,
win10_vb = 0x0A000008,
win10_mn = 0x0A000009,
win10_fe = 0x0A00000A,
win10_co = 0x0A00000B,
win10_ni = 0x0A00000C,
win10_cu = 0x0A00000D,
win11_zn = 0x0A00000E,
win11_ga = 0x0A00000F,
win11_ge = 0x0A000010,
win11_dt = 0x0A000011,
_,
/// Latest Windows version
pub const latest = WindowsVersion.win11_dt;
Linux Versions
lib/std/Target.zig:331-346
pub const LinuxVersionRange = struct {
range: std.SemanticVersion.Range,
glibc: std.SemanticVersion,
/// Android API level.
android: u32,
pub inline fn includesVersion(range: LinuxVersionRange, ver: std.SemanticVersion) bool {
return range.range.includesVersion(ver);
}
/// Checks if system is guaranteed to be at least `version` or older than `version`.
/// Returns `null` if a runtime check is required.
pub inline fn isAtLeast(range: LinuxVersionRange, ver: std.SemanticVersion) ?bool {
return range.range.isAtLeast(ver);
}
};
Default Version Ranges
lib/std/Target.zig:430-446
.linux => .{
.linux = .{
.range = .{
.min = .{ .major = 5, .minor = 10, .patch = 0 },
.max = .{ .major = 6, .minor = 17, .patch = 0 },
},
.glibc = .{ .major = 2, .minor = 31, .patch = 0 },
.android = 29,
},
},
CPU Features
Configure specific CPU features:
lib/std/Build.zig:628-634
const target = b.resolveTargetQuery(std.Target.Query.parse(.{
.arch_os_abi = "wasm32-wasi",
.cpu_features = "baseline-extended_const+nontrapping_bulk_memory_len0",
}) catch unreachable);
Feature syntax:
baseline - Default features for the architecture
+feature - Enable a feature
-feature - Disable a feature
Target-Specific Configuration
Querying Target Properties
if (target.result.os.tag == .windows) {
// Windows-specific configuration
exe.root_module.linkSystemLibrary("ws2_32", .{});
exe.root_module.linkSystemLibrary("version", .{});
}
if (target.result.os.tag.isDarwin()) {
// macOS/iOS-specific configuration
exe.headerpad_max_install_names = true;
}
if (target.result.cpu.arch == .wasm32) {
// WebAssembly-specific configuration
}
File Extensions
lib/std/Target.zig:99-109
pub fn exeFileExt(tag: Tag, arch: Cpu.Arch) [:0]const u8 {
return switch (tag) {
.windows => ".exe",
.uefi => ".efi",
.plan9 => arch.plan9Ext(),
else => switch (arch) {
.wasm32, .wasm64 => ".wasm",
else => "",
},
};
}
Library Extensions
lib/std/Target.zig:111-134
pub fn staticLibSuffix(tag: Tag, abi: Abi) [:0]const u8 {
return switch (abi) {
.msvc, .itanium => ".lib",
else => switch (tag) {
.windows, .uefi => ".lib",
else => ".a",
},
};
}
pub fn dynamicLibSuffix(tag: Tag) [:0]const u8 {
return switch (tag) {
.windows, .uefi => ".dll",
.driverkit,
.ios,
.maccatalyst,
.macos,
.tvos,
.visionos,
.watchos,
=> ".dylib",
else => ".so",
};
}
Multi-Target Builds
Build for multiple targets in a single build script:
const targets = [_]std.Target.Query{
.{ .cpu_arch = .x86_64, .os_tag = .linux, .abi = .gnu },
.{ .cpu_arch = .x86_64, .os_tag = .windows, .abi = .gnu },
.{ .cpu_arch = .aarch64, .os_tag = .macos },
.{ .cpu_arch = .wasm32, .os_tag = .wasi },
};
for (targets) |t| {
const resolved = b.resolveTargetQuery(t);
const exe = b.addExecutable(.{
.name = b.fmt("myapp-{s}-{s}", .{
@tagName(t.cpu_arch.?),
@tagName(t.os_tag.?),
}),
.root_module = b.createModule(.{
.root_source_file = b.path("src/main.zig"),
.target = resolved,
.optimize = .ReleaseFast,
}),
});
b.installArtifact(exe);
}
Common Target Patterns
Native Builds
// Build for the host machine
const exe = b.addExecutable(.{
.name = "tool",
.root_module = b.createModule(.{
.root_source_file = b.path("tools/tool.zig"),
.target = b.graph.host,
.optimize = .Debug,
}),
});
Freestanding Targets
const kernel = b.addExecutable(.{
.name = "kernel",
.root_module = b.createModule(.{
.root_source_file = b.path("src/kernel.zig"),
.target = b.resolveTargetQuery(.{
.cpu_arch = .x86_64,
.os_tag = .freestanding,
.abi = .none,
}),
.optimize = .ReleaseSmall,
}),
});
WebAssembly Targets
const wasm = b.addExecutable(.{
.name = "app",
.root_module = b.createModule(.{
.root_source_file = b.path("src/main.zig"),
.target = b.resolveTargetQuery(.{
.cpu_arch = .wasm32,
.os_tag = .wasi,
}),
.optimize = .ReleaseSmall,
}),
});
Target Resolution
The ResolvedTarget type contains the final, resolved target configuration:
/// Information about the native target. Computed before build() is invoked.
host: ResolvedTarget,
Key properties:
result - The fully resolved std.Target
query - The original target query
Advanced Target Features
Default ABI Selection
lib/std/Target.zig:795-812
pub fn default(arch: Cpu.Arch, os_tag: Os.Tag) Abi {
return switch (os_tag) {
.freestanding, .other => switch (arch) {
.arm,
.armeb,
.csky,
.hppa,
.mips,
.mipsel,
.powerpc,
.powerpcle,
.sh,
.sheb,
.thumb,
.thumbeb,
=> .eabi,
else => .none,
},
PIC Requirements
pub fn requiresPIC(target: *const std.Target, linking_libc: bool) bool {
return target.abi.isAndroid() or
target.os.tag == .windows or target.os.tag == .uefi or
osRequiresLibC(target) or
(linking_libc and target.isGnuLibC());
}
See Also