{ lib, stdenv, alsa-lib, cmake, dbus, fetchFromGitHub, ibusMinimal, installShellFiles, libGL, libayatana-appindicator, libdecor, libdrm, libjack2, libpulseaudio, libusb1, libxkbcommon, libgbm, libx11, libxcb, libxscrnsaver, libxcursor, libxext, libxfixes, libxi, libxrandr, libxtst, ninja, nix-update-script, nixosTests, pipewire, sndio, systemdLibs, testers, validatePkgConfig, vulkan-headers, vulkan-loader, wayland, wayland-scanner, zenity, # for passthru.tests sdl12-compat, sdl2-compat, sdl3-image, sdl3-ttf, alsaSupport ? stdenv.hostPlatform.isLinux && !stdenv.hostPlatform.isAndroid, dbusSupport ? stdenv.hostPlatform.isLinux && !stdenv.hostPlatform.isAndroid, drmSupport ? stdenv.hostPlatform.isLinux && !stdenv.hostPlatform.isAndroid, ibusSupport ? stdenv.hostPlatform.isUnix && !stdenv.hostPlatform.isDarwin, jackSupport ? stdenv.hostPlatform.isLinux && !stdenv.hostPlatform.isAndroid, libdecorSupport ? stdenv.hostPlatform.isLinux && !stdenv.hostPlatform.isAndroid, libudevSupport ? stdenv.hostPlatform.isLinux && !stdenv.hostPlatform.isAndroid, libusbSupport ? stdenv.hostPlatform.isLinux, openglSupport ? lib.meta.availableOn stdenv.hostPlatform libGL, pipewireSupport ? stdenv.hostPlatform.isLinux && !stdenv.hostPlatform.isAndroid, pulseaudioSupport ? stdenv.hostPlatform.isLinux && !stdenv.hostPlatform.isAndroid, sndioSupport ? false, traySupport ? true, vulkanSupport ? true, waylandSupport ? stdenv.hostPlatform.isLinux && !stdenv.hostPlatform.isAndroid, x11Support ? !stdenv.hostPlatform.isAndroid && !stdenv.hostPlatform.isWindows, }: assert lib.assertMsg ( waylandSupport -> openglSupport ) "SDL3 requires OpenGL support to enable Wayland"; assert lib.assertMsg (ibusSupport -> dbusSupport) "SDL3 requires dbus support to enable ibus"; stdenv.mkDerivation (finalAttrs: { pname = "sdl3"; version = "3.4.18"; outputs = [ "lib" "dev" "out" "installedTests" ]; src = fetchFromGitHub { owner = "libsdl-org"; repo = "SDL"; tag = "release-${finalAttrs.version}"; hash = "sha256-3dP4FJ5OvZI6UPykJpE3hTH6kdW+Nn7gUSf3yiPCobo="; }; postPatch = lib.optionalString (finalAttrs.finalPackage.doCheck) '' # Tests timeout on Darwin substituteInPlace test/CMakeLists.txt \ --replace-fail 'set(noninteractive_timeout 10)' 'set(noninteractive_timeout 30)' # intermittent test failure # https://github.com/libsdl-org/SDL/issues/15346 substituteInPlace test/CMakeLists.txt \ --replace-fail \ 'add_sdl_test_executable(testrwlock SOURCES testrwlock.c NONINTERACTIVE NONINTERACTIVE_TIMEOUT 20)' \ 'add_sdl_test_executable(testrwlock SOURCES testrwlock.c NONINTERACTIVE NONINTERACTIVE_TIMEOUT 300)' '' + lib.optionalString waylandSupport '' substituteInPlace src/dialog/unix/SDL_zenitymessagebox.c \ --replace-fail '"zenity"' '"${lib.getExe zenity}"' substituteInPlace src/dialog/unix/SDL_zenitydialog.c \ --replace-fail '"zenity"' '"${lib.getExe zenity}"' '' # https://github.com/libsdl-org/SDL/issues/14805 + lib.optionalString vulkanSupport '' substituteInPlace src/video/x11/SDL_x11vulkan.c \ src/video/wayland/SDL_waylandvulkan.c \ src/video/offscreen/SDL_offscreenvulkan.c \ src/video/kmsdrm/SDL_kmsdrmvulkan.c \ src/video/vivante/SDL_vivantevulkan.c \ src/video/android/SDL_androidvulkan.c \ --replace-fail 'libvulkan.so' '${lib.getLib vulkan-loader}/lib/libvulkan.so' '' + lib.optionalString x11Support '' substituteInPlace src/video/x11/SDL_x11vulkan.c \ --replace-fail 'libX11-xcb.so' '${lib.getLib libx11}/lib/libX11-xcb.so' ''; strictDeps = true; nativeBuildInputs = [ cmake ninja validatePkgConfig ] ++ lib.optional waylandSupport wayland-scanner; buildInputs = lib.optionals libusbSupport [ libusb1 ] ++ lib.optional ( stdenv.hostPlatform.isUnix && !stdenv.hostPlatform.isDarwin && traySupport ) libayatana-appindicator ++ lib.optional alsaSupport alsa-lib ++ lib.optional dbusSupport dbus ++ lib.optionals drmSupport [ libdrm libgbm ] ++ lib.optional jackSupport libjack2 ++ lib.optional libdecorSupport libdecor ++ lib.optional libudevSupport systemdLibs ++ lib.optional openglSupport libGL ++ lib.optional pipewireSupport pipewire ++ lib.optional pulseaudioSupport libpulseaudio ++ lib.optional sndioSupport sndio ++ lib.optionals waylandSupport [ libxkbcommon wayland ] ++ lib.optionals x11Support [ libx11 libxcb libxscrnsaver libxcursor libxext libxfixes libxi libxrandr libxtst ] ++ lib.optionals vulkanSupport [ vulkan-headers vulkan-loader ] ++ lib.optionals ibusSupport [ # sdl3 only uses some constants of the ibus headers # it never actually loads the library # thus, it also does not have to care about gtk integration, # so using ibusMinimal avoids an unnecessarily large closure here. ibusMinimal ]; cmakeFlags = [ (lib.cmakeBool "SDL_ALSA" alsaSupport) (lib.cmakeBool "SDL_DBUS" dbusSupport) (lib.cmakeBool "SDL_HIDAPI_LIBUSB" libusbSupport) (lib.cmakeBool "SDL_IBUS" ibusSupport) (lib.cmakeBool "SDL_JACK" jackSupport) (lib.cmakeBool "SDL_KMSDRM" drmSupport) (lib.cmakeBool "SDL_LIBUDEV" libudevSupport) (lib.cmakeBool "SDL_OPENGL" openglSupport) (lib.cmakeBool "SDL_PIPEWIRE" pipewireSupport) (lib.cmakeBool "SDL_PULSEAUDIO" pulseaudioSupport) (lib.cmakeBool "SDL_SNDIO" sndioSupport) (lib.cmakeBool "SDL_TEST_LIBRARY" true) (lib.cmakeBool "SDL_TRAY_DUMMY" (!traySupport)) (lib.cmakeBool "SDL_VULKAN" vulkanSupport) (lib.cmakeBool "SDL_WAYLAND" waylandSupport) (lib.cmakeBool "SDL_WAYLAND_LIBDECOR" libdecorSupport) (lib.cmakeBool "SDL_X11" x11Support) (lib.cmakeBool "SDL_TESTS" true) (lib.cmakeBool "SDL_INSTALL_TESTS" true) (lib.cmakeBool "SDL_DEPS_SHARED" false) # Only ppc64le baseline guarantees AltiVec (lib.cmakeBool "SDL_ALTIVEC" (stdenv.hostPlatform.isPower64 && stdenv.hostPlatform.isLittleEndian)) (lib.cmakeBool "SDL_UNIX_CONSOLE_BUILD" ( stdenv.hostPlatform.isUnix && !(stdenv.hostPlatform.isDarwin || stdenv.hostPlatform.isAndroid) && !(x11Support || waylandSupport) )) ]; doCheck = true; postInstall = '' moveToOutput "share/installed-tests" "$installedTests" moveToOutput "libexec/installed-tests" "$installedTests" ''; passthru = { # Building this in its own derivation to make sure the rpath hack above propagate to users debug-text-example = stdenv.mkDerivation (finalAttrs': { pname = "sdl3-debug-text-example"; inherit (finalAttrs) version src; sourceRoot = "${finalAttrs'.src.name}/examples/renderer/18-debug-text"; nativeBuildInputs = [ installShellFiles ]; buildInputs = [ finalAttrs.finalPackage ]; postBuild = '' $CC -lSDL3 -o debug-text{,.c} ''; postInstall = '' installBin debug-text ''; meta = { inherit (finalAttrs.meta) maintainers platforms; mainProgram = "debug-text"; }; }); tests = sdl12-compat.tests // sdl2-compat.tests // { inherit sdl12-compat sdl2-compat sdl3-image sdl3-ttf ; pkg-config = testers.hasPkgConfigModules { package = finalAttrs.finalPackage; versionCheck = true; }; inherit (finalAttrs.passthru) debug-text-example; } // lib.optionalAttrs stdenv.hostPlatform.isLinux { nixosTest = nixosTests.sdl3; }; updateScript = nix-update-script { extraArgs = [ "--version-regex" "release-(3\\..*)" ]; }; }; meta = { description = "Cross-platform development library"; homepage = "https://libsdl.org"; changelog = "https://github.com/libsdl-org/SDL/releases/tag/${finalAttrs.src.tag}"; license = lib.licenses.zlib; maintainers = with lib.maintainers; [ getchoo ]; teams = [ lib.teams.sdl ]; platforms = lib.platforms.unix ++ lib.platforms.windows; pkgConfigModules = [ "sdl3" ]; }; })