Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
117 changes: 61 additions & 56 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -1,56 +1,61 @@
name: CI

on:
push:
branches:
- main
pull_request:
branches:
- main
workflow_dispatch:

jobs:
build:
strategy:
fail-fast: false
matrix:
zig-version: [0.16.0, master]
os: [ubuntu-latest, windows-latest, macos-latest]
runs-on: ${{ matrix.os }}
continue-on-error: ${{ matrix.zig-version == 'master' }}
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Zig
uses: mlugg/setup-zig@v2
with:
version: ${{ matrix.zig-version }}

- name: Workaround Zig 0.16.0 ZIP unpack failure
# https://codeberg.org/ziglang/zig/issues/31964
shell: bash
run: mkdir -p "${ZIG_GLOBAL_CACHE_DIR}/tmp"

- name: Check Formatting
if: runner.os != 'Windows' # zig fmt failing on Windows CI, unclear why
run: zig fmt --ast-check --check .

- name: Build for Windows
run: zig build example -Dtarget=x86_64-windows-gnu --summary all

- name: Build for Linux
run: zig build example -Dtarget=x86_64-linux-gnu --summary all

- name: Build for macOS
if: runner.os == 'macOS'
# We don't support cross compiling for macOS, so don't set a target just build
# the native target
run: zig build example --summary all

- name: Build for iOS
if: runner.os == 'macOS'
# The iOS SDK is not bundled with Zig, so point the build at Xcode's iPhoneOS SDK.
run: |
SDK="$(xcrun --sdk iphoneos --show-sdk-path)"
zig build -Dtarget=aarch64-ios -Dinclude_path="$SDK/usr/include" -Dframework_path="$SDK/System/Library/Frameworks" --summary all
name: CI

on:
push:
branches:
- main
pull_request:
branches:
- main
workflow_dispatch:

jobs:
build:
strategy:
fail-fast: false
matrix:
zig-version: [0.16.0, master]
os: [ubuntu-latest, windows-latest, macos-latest]
runs-on: ${{ matrix.os }}
continue-on-error: ${{ matrix.zig-version == 'master' }}
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Zig
uses: mlugg/setup-zig@v2
with:
version: ${{ matrix.zig-version }}

- name: Workaround Zig 0.16.0 ZIP unpack failure
# https://codeberg.org/ziglang/zig/issues/31964
shell: bash
run: mkdir -p "${ZIG_GLOBAL_CACHE_DIR}/tmp"

- name: Check Formatting
if: runner.os != 'Windows' # zig fmt failing on Windows CI, unclear why
run: zig fmt --ast-check --check .

- name: Build for Windows
run: zig build example -Dtarget=x86_64-windows-gnu --summary all

- name: Build for Linux
if: runner.os == 'Linux'
# Headers come from the system, see "Linux" in the README
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends libx11-dev libxext-dev libxcursor-dev libxi-dev libxfixes-dev libxrandr-dev libxrender-dev libxss-dev libxtst-dev libxcb1-dev libxkbcommon-dev libwayland-dev libdecor-0-dev libegl-dev libgl-dev libgles-dev libgbm-dev libdrm-dev libdbus-1-dev libibus-1.0-dev libglib2.0-dev libpipewire-0.3-dev libpulse-dev libjack-jackd2-dev libsndio-dev libasound2-dev libusb-1.0-0-dev libudev-dev liburing-dev libfribidi-dev libthai-dev
zig build example -Dtarget=x86_64-linux-gnu --summary all

- name: Build for macOS
if: runner.os == 'macOS'
# We don't support cross compiling for macOS, so don't set a target just build
# the native target
run: zig build example --summary all

- name: Build for iOS
if: runner.os == 'macOS'
# The iOS SDK is not bundled with Zig, so point the build at Xcode's iPhoneOS SDK.
run: |
SDK="$(xcrun --sdk iphoneos --show-sdk-path)"
zig build -Dtarget=aarch64-ios -Dinclude_path="$SDK/usr/include" -Dframework_path="$SDK/System/Library/Frameworks" --summary all
22 changes: 19 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ Not all of these dependencies in this example are required. Since both X11 and W
# Target Configuration

