An opinionated build tool for Zig projects.
zbuild
is a command-line build tool designed to simplify and enhance the build process for Zig projects. It leverages a ZON-based configuration file (zbuild.zon
) to define project builds declaratively, generating a corresponding build.zig
and build.zig.zon
file that integrates seamlessly with Zig’s native build system. This approach reduces the complexity of writing and maintaining Zig build scripts manually, offering a structured alternative for managing dependencies, modules, executables, libraries, tests, and more.
Note: zbuild
is under active development. Some features are incomplete or subject to change. Check the docs/TODO.md
file for planned enhancements.
- ZON-based Configuration: Define your build in a
zbuild.zon
file instead of writing Zig code directly. - Automatic build.zig Generation: Create a
build.zig
andbuild.zig.zon
file from your configuration. - Comprehensive Build Support: Manage dependencies, modules, executables, libraries, objects, tests, formatting, and run commands.
- Command-Line Interface: Execute common build tasks like compiling executables, running tests, and formatting code.
Currently, zbuild must be built from source:
- Clone the repository:
git clone https://github.com/chainsafe/zbuild.git
cd zbuild
- Build the executable:
zig build -Doptimize=ReleaseFast
- (Optional) Install it globally:
zig build install --prefix ~/.local
A pre-built binary distribution is planned for future releases once sufficient feature-completeness is achieved.
zbuild
provides a command-line interface with various commands to manage your Zig projects. Below is the general syntax and a list of available commands:
Usage: zbuild [global_options] [command] [options]
init
: Initialize a new Zig project with a basiczbuild.zon
,build.zig
,build.zig.zon
, andsrc/main.zig
in the current directory.fetch
: Copy a package into the global cache and optionally add it tozbuild.zon
andbuild.zig.zon
install
: Install all artifacts defined inzbuild.zon
.uninstall
: Uninstall all artifacts.sync
: Synchronizebuild.zig
andbuild.zig.zon
withzbuild.zon
.build
: Runzig build
with the generatedbuild.zig
.build-exe <name>
: Build a specific executable defined inzbuild.zon
.build-lib <name>
: Build a specific library.build-obj <name>
: Build a specific object file.build-test <name>
: Build a specific test into an executable.run <name>
: Run an executable or a custom run script.test [name]
: Run all tests or a specific test.fmt [name]
: Format code for all or a specific formatting target.help
: Print the help message and exit.version
: Print the version number and exit.
--project-dir <path>
: Set the project directory (default:.
).--zbuild-file <path>
: Specify the configuration file (default:zbuild.zon
).--no-sync
: Skip automatic synchronization ofbuild.zig
andbuild.zig.zon
.
-h, --help
: Print command-specific usage.
For command-specific options (e.g., fetch
), use zbuild --help.
The zbuild.zon
file is the heart of the zbuild system. It defines your project’s structure and build settings. Below is an example configuration:
.{
.name = .example_project,
.version = "1.2.3",
.description = "A comprehensive example",
.fingerprint = 0x90797553773ca567,
.minimum_zig_version = "0.14.0",
.paths = .{ "build.zig", "build.zig.zon", "src" },
.keywords = .{"example"},
.dependencies = .{
.mathlib = .{
.path = "deps/mathlib",
},
.network = .{
.url = "https://github.com/example/network/archive/v1.0.0.tar.gz",
},
},
.options_modules = .{
.build_options = .{
.max_depth = .{
.type = "usize",
.default = 100,
},
},
},
.modules = .{
.utils = .{
.root_source_file = "src/utils/main.zig",
.imports = .{.mathlib, .build_options},
.link_libc = true,
},
.core = .{
.root_source_file = "src/core/core.zig",
.imports = .{.utils},
},
},
.executables = .{
.main_app = .{
.root_module = .{
.root_source_file = "src/main.zig",
.imports = .{.core, .network},
},
},
},
.libraries = .{
.libmath = .{
.version = "0.1.0",
.root_module = .utils,
.linkage = .static,
},
},
.tests = .{
.unit_tests = .{
.root_module = .{
.root_source_file = "tests/unit.zig",
.imports = .{.core, .utils},
},
},
},
.fmts = .{
.source = .{
.paths = .{"src", "tests"},
.exclude_paths = .{"src/generated"},
.check = true,
},
},
.runs = .{
.start_server = "zig run src/server.zig",
.build_docs = "scripts/build_docs.sh",
},
}
name
,version
,fingerprint
,minimum_zig_version
,paths
: Project metadata (required).dependencies
: External packages (path or URL).options_modules
: Configurable build options bundled into modules.modules
: Reusable code units with optional imports and build settings.executables
,libraries
,objects
: Build targets with root modules.tests
: Test targets with optional filters.fmts
: Code formatting rules.runs
: Custom shell commands.
Here’s a step-by-step example to create and build a simple Zig project with zbuild:
- Initialize the project:
mkdir myproject
cd myproject
zbuild init
- (Optional) Inspect
zbuild.zon
.{
.name = .myproject,
.version = "0.1.0",
.fingerprint = 0x<generated>,
.minimum_zig_version = "0.14.0",
.paths = .{ "build.zig", "build.zig.zon", "src" },
.executables = .{
.myproject = .{
.root_module = .{
.root_source_file = "src/main.zig",
},
},
},
}
- Update
src/main.zig
const std = @import("std");
pub fn main() !void {
const allocator = std.heap.page_allocator;
const args = try std.process.argsAlloc(allocator);
defer std.process.argsFree(allocator, args);
const arg = if (args.len >= 2) args[1] else "zbuild";
std.debug.print("Hello {s}!\n", .{arg});
}
- (Optional) Build the Executable:
zbuild build-exe myproject
This builds the myproject
executable into zig-out/bin
.
- Run the Executable:
zbuild run myproject -- world
Outputs: Hello, world!
Add a dependency to your project:
zbuild fetch --save=example https://github.com/example/repo/archive/v1.0.0.tar.gz
This updates zbuild.zon
with:
.dependencies = .{
.example = {
.url = "https://github.com/example/repo/archive/v1.0.0.tar.gz,
}
}
And synchronizes build.zig.zon
with the fetched hash.
Contributions are welcome! To contribute:
- Fork the repository on GitHub: https://github.com/chainsafe/zbuild.
- Create a branch for your changes.
- Submit a pull request with a clear description of your improvements.
Please open an issue first to discuss significant changes or report bugs.
MIT