
* all: build: fix sdkPath for relative @src.file
Prior to this commit, the build system heavily assumed that the result
`@src.file` would always be absolute, but this is no longer
guaranteed, likely due to there being no such thing as an "absolute
path" in WASI.
It appears that for normal invocations of `zig build`, it is safe to
assume that `@src.file` is absolute. However, when ZLS uses a custom
`build_runner.zig` to collect build configuration, `@src.file` is
actually relative to the current working directory, at least on my
system. For a while, this led to ZLS completions breaking entirely,
but presently it actually causes ZLS to crash!
The solution is not as simple as using relative `sdkPath` results
as-is, because the build system may attempt to resolve these paths
relative to build root, when the paths are actually relative to the
current working directory.
This leads to a sticky situation: the current working directory is a
runtime concept, but `@src.file` is resolved at compile time. However,
it appears that the build runner does not change current working
directory in between compilation and execution, so it is probably safe
to calculate `sdkPath` using runtime current working directory.
Still, this requires major changes with how `sdkPath` works, since
runtime computation and allocations are required. So pretty much
anything that relied on `sdkPath` being comptime-known has been
refactored in this commit.
The most severe result of this is that, for example, `gpu.pkg` can no
longer be a comptime-known constant: it has to be a runtime function
that takes a `*Builder` and returns a `Pkg`.
This commit deals with usages of `*.pkg` and `sdkPath` within Mach
itself, but projects that depend on Mach such as `mach-examples` will
almost certainly require changes as well.
* all: update README to reflect change in pkg usage
For details on updating your code to use this version, see: 88b1106953
Signed-off-by: Stephen Gutekanst <stephen@hexops.com>
Co-authored-by: Stephen Gutekanst <stephen@hexops.com>
6 KiB
mach/glfw - Ziggified GLFW bindings

Ziggified GLFW bindings that Mach engine uses, with 100% API coverage, zero-fuss installation, cross compilation, and more.
This repository is a separate copy of the same library in the main Mach repository, and is automatically kept in sync, so that anyone can use this library in their own project / engine if they like!
Zero fuss installation, cross compilation, and more
Just as with Mach, you get zero fuss installation & cross compilation using these GLFW bindings. only zig
and git
are needed to build from any OS and produce binaries for every OS. No system dependencies at all.
100% API coverage, 130+ tests, etc.
These bindings have 100% API coverage of GLFW v3.3.4. Every function, type, constant, etc. has been wrapped in a ziggified API.
There are 130+ tests, and CI tests on all major platforms as well as cross-compilation between platforms:
What does a ziggified GLFW API offer?
Why create a ziggified GLFW wrapper, instead of just using @cImport
and interfacing with GLFW directly? You get:
- Errors as zig errors instead of via a callback function.
true
andfalse
instead ofc.GLFW_TRUE
andc.GLFW_FALSE
constants.- Generics, so you can just use
window.hint
instead ofglfwWindowHint
,glfwWindowHintString
, etc. - Enums, always know what value a GLFW function can accept as everything is strictly typed. And use the nice Zig syntax to access enums, like
window.getKey(.escape)
instead ofc.glfwGetKey(window, c.GLFW_KEY_ESCAPE)
- Slices instead of C pointers and lengths.
- packed structs represent bit masks, so you can use
if (joystick.down and joystick.right)
instead ofif (joystick & c.GLFW_HAT_DOWN and joystick & c.GLFW_HAT_RIGHT)
, etc. - Methods, e.g.
my_window.hint(...)
instead ofglfwWindowHint(my_window, ...)
How do I use OpenGL, Vulkan, WebGPU, etc. with this?
You'll need to bring your own library for this. Some are:
- (Vulkan) https://github.com/Snektron/vulkan-zig (also see https://github.com/Avokadoen/zig_vulkan)
- (OpenGL) https://github.com/ziglibs/zgl
Examples
A minimal Vulkan example can be found in the mach-glfw-vulkan-example repository:

Getting started
Adding dependency (using Git)
In a libs
subdirectory of the root of your project:
git clone https://github.com/hexops/mach-glfw
Then in your build.zig
add:
...
const glfw = @import("libs/mach-glfw/build.zig");
pub fn build(b: *Builder) !void {
...
exe.addPackage(glfw.pkg(b));
try glfw.link(b, exe, .{});
}
(optional) Adding dependency using Gyro
gyro add --src github hexops/mach-glfw --root src/main.zig --alias glfw
gyro add --build_dep --src github hexops/mach-glfw --root build.zig --alias build-glfw
Then in your build.zig
add:
...
const pkgs = @import("deps.zig").pkgs;
const glfw = @import("build-glfw");
pub fn build(b: *Builder) !void {
...
exe.addPackage(pkgs.glfw);
try glfw.link(b, exe, .{});
}
Note: You should use gyro build
instead of zig build
to use gyro
Next steps
Now in your code you may import and use GLFW:
const glfw = @import("glfw");
pub fn main() !void {
try glfw.init(.{});
defer glfw.terminate();
// Create our window
const window = try glfw.Window.create(640, 480, "Hello, mach-glfw!", null, null, .{});
defer window.destroy();
// Wait for the user to close the window.
while (!window.shouldClose()) {
try glfw.pollEvents();
}
}
A warning about error handling
Unless the action you're performing is truly critical to your application continuing further, you should avoid using try
.
This is because GLFW unfortunately must return errors for a large portion of its functionality on some platforms, but especially for Wayland - so ideally your application is resiliant to such errors and merely e.g. logs failures that are not critical.
Instead of try window.getPos()
for example, you may use:
const pos = window.getPos() catch |err| {
std.log.err("failed to get window position: error={}\n", .{err});
return;
};
Here is a rough list of functionality Wayland does not support:
Window.setIcon
Window.setPos
,Window.getPos
Window.iconify
,Window.focus
Monitor.setGamma
Monitor.getGammaRamp
,Monitor.setGammaRamp
Join the community
Join the Mach engine community on Matrix chat to discuss this project, ask questions, get help, etc.
Issues
Issues are tracked in the main Mach repository.
Contributing
Contributions are very welcome. Pull requests must be sent to the main repository to avoid some complex merge conflicts we'd get by accepting contributions in both repositories. Once the changes are merged there, they'll get sync'd to this repository automatically.
For now mach/glfw tracks the latest master
revision of GLFW, as recorded in this file, as this version has critical undefined behavior fixes required for GLFW to work with Zig. We will switch to stable releases of GLFW once GLFW 3.4 is tagged.