This library provides a default configuration for common targets:
* [x] Linux (including Steam Deck)
* [x] Linux (including Steam Deck), see [Linux](#linux)
* [x] Steam Deck
* [x] Windows
* [x] macOS (no cross compilation due to Apple licensing)
Expand All @@ -96,6 +96,22 @@ This library provides a default configuration for common targets:
* [ ] [Emscripten (help wanted!)](https://github.com/allyourcodebase/SDL/issues/5)
* [ ] [Consoles (help wanted!)](https://github.com/allyourcodebase/SDL/issues/6)

## Linux

SDL `dlopen`s its Linux dependencies at runtime, but needs their headers at build time. These come from your system (native builds) or from a sysroot for the target (cross builds); none are bundled. On Debian/Ubuntu:

```sh
sudo apt-get install libx11-dev libxext-dev libxcursor-dev libxi-dev libxfixes-dev libxrandr-dev libxrender-dev libxss-dev libxtst-dev libxcb1-dev libxkbcommon-dev libwayland-dev libdecor-0-dev libegl-dev libgl-dev libgles-dev libgbm-dev libdrm-dev libdbus-1-dev libibus-1.0-dev libglib2.0-dev libpipewire-0.3-dev libpulse-dev libjack-jackd2-dev libsndio-dev libasound2-dev libusb-1.0-0-dev libudev-dev liburing-dev libfribidi-dev libthai-dev
```

To cross compile, point the build at a sysroot with those packages installed:

```sh
zig build -Dtarget=x86_64-linux-gnu -Dinclude_path=$SYSROOT/usr/include -Dlibrary_path=$SYSROOT/usr/lib/x86_64-linux-gnu
```

`library_path` is only read for the arch specific `glibconfig.h`/`dbus-arch-deps.h` and the `xkbcommon`/`libdecor-0` pkg-config versions, nothing is linked.

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:
```zig
const sdl = b.dependency("sdl", .{
Expand All @@ -113,7 +129,7 @@ If you're interested in adding default configuration for additional targets, lis

When making a PR that adds support for a new target:
* Replicate the [default SDL configuration for the target](https://github.com/libsdl-org/SDL/tree/main/include/build_config) within reason
* Pull dependencies in via the build system rather than vendoring them when possible. If this isn't possible, vendor the needed files in `/deps` with a README explaining why they couldn't be pulled in via the build system and any relevant licensing information.
* Take third party headers from the target's system/sysroot (`-Dinclude_path`, `-Dlibrary_path`) rather than bundling them.
* Cross compilation to all targets should be possible within reason unless forbidden by licensing.
* Update [.github/workflows/ci.yaml](.github/workflows/ci.yaml) to test the new target.

Expand All @@ -128,4 +144,4 @@ When making a PR that adds support for a new target:

## SDL's Dependencies

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.
Nothing to update, they come from the system or sysroot. The only generated files are the Wayland protocols in `deps/wayland`, see above.
23 changes: 22 additions & 1 deletion build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,16 @@ pub const SystemPaths = struct {
}
};

pub const LinuxFeatures = struct {
audio: bool,
joystick: bool,
camera: bool,
kmsdrm: bool,
io_uring: bool,
fribidi: bool,
libthai: bool,
};

pub fn build(b: *std.Build) !void {
// Get the upstream source and build options
const upstream = b.dependency("sdl", .{});
Expand Down Expand Up @@ -59,6 +69,17 @@ pub fn build(b: *std.Build) !void {
.library = b.option(std.Build.LazyPath, "library_path", "SDK library dir, e.g. $(xcrun --sdk iphoneos --show-sdk-path)/usr/lib"),
};

// Each one also drops the dev headers it needs from the sysroot. Linux only for now.
const linux_features: LinuxFeatures = .{
.audio = b.option(bool, "audio", "Linux: audio subsystem (alsa, pulse, pipewire, jack, sndio headers), defaults to true") orelse true,
.joystick = b.option(bool, "joystick", "Linux: joystick, gamepad, haptic and hidapi (libudev, libusb headers), defaults to true") orelse true,
.camera = b.option(bool, "camera", "Linux: camera subsystem (libudev, pipewire headers), defaults to true") orelse true,
.kmsdrm = b.option(bool, "kmsdrm", "Linux: KMSDRM video driver (libdrm, gbm, libudev headers), defaults to true") orelse true,
.io_uring = b.option(bool, "io_uring", "Linux: io_uring async IO backend (liburing header), defaults to true") orelse true,
.fribidi = b.option(bool, "fribidi", "Linux: bidirectional text in message boxes (fribidi header), defaults to true") orelse true,
.libthai = b.option(bool, "libthai", "Linux: Thai line breaking in message boxes (libthai header), defaults to true") orelse true,
};

// Get the SO version. This is the same as the SDL version, but the major version is elided
// since it's baked into the name. This mirrors the official build process.
var sdl_so_version = comptime std.SemanticVersion.parse(build_zon.dependencies.sdl.version) catch unreachable;
Expand Down Expand Up @@ -131,7 +152,7 @@ pub fn build(b: *std.Build) !void {
.linux => if (target.result.abi.isAndroid())
android.build(b, target.result, lib, build_config_h, system_paths)
else
linux.build(b, target.result, lib, build_config_h),
linux.build(b, target.result, lib, build_config_h, system_paths, linux_features),
.windows => windows.build(b, target.result, lib, build_config_h),
.macos => macos.build(b, target.result, lib, build_config_h),
.ios => ios.build(b, target.result, lib, build_config_h, system_paths),
Expand Down
128 changes: 0 additions & 128 deletions build.zig.zon
Original file line number Diff line number Diff line change
Expand Up @@ -9,134 +9,6 @@
.hash = "N-V-__8AABHq9wIiTHGY4qR6mw45F_TX8FSvqsQQ-Wtq1tzY",
.version = "3.4.16",
},
.dbus = .{
.version = "1.16.2",
.url = "https://gitlab.freedesktop.org/dbus/dbus/-/archive/dbus-1.16.2/dbus-dbus-1.16.2.tar.gz",
.hash = "N-V-__8AALxqaQCXLK7KmtlbRHzj5quTSajWtJZ86Qy7aBxj",
},
.x11 = .{
.url = "https://gitlab.freedesktop.org/xorg/lib/libx11/-/archive/libX11-1.8.13/libx11-libX11-1.8.13.tar.gz",
.hash = "N-V-__8AANL5xACqderCBKpnIFKe282dZAikvyc--kNSKWgd",
},
.egl = .{
.url = "https://github.com/KhronosGroup/EGL-Registry/archive/3d7796b3721d93976b6bfe536aa97bbc4bce8667.tar.gz",
.hash = "N-V-__8AAItrbQBen6_Wl2eZ2ax6B0G6qtKys7_uVz224o99",
},
.wayland = .{
.version = "1.26.0",
.url = "git+https://gitlab.freedesktop.org/wayland/wayland?ref=1.26.0#87cc8a8728a923fc57938faa81ba0e74f34ecdc7",
.hash = "N-V-__8AAA46JQABKU7sa-6xGUAN44uFsYSUS_w79UVuu7qo",
},
.xkbcommon = .{
.version = "1.13.2",
.url = "https://github.com/xkbcommon/libxkbcommon/archive/refs/tags/xkbcommon-1.13.2.tar.gz",
.hash = "N-V-__8AAGh7bAAD9LH6Hh6HB6br9SDZmRBbRu-_1NNpQ4GL",
},
.xorgproto = .{
.url = "https://gitlab.freedesktop.org/xorg/proto/xorgproto/-/archive/xorgproto-2025.1/xorgproto-xorgproto-2025.1.tar.gz",
.hash = "N-V-__8AAG86ZgA2-SHGTO4n81-Sj8LNvSASCKZ91wOWZ7Sg",
},
.xext = .{
.url = "https://gitlab.freedesktop.org/xorg/lib/libxext/-/archive/libXext-1.3.7/libxext-libXext-1.3.7.tar.gz",
.hash = "N-V-__8AAHTdBwAEWsgYzKEVP-WmGT0wYKIJjBtqH1No6y73",
},
.xcb = .{
.url = "https://gitlab.freedesktop.org/xorg/lib/libxcb/-/archive/libxcb-1.17.0/libxcb-libxcb-1.17.0.tar.gz",
.hash = "N-V-__8AAPZxCQD7JyQLx0_D9J9dnkSoP7iziBVxreTgUqlj",
},
.ibus = .{
.url = "https://github.com/ibus/ibus/releases/download/1.5.34/ibus-1.5.34.tar.gz",
.hash = "N-V-__8AANTkvAHAAXsApyhePM0ufoLcIQxEGXVB6Q7n7grW",
},
.usb = .{
.url = "https://github.com/libusb/libusb/archive/refs/tags/v1.0.30.zip",
.hash = "N-V-__8AAP6YHABRm4muBuwd_qlKgvsenaOLg962zfsjQr8B",
},
.xcursor = .{
.version = "1.2.3",
.url = "https://gitlab.freedesktop.org/xorg/lib/libxcursor/-/archive/libXcursor-1.2.3/libxcursor-libXcursor-1.2.3.tar.gz",
.hash = "N-V-__8AAKtlAgAAqwksheZkCSajEEPpi2XivNet-_3hZyz2",
},
.xi = .{
.url = "https://gitlab.freedesktop.org/xorg/lib/libxi/-/archive/libXi-1.8.3/libxi-libXi-1.8.3.tar.gz",
.hash = "N-V-__8AAPR0DQAuD3_ZopKbezyogf0SLNe6GiYF3RlaaNrh",
},
.xfixes = .{
.url = "https://gitlab.freedesktop.org/xorg/lib/libxfixes/-/archive/libXfixes-6.0.2/libxfixes-libXfixes-6.0.2.tar.gz",
.hash = "N-V-__8AAFIgAQCJSug37AGy4zypGtiDtUR9wtQa8U74Nm0a",
},
.xrandr = .{
.url = "https://gitlab.freedesktop.org/xorg/lib/libxrandr/-/archive/libXrandr-1.5.5/libxrandr-libXrandr-1.5.5.tar.gz",
.hash = "N-V-__8AAGlRAgBdkf1F-Y410qIz6cV4C62ZAUk_SGeUVriw",
},
.xrender = .{
.url = "https://gitlab.freedesktop.org/xorg/lib/libxrender/-/archive/libXrender-0.9.12/libxrender-libXrender-0.9.12.tar.gz",
.hash = "N-V-__8AANorBADbt-RlITZJofNvQWTiaQlv7r7lWYtxAqGx",
},
.decor = .{
.url = "https://gitlab.freedesktop.org/libdecor/libdecor/-/archive/0.2.5/libdecor-0.2.5.tar.gz",
.hash = "N-V-__8AADG6BADZ6vLbOD3OrWhDYa5jrubmgY-ljspuv-4R",
.version = "0.2.5",
},
.opengl = .{
.url = "https://github.com/KhronosGroup/OpenGL-Registry/archive/e8f7cd0e35ac8d6f5667a021ff83d04b1fec41ef.tar.gz",
.hash = "N-V-__8AADsI5wqNqQMgAmqSba8PUrQcWdd3Svxc8GoX8SgY",
},
.pipewire = .{
.url = "https://gitlab.freedesktop.org/pipewire/pipewire/-/archive/1.6.8/pipewire-1.6.8.tar.gz",
.hash = "N-V-__8AAEBm3gCliUlb1HgAJA-3XvTWKC2YfRa5hJMiaEld",
.version = "1.6.8",
.api_version = "0.3", // From `meson.build`, does not directly track `version`!
},
.jack = .{
.url = "https://github.com/jackaudio/jack2/archive/refs/tags/jack2-control-api-relicense-nedko.tar.gz",
.hash = "N-V-__8AANOERwAn9QBxYJf43h9P3jq2HYTPvXlZRCHPEmrj",
},
.pulseaudio = .{
// This dependency must be kept in sync with `pulseaudio_windows`.
//
// We fetch from a mirror because the upstream tarball hash occasionally changes. The
// mirror is identical to upstream at the time it was pulled.
//
// Upstream: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/
.url = "https://github.com/Games-by-Mason/pulseaudio/archive/refs/tags/v16.2.tar.gz",
.hash = "N-V-__8AADiK2wBbQBbppKI9s1sR8vTGLV1mhn44OEYxyPD4",
.version = "16.2.0",
.api_version = "12", // From `meson.build`, does not directly track version!
.protocol_version = "35", // From `meson.build`, does not directly track version!
.lazy = true,
},
.pulseaudio_windows = .{
// This is a duplicate of `pulseaudio`, but with a different hash due to a Zig bug that
// results in a different hash on Windows than Linux.
.url = "https://github.com/Games-by-Mason/pulseaudio/archive/refs/tags/v16.2.tar.gz",
.hash = "N-V-__8AAH-J2wA1QFgeIKK0hLveAjq3mNnOJb96xak4HFqx",
.lazy = true,
},
.xscrnsaver = .{
// This dependency must be kept in sync with `xscrnsaver_windows` for similar reasons explained in the `pulseaudio` dependency.
.url = "https://gitlab.freedesktop.org/xorg/lib/libxscrnsaver/-/archive/libXScrnSaver-1.2.5/libxscrnsaver-libXScrnSaver-1.2.5.tar.gz",
.hash = "N-V-__8AAMXRAADYeHz48Y1IuZUzOOqRvOO7f0wrdeNkWcBF",
},
.alsa = .{
.url = "https://github.com/alsa-project/alsa-lib/archive/refs/tags/v1.2.16.1.tar.gz",
.hash = "N-V-__8AACQ2RADoahGXBHOr7fJYspVVN8sMHwQn2C-kzECe",
},
.sndio = .{
.url = "https://sndio.org/sndio-1.10.0.tar.gz",
.hash = "N-V-__8AAKA0CgB5SuKmufbOKBnZsjDFZuUTNO70MHQEf1p8",
},
.fribidi = .{
.version = "1.0.16",
.interface_version = 4,
.unicode_version = "16.0.0",
.url = "https://github.com/fribidi/fribidi/archive/refs/tags/v1.0.16.tar.gz",
.hash = "N-V-__8AABbxDAFJr4_dchs33gEqLRpBMP2oUBTuIueW9u_h",
},
.thai = .{
.url = "https://github.com/tlwg/libthai/archive/refs/tags/v0.1.30.tar.gz",
.hash = "N-V-__8AAAqMIgArahV5mT0LGKWmDhZC9QtlMIZlaT9yp_lP",
},
},
.paths = .{
"build.zig",
Expand Down
2 changes: 1 addition & 1 deletion deps/README.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
This directory contains dependencies, or parts of dependencies, that we couldn't pull in via the build system for one reason or another. See the README in each directory for an explanation.
This directory contains the Wayland protocol code generated by `zig build wayland-scanner`, cached so builds don't need `wayland-scanner`. Every other dependency comes from the system or sysroot, see the Linux section of the top level README.
3 changes: 0 additions & 3 deletions deps/alsa/README.md

This file was deleted.

Loading
Loading