Games-by-Mason/sdl_zig
SDL ported to the Zig build system.
refs
3ae2b7c48690d2ce13cc6db3db02dfc0572be65e.tar.gz
refs
a61afe5f75d969c4561a1d0ad753aa23cee6329a.zip
200cea4030cb49d3e40677379e6368a5f0e8c27b.zip
refs
refs
SDL3 ported to the Zig build system.
Supports cross compilation and custom platform configuration.
You can add SDL3 to your project like this by updating build.zig.zon
from the command line:
zig fetch --save <url-of-this-repo>
And then you can add it to your build.zig
like this:
const sdl = b.dependency("sdl", .{
.optimize = optimize,
.target = target,
});
exe.linkLibrary(sdl.artifact("SDL3"));
Finally, you can use SDL's C API from Zig like this:
const c = @import("c.zig");
if (!c.SDL_Init(c.SDL_INIT_VIDEO)) {
panic("SDL_Init failed: {?s}\n", .{c.SDL_GetError()});
}
defer c.SDL_Quit();
You can run src/example.zig
from the command line:
zig build run-example
This should produce a window with a pulsing gradient.
SDL_Init
failed on Linux!SDL_Init failed: No available video device
By default, SDL loads most of its dependencies at runtime on Linux. This lets it decide at runtime which audio drivers to use, whether to use Wayland or X11, etc.
For this to work, the libraries SDL is looking for need to be on your LD_LIBRARY_PATH
. This may not be the case by default on distributions like NixOS.
Here's a shell.nix
for a Vulkan app as an example of running an SDL application on NixOS with either X11 or Wayland.
{ pkgs ? import <nixpkgs> {}}:
pkgs.mkShell {
packages = with pkgs; [
vulkan-validation-layers
];
LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath (with pkgs; [
alsa-lib
libdecor
libusb1
libxkbcommon
vulkan-loader
wayland
xorg.libX11
xorg.libXext
xorg.libXi
udev
]);
}
Not all of these dependencies in this example are required. Since both X11 and Wayland dependencies are listed, SDL will use its judgement to decide which to prefer unless SDL_VIDEODRIVER
is set.
This library provides a default configuration for common targets:
You can override the default target configuration by setting default_target_config
to false
, and then providing your own configuration. This is typically only necessary when your platform doesn't yet have a default configuration:
const sdl = b.dependency("sdl", .{
.optimize = optimize,
.target = target,
.default_target_config = false,
});
const sdl_lib = sdl.artifact("SDL3");
sdl_lib.addIncludePath(...); // Path to your `SDL_build_config.h`, see `windows.zig` for an example of generating this
Any other necessary tweaks such as turning of linking with libc, linking with dependencies, or adding other headers can be done here as well.
If you're interested in adding default configuration for additional targets, contributions are welcome! See src/linux.zig
or src/windows.zig
for examples of how this works.
When making a PR that adds support for a new target:
/deps
with a README explaining why they couldn't be pulled in via the build system and any relevant licensing information.build.zig.zon
to point to the desired SDL versionzig build wayland-scanner
with wayland-scanner
.src/sdl.zon
.This should rarely be necessary. When it is, you can update their version in build.zig.zon
if present, and any relevant files in /deps
if present.