This skill should be used when the user asks questions like "how does build.zig work", "how to add dependencies in Zig", "explain Zig build system", "how to cross-compile in Zig", "what are Zig build modes", "how to create build steps", or generally asks about Zig's build system and package management.
Explains Zig's built-in build system for creating cross-compiled executables with dependencies.
/plugin marketplace add surt666/zig-support/plugin install surt666-zig-support@surt666/zig-supportThis skill inherits all available tools. When active, it can use any tool Claude has access to.
references/build-examples.mdreferences/dependency-management.mdThis skill explains Zig's built-in build system for experienced programmers. Unlike Make, CMake, or other external build tools, Zig's build system is written in Zig itself (build.zig). The build system provides cross-compilation, dependency management, and flexible build configuration out of the box.
Target Zig version: 0.15.2
Every Zig project has a build.zig file at the root:
const std = @import("std");
pub fn build(b: *std.Build) void {
// Build configuration goes here
}
The build() function receives a *std.Build pointer providing the build API.
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const exe = b.addExecutable(.{
.name = "my-app",
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});
b.installArtifact(exe);
}
Build the executable:
zig build
# Output: zig-out/bin/my-app
Key components:
standardTargetOptions(): Cross-compilation target (from CLI: zig build -Dtarget=...)standardOptimizeOption(): Build mode (from CLI: zig build -Doptimize=...)addExecutable(): Creates executable artifactinstallArtifact(): Copies to output directory (zig-out/)pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
// Static library
const lib = b.addStaticLibrary(.{
.name = "mylib",
.root_source_file = b.path("src/lib.zig"),
.target = target,
.optimize = optimize,
});
b.installArtifact(lib);
// Executable that links the library
const exe = b.addExecutable(.{
.name = "my-app",
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});
exe.linkLibrary(lib); // Link against our library
b.installArtifact(exe);
}
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
// Main executable
const exe = b.addExecutable(.{
.name = "my-app",
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});
b.installArtifact(exe);
// Unit tests
const unit_tests = b.addTest(.{
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});
const run_tests = b.addRunArtifact(unit_tests);
const test_step = b.step("test", "Run unit tests");
test_step.dependOn(&run_tests.step);
}
Run tests:
zig build test
Zig has four build modes controlling optimization and safety:
| Mode | Flag | Optimizations | Safety Checks | Use Case |
|---|---|---|---|---|
| Debug | -Doptimize=Debug | None | All enabled | Development, debugging |
| ReleaseSafe | -Doptimize=ReleaseSafe | Yes | All enabled | Production with safety |
| ReleaseFast | -Doptimize=ReleaseFast | Maximum | Disabled | Production, performance |
| ReleaseSmall | -Doptimize=ReleaseSmall | Size | Disabled | Embedded, size-critical |
Examples:
zig build # Debug (default)
zig build -Doptimize=ReleaseSafe # Safe release
zig build -Doptimize=ReleaseFast # Fast release
zig build -Doptimize=ReleaseSmall # Small release
Choosing a mode:
Zig excels at cross-compilation—build for any target from any host.
Targets specified as: <arch>-<os>-<abi>
Examples:
# Linux ARM64
zig build -Dtarget=aarch64-linux
# Windows x86_64
zig build -Dtarget=x86_64-windows
# macOS ARM64 (M1/M2)
zig build -Dtarget=aarch64-macos
# WebAssembly
zig build -Dtarget=wasm32-freestanding
# Native (host system)
zig build -Dtarget=native
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
// Query target properties
if (target.result.cpu.arch == .wasm32) {
// WebAssembly-specific configuration
}
if (target.result.os.tag == .windows) {
// Windows-specific configuration
}
const exe = b.addExecutable(.{
.name = "my-app",
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = b.standardOptimizeOption(.{}),
});
b.installArtifact(exe);
}
pub fn build(b: *std.Build) void {
const targets = [_]std.Target.Query{
.{ .cpu_arch = .x86_64, .os_tag = .linux },
.{ .cpu_arch = .x86_64, .os_tag = .windows },
.{ .cpu_arch = .aarch64, .os_tag = .macos },
};
for (targets) |target_query| {
const target = b.resolveTargetQuery(target_query);
const exe = b.addExecutable(.{
.name = "my-app",
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = .ReleaseSafe,
});
b.installArtifact(exe);
}
}
Zig 0.15.2 uses .zon (Zig Object Notation) files for dependency declaration.
build.zig.zon:
.{
.name = "my-app",
.version = "0.1.0",
.dependencies = .{
.@"some-lib" = .{
.url = "https://github.com/user/some-lib/archive/v1.0.0.tar.gz",
.hash = "1220abcdef...", // Content hash
},
},
.paths = .{
"build.zig",
"build.zig.zon",
"src",
},
}
build.zig:
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
// Get dependency
const some_lib = b.dependency("some-lib", .{
.target = target,
.optimize = optimize,
});
const exe = b.addExecutable(.{
.name = "my-app",
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});
// Add module from dependency
exe.root_module.addImport("some-lib", some_lib.module("some-lib"));
b.installArtifact(exe);
}
Using in code (src/main.zig):
const some_lib = @import("some-lib");
pub fn main() !void {
some_lib.doSomething();
}
# Fetch all dependencies
zig build
# Or explicitly
zig fetch --save https://github.com/user/some-lib/archive/v1.0.0.tar.gz
Zig automatically downloads and caches dependencies.
pub fn build(b: *std.Build) void {
const exe = b.addExecutable(.{
.name = "my-app",
.root_source_file = b.path("src/main.zig"),
.target = b.standardTargetOptions(.{}),
.optimize = b.standardOptimizeOption(.{}),
});
b.installArtifact(exe);
// Run step
const run_cmd = b.addRunArtifact(exe);
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| {
run_cmd.addArgs(args);
}
const run_step = b.step("run", "Run the application");
run_step.dependOn(&run_cmd.step);
}
Usage:
zig build run
zig build run -- arg1 arg2 # Pass arguments
pub fn build(b: *std.Build) void {
// ... executable setup ...
// Custom step: Generate code
const gen_step = b.step("generate", "Generate code");
const gen_cmd = b.addSystemCommand(&[_][]const u8{
"python3",
"scripts/generate.py",
});
gen_step.dependOn(&gen_cmd.step);
}
Usage:
zig build generate
Pass compile-time configuration:
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
// Create build options
const options = b.addOptions();
options.addOption(bool, "enable_logging", b.option(
bool,
"enable_logging",
"Enable logging (default: false)",
) orelse false);
const exe = b.addExecutable(.{
.name = "my-app",
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});
exe.root_module.addOptions("config", options);
b.installArtifact(exe);
}
Using in code:
const config = @import("config");
pub fn main() !void {
if (config.enable_logging) {
std.debug.print("Logging enabled\n", .{});
}
}
Build with option:
zig build -Denable_logging=true
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const exe = b.addExecutable(.{
.name = "my-app",
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});
// Platform-specific linking
if (target.result.os.tag == .windows) {
exe.linkSystemLibrary("ws2_32"); // Windows sockets
} else {
exe.linkSystemLibrary("c");
}
b.installArtifact(exe);
}
pub fn build(b: *std.Build) void {
// Install executable
const exe = b.addExecutable(.{
.name = "my-app",
.root_source_file = b.path("src/main.zig"),
.target = b.standardTargetOptions(.{}),
.optimize = b.standardOptimizeOption(.{}),
});
b.installArtifact(exe);
// Install additional files
b.installFile("config.json", "config.json");
b.installDirectory(.{
.source_dir = b.path("assets"),
.install_dir = .prefix,
.install_subdir = "assets",
});
}
pub fn build(b: *std.Build) void {
const exe = b.addExecutable(.{
.name = "my-app",
.root_source_file = b.path("src/main.zig"),
.target = b.standardTargetOptions(.{}),
.optimize = b.standardOptimizeOption(.{}),
});
// Link system C library
exe.linkSystemLibrary("curl");
// Link libc
exe.linkLibC();
b.installArtifact(exe);
}
Default output structure:
zig-out/
├── bin/ # Executables
├── lib/ # Libraries
└── include/ # Headers (for C libraries)
Custom output directory:
zig build --prefix /custom/path
# Build project (Debug mode)
zig build
# Build with optimization
zig build -Doptimize=ReleaseFast
# Cross-compile
zig build -Dtarget=x86_64-windows
# Run tests
zig build test
# Run application
zig build run
# Clean build artifacts
rm -rf zig-out zig-cache
# List available build steps
zig build --help
standardTargetOptions() and standardOptimizeOption(): Enables CLI configurationrun and test steps: Standard across Zig projectsb.option()src/ for source, build.zig at root.zonb.path() for file paths: Portable path handlingFor detailed examples and advanced patterns:
references/build-examples.md - Complete build.zig examples for common scenariosreferences/dependency-management.md - Advanced dependency patterns, vendoring, local packages| Task | Command |
|---|---|
| Build project | zig build |
| Build optimized | zig build -Doptimize=ReleaseFast |
| Cross-compile | zig build -Dtarget=x86_64-windows |
| Run tests | zig build test |
| Run app | zig build run |
| Add dependency | Edit build.zig.zon, run zig build |
| Custom step | zig build <step-name> |
| List steps | zig build --help |
Zig's build system is:
Master build.zig to create portable, cross-platform Zig projects with minimal configuration.
This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.
This skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs guidance on slash command structure, YAML frontmatter fields, dynamic arguments, bash execution in commands, user interaction patterns, or command development best practices for Claude Code.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.