Skip to content

Latest commit

 

History

68 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Azazel

CI Zig

Azazel is a deterministic, declarative build-model layer for Zig. CUE validates a stable project model; Azazel generates typed Zig build data; Zig remains the build executor.

project.cue  ->  CUE validation  ->  build_spec.zig  ->  std.Build  ->  artifacts
    human          constraints          typed IR          Zig

The point is not to hide Zig. The point is to keep project configuration stable while Azazel absorbs std.Build API churn, and to make the build graph available as validated data for analysis, tooling, compatibility work, and eventually safe remote caching.

Production status

The core build pipeline is production-supported on Zig 0.14.1, 0.15.2, and 0.16.0. CI runs the same canonical CLI path users run, forces code generation twice to verify determinism, builds, and runs the test suites on every supported lane.

Azazel is still pre-1.0. Pin the revision or release you adopt and upgrade deliberately. The exact support contract and release gate are in docs/PRODUCTION.md.

The shared artifact cache is experimental and disabled by default. It must not be used for release artifacts until its key proves a complete input closure. See CACHE.md.

What it looks like

package build

core: #Module & {
    kind: "module"
    root: "src/core.zig"
}

app: #Module & {
    kind:    "exe"
    root:    "src/main.zig"
    deps:    ["core"]
    profile: "release"
}

For a pure Zig dependency, kind: "module" is consumed through @import and produces no separate artifact. ABI-linked static/shared libraries remain available for C/C++ interoperability and explicit binary boundaries.

Quick start

Prerequisites are Zig, CUE, and Python 3.

brew install cue zig
git clone https://github.com/godofecht/azazel.git
cd azazel
./setup.sh

The canonical CLI is the root azazel script:

python3 azazel check              # validate CUE, exported contract, roots, graph
python3 azazel gen                # generate build_spec.zig
python3 azazel build              # check + generate + zig build
python3 azazel build -Dfoo=true   # forward normal Zig build arguments
python3 azazel info               # print the resolved build model
python3 azazel clean

The CLI does not contain a second generator. gen_build_spec.sh is the single CUE-to-Zig implementation used by both direct and CLI workflows.

The equivalent low-level path is:

./gen_build_spec.sh
zig build
zig build test --summary all

Why a build model

A hand-written build.zig is executable build logic. Azazel moves the project description into a validated model and keeps the compatibility/execution layer separate.

That gives the project a representation which can be checked before compilation, diffed as data, consumed by editor tooling, replayed against multiple Zig lanes, translated into a build graph, and pressure-tested against real repositories without treating arbitrary build-script behavior as the configuration format.

The generated build_spec.zig is typed Zig source. The executor does not parse JSON at build time.

Supported module surface

#Module currently models:

Field Purpose
kind exe, static, shared, or module-only target
root Zig root source file
artifact_name Produced artifact name when it differs from the graph/import name
deps Internal module dependencies
profile Debug or release optimization profile
link import or ABI consumption
pre, post Explicit build-time commands
install_dirs Runtime/resource directory staging
pkg_imports Zig package module imports
pkg_artifacts Artifacts exported by Zig packages
pkg_library_paths Package-provided library search paths
build_options User-selectable typed build options
option_values Fixed typed values injected into an options module
gen_imports Zig modules generated by declared host tools
build_options_import Import name for generated build options
native C sources, includes, objects, system libraries, frameworks, libc/libc++ linkage

The full schema is in schema.cue and the worked reference is in docs/WIKI.md.

A field is considered implemented only when it survives all four layers: schema, CUE export, generated spec, and Zig executor. python3 azazel check validates the exported module contract so silently dropped fields fail before compilation.

Zig compatibility

Projects may declare accepted lanes:

toolchain: zig: {
    lanes: ["0.14", "0.15", "0.16"]
    preferred: "0.15"
}

The generated build spec records those lanes and build.zig rejects an unsupported Zig lane before doing real build work.

Release CI currently covers 0.14.1, 0.15.2, and 0.16.0. Zig 0.17 support exists for corpus work but remains best-effort while 0.17 is a moving development target.

Import and ABI graphs

Azazel distinguishes two internal dependency shapes.

link: "import" merges a Zig dependency into the consumer compilation and exposes it through @import("name"). It avoids a separate artifact/link step and is the normal choice for pure Zig module edges.

link: "abi" keeps a separately compiled artifact and links it across an ABI boundary. Shared libraries are always ABI targets. This is the appropriate shape for C/C++ interoperability and deliberate binary boundaries.

Large projects can combine the two into clusters: import-connected modules inside a cluster, with ABI boundaries between clusters. See examples/06-clusters.

Real-project pressure testing

Azazel maintains a corpus built around ZLS, libxev, River, Mach, MicroZig, libvaxis, Capy, zig-gamedev, TigerBeetle, and Ghostty. The corpus is used to discover missing build-model primitives and toolchain/API failure modes.

Executable parity is claimed only for modeled target slices that actually compile through the Azazel-generated graph. An upstream project's own successful zig build is tracked separately and is not reported as Azazel replacement parity.

See docs/HUGE_PROJECT_CORPUS.md.

Experimental and dogfood components

The production build path does not depend on the shared cache, corpus automation, IDE prototypes, or Danzig.

cache_build.sh is an explicitly gated cache experiment. tools/huge_corpus.py is validation/research infrastructure. ide/ contains editor experiments. src/danzig/ is retained as a substantial integration/dogfood workload rather than as part of Azazel's build-system API.

Keeping those boundaries explicit is intentional: experimental surfaces may inform the build model without silently becoming production dependencies.

Documentation

The complete reference lives in docs/WIKI.md. Production guarantees are defined in docs/PRODUCTION.md. Contribution requirements are in CONTRIBUTING.md, and security reporting guidance is in SECURITY.md.

The generated documentation site is published from the repository's documentation sources on GitHub Pages.

Zaza

Azazel is the declarative configuration frontend for Zaza, a Zig-driven build system for C, C++, Zig, CMake interoperability, and WebAssembly. Azazel can also be used directly for Zig projects.

License

MIT

About

CUE + Zig deterministic build system. No JSON runtime, no flags, no ceremony.

Topics

Resources

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages