Reference
Targets
NullBuilder cross-compiles ReleaseSmall binaries from a JSON target matrix. CI defaults to three targets; nightly and release default to twelve across five OS families.
Default CI matrix (zig-ci.yml)#
| target | Runner | zig_target |
|---|---|---|
linux-x86_64 |
ubuntu-latest | x86_64-linux-musl |
macos-aarch64 |
macos-latest | aarch64-macos |
windows-x86_64 |
windows-latest | x86_64-windows |
Default nightly and release matrix#
| target | Runner | zig_target | Notes |
|---|---|---|---|
linux-x86_64 |
ubuntu-latest | x86_64-linux-musl |
|
linux-aarch64 |
ubuntu-latest | aarch64-linux-musl |
|
linux-arm32-gnu |
ubuntu-latest | arm-linux-gnueabihf |
|
linux-arm32-musl |
ubuntu-latest | arm-linux-musleabihf |
|
linux-riscv64 |
ubuntu-latest | riscv64-linux-musl |
|
android-aarch64 |
ubuntu-latest | aarch64-linux-android |
NDK build |
android-armv7 |
ubuntu-latest | arm-linux-androideabi |
zig_cpu: baseline+v7a |
android-x86_64 |
ubuntu-latest | x86_64-linux-android |
NDK build |
macos-aarch64 |
macos-latest | aarch64-macos |
|
macos-x86_64 |
macos-latest | x86_64-macos |
|
windows-x86_64 |
windows-latest | x86_64-windows |
ext: .exe |
windows-aarch64 |
windows-latest | aarch64-windows |
ext: .exe |
Linux binaries are musl-linked static builds except the arm32 gnu flavor. Everything is compiled with -Doptimize=ReleaseSmall and, for nightly and release, a -Dversion injected by the workflow.
Custom matrices#
Pass targets_json to override the matrix. Each entry needs os (runner label), target (your artifact name suffix) and zig_target (the Zig triple); zig_cpu and ext are optional. From the README — NullHub trims CI to four targets and adds Node for its UI build:
jobs:
zig:
uses: nullclaw/nullbuilder/.github/workflows/zig-ci.yml@v1
permissions:
contents: read
with:
binary_name: nullhub
artifact_prefix: nullhub
node_version: 22
node_cache_dependency_path: ui/package-lock.json
test_command: zig build test -Dembed-ui=false -Dbuild-ui=false --summary all
pre_build_command: |
npm --prefix ui ci --no-audit --no-fund
npm --prefix ui run build
build_args: -Dbuild-ui=false
e2e_command: bash tests/test_e2e.sh
targets_json: >-
[
{"os":"ubuntu-latest","target":"linux-x86_64","zig_target":"x86_64-linux-musl"},
{"os":"ubuntu-latest","target":"linux-aarch64","zig_target":"aarch64-linux-musl"},
{"os":"macos-latest","target":"macos-aarch64","zig_target":"aarch64-macos"},
{"os":"windows-latest","target":"windows-x86_64","zig_target":"x86_64-windows"}
]How Android builds work#
No Gradle. Targets whose name starts with android- get, on the Ubuntu runner:
- JDK 17 (Temurin) and the Android SDK.
- The NDK, installed via
sdkmanager --install "ndk;<version>"— default29.0.14206865. - A generated libc file pointing Zig at the NDK sysroot (
include_dir,sys_include_dir,crt_dirfor the API level).
The API level (default 24) is appended to the triple — e.g. aarch64-linux-android.24 — and the build runs as plain zig build -Dtarget=... --libc <file>. Override with android_api_level and android_ndk_version on the nightly and release workflows.
Artifact naming#
| Context | Name |
|---|---|
| CI artifact | <prefix>-<target> (contains the raw binary) |
| Nightly artifact | <prefix>-nightly-<short-sha>-<target>, binary named <prefix>-<target> plus metadata |
| Release asset | <prefix>-<target>.bin, or <prefix>-<target>.exe + .zip on Windows |
| Source archive | <prefix>-source-<tag>.tar.gz (when source_archive: true) |
<prefix> is artifact_prefix, falling back to binary_name. Workflow inputs are documented in Workflows.