feat(compat.sdl3): SDL3 3.4.2, built from source - #371
Merged
Conversation
The last of vulkan-rt's dependencies, and the one that could not ride along in #370: 266 sources, three platforms, and a config header that has to be generated. Shape E, sibling to compat.sdl2 rather than its replacement — SDL2 and SDL3 are different APIs with different sonames. Two things are easier than they were for SDL2, both measured rather than assumed: * NO REPACKED TARBALL. SDL2's entry points at an xlings-res re-host because the upstream archive carries symlinks that break the windows runner. SDL3's carries none (`tar tvzf | grep -c '^l'` is 0), so GLOBAL points straight at GitHub. * THE CONFIG DISPATCHER IS UPSTREAM'S. include/build_config/SDL_build_config.h already selects _windows.h / _macos.h by platform and both are checked in. Only linux falls through to SDL_build_config_minimal.h, which has no video driver at all. So exactly one config is generated, and only linux uses it. THE CONFIG MAY ONLY CLAIM WHAT THIS INDEX PACKAGES. CMake probes the machine it runs on, so anything the host happens to have is switched on and then fails to compile here. Three were found by failing builds — XSCRNSAVER (fatal error: X11/extensions/scrnsaver.h), LIBTHAI, and HIDAPI_LIBUSB — and XTEST/XSYNC are off pre-emptively. What remains is checkable rather than hopeful: every library the finished config says it will dlopen must have a package here. That list is seven (libfribidi, libX11, libXcursor, libXext, libXfixes, libXi, libXrandr) and it matches linux.deps exactly. It was also generated WITH THIS INDEX'S TOOLCHAIN and the index's own X11 headers, which is not a formality: mcpp's gcc has its own sysroot and cannot see /usr/include, so without them SDL's check fails and configure aborts. compat.curl records what the shortcut costs — a config generated with the host cc once asserted that ssize_t does not exist. The source list is CMake's own answer rather than a reading of CMakeLists: after configuring, the objects it decided to build were read back out of CMakeFiles/SDL3-static.dir/build.make and mapped to directories — 266 sources, 73 directories taken whole and exactly one in part (src/core/linux, minus the six dbus/IME files compat.sdl2 also omits, which do not self-guard). macOS and Windows do not use the generated config, so their lists are derived from what the CHECKED-IN configs switch on. The non-obvious one is windows: SDL_THREAD_GENERIC_COND_SUFFIX and _RWLOCK_SUFFIX mean the windows backend falls back to the generic condition variable and rwlock, so thread/generic/SDL_syscond.c and SDL_sysrwlock.c must be linked alongside thread/windows/* — only those two, since the other four share basenames with their windows twins. The test drives SDL's DUMMY video driver, so it runs headless on all three platforms: header/runtime version agreement, the compiled-in driver list containing dummy AND offscreen (a config that fell through to minimal has neither), the dummy driver actually initialising and producing a 320x240 window with a surface of that size, and the timer advancing. Verified: linux gcc 16.1.0 and linux llvm 22.1.8 both compile all 267 units and run the test. macOS and Windows are derived as described and confirmed by CI — there is no way to compile either from here. CN mirror at gitcode.com/mcpp-res/sdl3, byte-identical to upstream (verified).
Two failures from the first CI run, both from assuming a shape rather than
checking it.
WINDOWS: SDL3 IS NOT ALL C. `core/windows`, `video/windows` and the GameInput
joystick backend (`joystick/gdk/SDL_gameinputjoystick.cpp`) carry C++ sources,
and `*/src/.../*.c` drops them silently — a glob that misses a file produces no
diagnostic at all until the link:
lld-link: error: undefined symbol: WIN_InitGameInput
lld-link: error: undefined symbol: SDL_GAMEINPUT_JoystickDriver
`render/direct3d12` has the same problem in the COMMON list: three of its files
are .cpp, so the `*.c` glob was linking half a renderer. Rather than patch only
the symbols the linker happened to name, the whole class was found by asking
the tree which sources are not .c — 34 directories, of which the windows-
relevant ones are these four. macOS was already right because its backends are
.m and the globs say .m.
LINUX/LLVM: `SDL_x11opengl.h` includes <GL/glx.h>, which is not in the Khronos
registry and needs `compat.glx-headers` — the same dependency, for the same
reason, that compat.sdl2 carries. This one is worth the comment it now has,
because it is invisible from two of the three places you would look: the gcc
toolchain's sysroot already carries GL/glx.h, so linux/gcc passed and so did a
local build with either compiler. Only the llvm leg says:
fatal error: 'GL/glx.h' file not found
Verified after the fix that the header now resolves to the PACKAGE's copy
(.mcpp/.../compat-x-glx-headers/1.7.0/libglvnd-1.7.0/include/GL/glx.h) rather
than to whatever the toolchain happened to have, which is the difference
between a fix and a coincidence. Both linux legs pass; windows is CI's to
confirm.
The previous commit's message described this change; the file did not contain
it. The edit that was supposed to insert three .cpp globs into the windows
source list was written against a pattern with two globs on one line, while the
descriptor has one per line, so it matched nothing and changed nothing — and
because that particular substitution carried no assertion, it failed silently.
Only the direct3d12 line, which was a separate edit, landed.
CI said so immediately and identically: the same five undefined symbols, the
second time round.
lld-link: error: undefined symbol: WIN_InitGameInput
lld-link: error: undefined symbol: SDL_GAMEINPUT_JoystickDriver
The globs are in now, and the reasoning is recorded next to them: WIN_* is
defined in video/windows/SDL_windowsgameinput.cpp, the joystick driver in
joystick/gdk/SDL_gameinputjoystick.cpp, and core/windows carries two more C++
TUs. All four are reached because the CHECKED-IN windows config sets
SDL_JOYSTICK_GAMEINPUT — which this descriptor does not get to decide, so the
sources have to be there.
Linux still passes; windows is CI's to confirm.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The last of vulkan-rt's dependencies, and the one that could not ride along in #370: 266 sources, three platforms, and a config header that has to be generated. Shape E, and a sibling to
compat.sdl2rather than its replacement — SDL2 and SDL3 are different APIs with different sonames, and projects migrate on their own schedule.Two things are easier than they were for SDL2
Both measured, not assumed:
xlings-resre-host because the upstream archive carries symlinks that break the windows runner. SDL3's carries none —tar tvzf | grep -c '^l'is0— so GLOBAL points straight at GitHub.include/build_config/SDL_build_config.halready selects_windows.h/_macos.hby platform, and both of those are checked in. Only linux falls through toSDL_build_config_minimal.h, which has no video driver at all. So exactly one config is generated, and only linux uses it.The config may only claim what this index packages
That is a rule, not a preference. CMake probes the machine it runs on, so anything the host happens to have gets switched on and then fails to compile here. Three were found by failing builds:
SDL_X11_XSCRNSAVERsrc/video/x11/SDL_x11dyn.h:69: fatal error: X11/extensions/scrnsaver.h: No such file or directory— there is nocompat.xssSDL_LIBTHAISDL_HIDAPI_LIBUSBXTESTandXSYNCare off pre-emptively for the same reason.What remains is checkable rather than hopeful: every library the finished config says it will
dlopenmust have a package here. That list is seven, and it matcheslinux.depsexactly:Because the X11 driver is
x11(dynamic), those are compile-time headers only — the package links against none of them.The config was also generated with this index's toolchain and the index's own X11 headers, which is not a formality: mcpp's gcc has its own sysroot and cannot see
/usr/include, so without them SDL's check fails and configure aborts outright.compat.curlrecords what the shortcut costs — a config generated with the hostcconce asserted thatssize_tdoes not exist.The source list is CMake's own answer
Not a reading of
CMakeLists.txt. After configuring, the objects CMake decided to build were read back out ofCMakeFiles/SDL3-static.dir/build.makeand mapped to directories: 266 sources → 73 directories taken whole + exactly one taken in part. That one issrc/core/linux, minus the six dbus/IME files (SDL_dbus.c,SDL_fcitx.c,SDL_ibus.c,SDL_ime.c,SDL_progressbar.c,SDL_system_theme.c) — the same setcompat.sdl2omits, and for the same reason: they are not guarded internally, they simply fail without dbus-1 headers.Everything else is a directory glob, which works because SDL compiles unselected backends into empty translation units —
render/direct3d12andrender/ps2are in the common list and contribute nothing on linux.macOS and Windows
They do not use the generated config, so their lists are derived from what the checked-in configs switch on (COREAUDIO / IOKIT / MFI / COCOA / METAL / GPU_METAL … and WASAPI / DSOUND / DINPUT / XINPUT / WGI / D3D11 / D3D12 …).
The non-obvious one is windows:
SDL_THREAD_GENERIC_COND_SUFFIXandSDL_THREAD_GENERIC_RWLOCK_SUFFIXmean the windows backend implements condition variables and rwlocks by falling back to the generic ones, sothread/generic/SDL_syscond.candSDL_sysrwlock.cmust be linked alongsidethread/windows/*. Only those two — the other four generic files share basenames with their windows twins, and taking the directory whole would compile two definitions of the same functions.The test runs headless on all three platforms
It forces SDL's dummy video driver, so it exercises the real video subsystem without a display server:
SDL_build_config_minimal.hhas neither, which is exactly the failure mode a "it compiled" test would missSDL_GetTicksadvances across a delayVerified
CN mirror at
gitcode.com/mcpp-res/sdl3, byte-identical to upstream (verified by downloading it back and comparing sha256).