- Zig 100%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
|
||
| src | ||
| tools | ||
| .gitignore | ||
| build.zig | ||
| build.zig.zon | ||
| README.md | ||
stereokit-zig
Warning
This project was generated by Claude, an AI model, and has not been tested. Use it at your own risk.
StereoKit for Zig. The package builds StereoKit from its pinned upstream sources with the Zig toolchain. It needs no CMake and no prebuilt binaries, and it links StereoKit statically into your executable. On top of that, a thin layer exposes the API in idiomatic Zig.
- Zig: 0.17.0
- StereoKit: 0.3.11
- Platforms: Linux x86_64 builds and runs. Windows x86_64 (
x86_64-windows-gnu) compiles the library, but linking and running an executable is untested.
Using it
zig fetch --save=stereokit https://git.ray.works/sfeng/stereokit-zig/archive/v0.1.1.tar.gz
// build.zig
const std = @import("std");
const stereokit = @import("stereokit");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const sk = b.dependency("stereokit", .{ .target = target, .optimize = .fast });
const exe = b.addExecutable(.{
.name = "app",
.root_module = b.createModule(.{
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
.imports = &.{.{ .name = "sk", .module = sk.module("stereokit") }},
}),
});
b.installArtifact(exe);
// Compile your .hlsl shaders and install them next to your assets.
const shaders = stereokit.addShaders(b, sk, .{
.root = b.path("assets/shaders"),
.files = &.{"my_shader.hlsl"},
.optimize = optimize,
});
b.installDirectory(.{ .source_dir = shaders, .install_dir = .bin, .install_subdir = "assets/shaders" });
}
// src/main.zig
const sk = @import("sk");
const App = struct {
window_pose: sk.Pose,
pub fn step(app: *App) void {
sk.ui.window("Hello", &app.window_pose, .{});
if (sk.ui.button("Quit")) sk.quit();
sk.ui.windowEnd();
}
};
pub fn main() !void {
try sk.init(.{ .app_name = "Hello" });
// Pose math calls into StereoKit, so it runs at runtime, not as a default.
var app: App = .{ .window_pose = .lookAt(.init(0, 0, -0.5), .zero) };
sk.run(&app);
}
On Linux the build needs the system development headers for EGL, gbm, X11, Xfixes and fontconfig.
Options
These are passed through b.dependency("stereokit", .{ ... }):
| Option | Default | |
|---|---|---|
target, optimize |
native, debug |
StereoKit is large C++, so pass .fast even for debug app builds. |
openxr |
.bundled |
.bundled compiles the Khronos loader in. .system links the OS's libopenxr_loader. |
What it provides
- Module
stereokit: the Zig layer. Importing it links the static library. - Module
stereokit_c: the raw translate-c bindings, also available asstereokit.c. - Artifact
StereoKitC: the static library. addShaders(): compiles.hlslfiles to.sks, as StereoKit's NuGet package does for C#.
The Zig layer
The layer keeps StereoKit's names and concepts, so the C# documentation still applies. It changes only what C makes awkward:
bool32_tbecomesbool, and C enums become Zig enums.- Math is value types with methods. Rotations and matrices call StereoKit's own C code, so conventions match exactly: -Z is forward, and
mulfollows C#'s operand order. - Default arguments become option structs.
- Missing assets become errors.
- Asset handles have an explicit
release(): every constructor, includingfind, returns a reference you own. sk.run(&app)drives any struct with astepmethod, which may return an error, and an optionalshutdownmethod.sk.frameFmtformats strings into scratch memory that is reset each frame, for immediate-mode labels.
| File | Contents |
|---|---|
stereokit.zig |
init, run, quit, time, frameFmt, and re-exports. |
math.zig |
Vec2/3/4, Quat, Matrix, Pose, Ray, Bounds. |
color.zig |
Color and Color32. |
asset.zig |
Tex, Shader, Material, Mesh, Vertex, Model, Sound, Sprite. |
ui.zig |
Windows, buttons, radio, toggle, text, input, slider, layout, tint and theme. |
input.zig |
Head, eyes, controllers, hand visibility. |
draw.zig |
Lines, world text, the transform hierarchy, screenshots. |
log.zig |
Formatted logging, plus stdLogFn to route std.log through StereoKit. |
interop.zig |
Conversions to and from C types, with comptime layout checks. |
Only part of the API is wrapped so far. Everything else is reachable through sk.c.
How the build works
The build.zig.zon pins StereoKit and exactly the dependency versions that StereoKit's CMake build pins: sk_gpu, the OpenXR SDK, meshoptimizer and basis_universal. build.zig then:
- Compiles StereoKit's built-in shaders into C headers with the prebuilt
skshadercfrom the sk_gpu release. - Compiles StereoKitC, the basis_universal transcoder and meshoptimizer, and, by default, the OpenXR loader. Physics (ReactPhysics3D) is not built.
- Runs translate-c over a C-compatible copy of the public headers.
Upstream quirks it works around, each commented where it lives:
- No executable bit. Zig's fetcher drops Unix permissions from zip archives, so
skshadercis copied with the executable bit set (tools/copy_executable.zig). - Header bug.
stereokit.h0.3.11 is not valid C, becausesk_quithas a C++ default argument.tools/patch_header.zigfixes it before translate-c, and fails loudly once upstream fixes the header. - Silent
skshadercfailures. It exits 0 even when it rejects its arguments.-itakes a separate argument, and-oneeds a trailing slash to mean a folder. - Missing headers on Zig. Zig is never MSVC, so StereoKit's bundled DirectXMath headers (
lib/include_no_win) are used on every target. Windows also needs_USE_MATH_DEFINES.
Upgrading StereoKit
- Run
zig fetch --save=stereokit_src <new tarball url>. Update the other dependencies to the commits pinned in the new release'sCMakeLists.txt. - Diff that
CMakeLists.txtagainst the source lists and defines inbuild.zig. - Run
zig build test. It checks that every wrapper type's layout matches its C twin and exercises the math against StereoKit.patch_headerreports any fixes that are no longer needed.
Development
zig build # builds the static library into zig-out/lib
zig build test
zig fmt --check build.zig src tools
zlint src tools