From f036ec4b963e1776c39b0597f8c9d51e85be83d9 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 13 Sep 2025 12:09:59 -0400 Subject: [PATCH] Add back duckstation. --- .../configuration/hosts/deck/default.nix | 2 +- .../roles/duckstation/default.nix | 7 +- .../package/001-fix-test-inclusion.diff | 11 ++ .../package/002-hardcode-vars.diff | 19 ++ .../package/003-fix-NEON-intrinsics.patch | 70 ++++++++ .../roles/duckstation/package/LICENSE | 26 +++ .../roles/duckstation/package/package.nix | 147 ++++++++++++++++ .../package/remove-cubeb-vendor.patch | 33 ++++ .../duckstation/package/shaderc-patched.nix | 20 +++ .../roles/duckstation/package/sources.nix | 166 ++++++++++++++++++ 10 files changed, 497 insertions(+), 4 deletions(-) create mode 100644 nix/steam_deck/configuration/roles/duckstation/package/001-fix-test-inclusion.diff create mode 100644 nix/steam_deck/configuration/roles/duckstation/package/002-hardcode-vars.diff create mode 100644 nix/steam_deck/configuration/roles/duckstation/package/003-fix-NEON-intrinsics.patch create mode 100644 nix/steam_deck/configuration/roles/duckstation/package/LICENSE create mode 100644 nix/steam_deck/configuration/roles/duckstation/package/package.nix create mode 100644 nix/steam_deck/configuration/roles/duckstation/package/remove-cubeb-vendor.patch create mode 100644 nix/steam_deck/configuration/roles/duckstation/package/shaderc-patched.nix create mode 100644 nix/steam_deck/configuration/roles/duckstation/package/sources.nix diff --git a/nix/steam_deck/configuration/hosts/deck/default.nix b/nix/steam_deck/configuration/hosts/deck/default.nix index edaf472..399945c 100644 --- a/nix/steam_deck/configuration/hosts/deck/default.nix +++ b/nix/steam_deck/configuration/hosts/deck/default.nix @@ -11,7 +11,7 @@ config = { me.ares.enable = true; me.dolphin.enable = true; - me.duckstation.enable = false; + me.duckstation.enable = true; me.graphical = true; me.optimizations.enable = true; me.pcsx2.enable = true; diff --git a/nix/steam_deck/configuration/roles/duckstation/default.nix b/nix/steam_deck/configuration/roles/duckstation/default.nix index 26833f1..57783e2 100644 --- a/nix/steam_deck/configuration/roles/duckstation/default.nix +++ b/nix/steam_deck/configuration/roles/duckstation/default.nix @@ -51,6 +51,7 @@ in ( final: prev: let + modified_package = (pkgs.callPackage ./package/package.nix { }); optimizeWithFlags = pkg: flags: pkg.overrideAttrs (old: { @@ -58,16 +59,16 @@ in }); original_package = if config.me.optimizations.enable then - (optimizeWithFlags prev.duckstation [ + (optimizeWithFlags modified_package [ "-march=znver2" "-mtune=znver2" ]) else - prev.duckstation; + modified_package; in { duckstation = pkgs.buildEnv { - name = prev.duckstation.name; + name = original_package.name; paths = [ (config.lib.nixGL.wrap original_package) ]; diff --git a/nix/steam_deck/configuration/roles/duckstation/package/001-fix-test-inclusion.diff b/nix/steam_deck/configuration/roles/duckstation/package/001-fix-test-inclusion.diff new file mode 100644 index 0000000..b2dabe0 --- /dev/null +++ b/nix/steam_deck/configuration/roles/duckstation/package/001-fix-test-inclusion.diff @@ -0,0 +1,11 @@ +diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt +index 879d46bc..95570f6b 100644 +--- a/src/CMakeLists.txt ++++ b/src/CMakeLists.txt +@@ -20,5 +20,5 @@ if(BUILD_REGTEST) + endif() + + if(BUILD_TESTS) +- add_subdirectory(common-tests EXCLUDE_FROM_ALL) ++ add_subdirectory(common-tests) + endif() diff --git a/nix/steam_deck/configuration/roles/duckstation/package/002-hardcode-vars.diff b/nix/steam_deck/configuration/roles/duckstation/package/002-hardcode-vars.diff new file mode 100644 index 0000000..edba33f --- /dev/null +++ b/nix/steam_deck/configuration/roles/duckstation/package/002-hardcode-vars.diff @@ -0,0 +1,19 @@ +diff --git a/src/scmversion/gen_scmversion.sh b/src/scmversion/gen_scmversion.sh +index 9122cd8..50ed8f9 100755 +--- a/src/scmversion/gen_scmversion.sh ++++ b/src/scmversion/gen_scmversion.sh +@@ -10,10 +10,10 @@ else + fi + + +-HASH=$(git rev-parse HEAD) +-BRANCH=$(git rev-parse --abbrev-ref HEAD | tr -d '\r\n') +-TAG=$(git describe --dirty | tr -d '\r\n') +-DATE=$(git log -1 --date=iso8601-strict --format=%cd) ++HASH="@gitHash@" ++BRANCH="@gitBranch@" ++TAG="@gitTag@" ++DATE="@gitDate@" + + cd $CURDIR + diff --git a/nix/steam_deck/configuration/roles/duckstation/package/003-fix-NEON-intrinsics.patch b/nix/steam_deck/configuration/roles/duckstation/package/003-fix-NEON-intrinsics.patch new file mode 100644 index 0000000..571a15d --- /dev/null +++ b/nix/steam_deck/configuration/roles/duckstation/package/003-fix-NEON-intrinsics.patch @@ -0,0 +1,70 @@ +From 19e094e5c7aaaf375a13424044521701e85c8313 Mon Sep 17 00:00:00 2001 +From: OPNA2608 +Date: Thu, 9 Jan 2025 17:46:25 +0100 +Subject: [PATCH] Fix usage of NEON intrinsics + +--- + src/common/gsvector_neon.h | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/src/common/gsvector_neon.h b/src/common/gsvector_neon.h +index e4991af5e..61b8dc09b 100644 +--- a/src/common/gsvector_neon.h ++++ b/src/common/gsvector_neon.h +@@ -867,7 +867,7 @@ public: + + ALWAYS_INLINE int mask() const + { +- const uint32x2_t masks = vshr_n_u32(vreinterpret_u32_s32(v2s), 31); ++ const uint32x2_t masks = vshr_n_u32(vreinterpret_u32_f32(v2s), 31); + return (vget_lane_u32(masks, 0) | (vget_lane_u32(masks, 1) << 1)); + } + +@@ -2882,7 +2882,7 @@ public: + ALWAYS_INLINE GSVector4 gt64(const GSVector4& v) const + { + #ifdef CPU_ARCH_ARM64 +- return GSVector4(vreinterpretq_f32_f64(vcgtq_f64(vreinterpretq_f64_f32(v4s), vreinterpretq_f64_f32(v.v4s)))); ++ return GSVector4(vreinterpretq_f32_u64(vcgtq_f64(vreinterpretq_f64_f32(v4s), vreinterpretq_f64_f32(v.v4s)))); + #else + GSVector4 ret; + ret.U64[0] = (F64[0] > v.F64[0]) ? 0xFFFFFFFFFFFFFFFFULL : 0; +@@ -2894,7 +2894,7 @@ public: + ALWAYS_INLINE GSVector4 eq64(const GSVector4& v) const + { + #ifdef CPU_ARCH_ARM64 +- return GSVector4(vreinterpretq_f32_f64(vceqq_f64(vreinterpretq_f64_f32(v4s), vreinterpretq_f64_f32(v.v4s)))); ++ return GSVector4(vreinterpretq_f32_u64(vceqq_f64(vreinterpretq_f64_f32(v4s), vreinterpretq_f64_f32(v.v4s)))); + #else + GSVector4 ret; + ret.U64[0] = (F64[0] == v.F64[0]) ? 0xFFFFFFFFFFFFFFFFULL : 0; +@@ -2906,7 +2906,7 @@ public: + ALWAYS_INLINE GSVector4 lt64(const GSVector4& v) const + { + #ifdef CPU_ARCH_ARM64 +- return GSVector4(vreinterpretq_f32_f64(vcgtq_f64(vreinterpretq_f64_f32(v4s), vreinterpretq_f64_f32(v.v4s)))); ++ return GSVector4(vreinterpretq_f32_u64(vcgtq_f64(vreinterpretq_f64_f32(v4s), vreinterpretq_f64_f32(v.v4s)))); + #else + GSVector4 ret; + ret.U64[0] = (F64[0] < v.F64[0]) ? 0xFFFFFFFFFFFFFFFFULL : 0; +@@ -2918,7 +2918,7 @@ public: + ALWAYS_INLINE GSVector4 ge64(const GSVector4& v) const + { + #ifdef CPU_ARCH_ARM64 +- return GSVector4(vreinterpretq_f32_f64(vcgeq_f64(vreinterpretq_f64_f32(v4s), vreinterpretq_f64_f32(v.v4s)))); ++ return GSVector4(vreinterpretq_f32_u64(vcgeq_f64(vreinterpretq_f64_f32(v4s), vreinterpretq_f64_f32(v.v4s)))); + #else + GSVector4 ret; + ret.U64[0] = (F64[0] >= v.F64[0]) ? 0xFFFFFFFFFFFFFFFFULL : 0; +@@ -2930,7 +2930,7 @@ public: + ALWAYS_INLINE GSVector4 le64(const GSVector4& v) const + { + #ifdef CPU_ARCH_ARM64 +- return GSVector4(vreinterpretq_f32_f64(vcleq_f64(vreinterpretq_f64_f32(v4s), vreinterpretq_f64_f32(v.v4s)))); ++ return GSVector4(vreinterpretq_f32_u64(vcleq_f64(vreinterpretq_f64_f32(v4s), vreinterpretq_f64_f32(v.v4s)))); + #else + GSVector4 ret; + ret.U64[0] = (F64[0] <= v.F64[0]) ? 0xFFFFFFFFFFFFFFFFULL : 0; +-- +2.47.0 + diff --git a/nix/steam_deck/configuration/roles/duckstation/package/LICENSE b/nix/steam_deck/configuration/roles/duckstation/package/LICENSE new file mode 100644 index 0000000..cd250d1 --- /dev/null +++ b/nix/steam_deck/configuration/roles/duckstation/package/LICENSE @@ -0,0 +1,26 @@ +# The files in this folder are imported from nixpkg https://github.com/NixOS/nixpkgs . +# +# They have slight modifications to fix the package build on my home-manager systems. +# +# The original license is reproduced below: + +Copyright (c) 2003-2025 Eelco Dolstra and the Nixpkgs/NixOS contributors + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/nix/steam_deck/configuration/roles/duckstation/package/package.nix b/nix/steam_deck/configuration/roles/duckstation/package/package.nix new file mode 100644 index 0000000..c84a3cd --- /dev/null +++ b/nix/steam_deck/configuration/roles/duckstation/package/package.nix @@ -0,0 +1,147 @@ +{ + lib, + stdenv, + llvmPackages, + SDL2, + callPackage, + cmake, + cpuinfo, + cubeb, + curl, + extra-cmake-modules, + libXrandr, + libbacktrace, + libwebp, + makeWrapper, + ninja, + pkg-config, + qt6, + vulkan-loader, + wayland, + wayland-scanner, +}: + +let + sources = callPackage ./sources.nix { }; + inherit (qt6) + qtbase + qtsvg + qttools + qtwayland + wrapQtAppsHook + ; +in +llvmPackages.stdenv.mkDerivation (finalAttrs: { + inherit (sources.duckstation) pname version src; + + patches = [ + # Tests are not built by default + ./001-fix-test-inclusion.diff + # Patching yet another script that fills data based on git commands . . . + ./002-hardcode-vars.diff + # Fix NEON intrinsics usage + ./003-fix-NEON-intrinsics.patch + ./remove-cubeb-vendor.patch + ]; + + nativeBuildInputs = [ + cmake + extra-cmake-modules + ninja + pkg-config + qttools + wayland-scanner + wrapQtAppsHook + ]; + + buildInputs = [ + SDL2 + cpuinfo + cubeb + curl + libXrandr + libbacktrace + libwebp + qtbase + qtsvg + qtwayland + sources.discord-rpc-patched + sources.lunasvg + sources.shaderc-patched + sources.soundtouch-patched + sources.spirv-cross-patched + wayland + ]; + + cmakeFlags = [ + (lib.cmakeBool "BUILD_TESTS" true) + ]; + + strictDeps = true; + + doInstallCheck = true; + + postPatch = '' + gitHash=$(cat .nixpkgs-auxfiles/git_hash) \ + gitBranch=$(cat .nixpkgs-auxfiles/git_branch) \ + gitTag=$(cat .nixpkgs-auxfiles/git_tag) \ + gitDate=$(cat .nixpkgs-auxfiles/git_date) \ + substituteAllInPlace src/scmversion/gen_scmversion.sh + ''; + + # error: cannot convert 'int16x8_t' to '__Int32x4_t' + env.NIX_CFLAGS_COMPILE = lib.optionalString stdenv.hostPlatform.isAarch64 "-flax-vector-conversions"; + + installCheckPhase = '' + runHook preInstallCheck + + $out/share/duckstation/common-tests + + runHook postInstallCheck + ''; + + installPhase = '' + runHook preInstall + + mkdir -p $out/bin $out/share + + cp -r bin $out/share/duckstation + ln -s $out/share/duckstation/duckstation-qt $out/bin/ + + install -Dm644 $src/scripts/org.duckstation.DuckStation.desktop $out/share/applications/org.duckstation.DuckStation.desktop + install -Dm644 $src/scripts/org.duckstation.DuckStation.png $out/share/pixmaps/org.duckstation.DuckStation.png + + runHook postInstall + ''; + + qtWrapperArgs = + let + libPath = lib.makeLibraryPath ([ + sources.shaderc-patched + sources.spirv-cross-patched + vulkan-loader + ]); + in + [ + "--prefix LD_LIBRARY_PATH : ${libPath}" + ]; + + # https://github.com/stenzek/duckstation/blob/master/scripts/appimage/apprun-hooks/default-to-x11.sh + # Can't avoid the double wrapping, the binary wrapper from qtWrapperArgs doesn't support --run + postFixup = '' + source "${makeWrapper}/nix-support/setup-hook" + wrapProgram $out/bin/duckstation-qt \ + --run 'if [[ -z $I_WANT_A_BROKEN_WAYLAND_UI ]]; then export QT_QPA_PLATFORM=xcb; fi' + ''; + + meta = { + homepage = "https://github.com/stenzek/duckstation"; + description = "Fast PlayStation 1 emulator for x86-64/AArch32/AArch64"; + license = lib.licenses.gpl3Only; + mainProgram = "duckstation-qt"; + maintainers = with lib.maintainers; [ + guibou + ]; + platforms = lib.platforms.linux; + }; +}) diff --git a/nix/steam_deck/configuration/roles/duckstation/package/remove-cubeb-vendor.patch b/nix/steam_deck/configuration/roles/duckstation/package/remove-cubeb-vendor.patch new file mode 100644 index 0000000..e740b06 --- /dev/null +++ b/nix/steam_deck/configuration/roles/duckstation/package/remove-cubeb-vendor.patch @@ -0,0 +1,33 @@ +diff --git a/dep/CMakeLists.txt b/dep/CMakeLists.txt +index af35687..8347825 100644 +--- a/dep/CMakeLists.txt ++++ b/dep/CMakeLists.txt +@@ -22,9 +22,8 @@ add_subdirectory(rcheevos EXCLUDE_FROM_ALL) + disable_compiler_warnings_for_target(rcheevos) + add_subdirectory(rapidyaml EXCLUDE_FROM_ALL) + disable_compiler_warnings_for_target(rapidyaml) +-add_subdirectory(cubeb EXCLUDE_FROM_ALL) +-disable_compiler_warnings_for_target(cubeb) +-disable_compiler_warnings_for_target(speex) ++find_package(cubeb REQUIRED GLOBAL) ++add_library(cubeb ALIAS cubeb::cubeb) + add_subdirectory(kissfft EXCLUDE_FROM_ALL) + disable_compiler_warnings_for_target(kissfft) + +diff --git a/src/util/cubeb_audio_stream.cpp b/src/util/cubeb_audio_stream.cpp +index 85579c4..339190a 100644 +--- a/src/util/cubeb_audio_stream.cpp ++++ b/src/util/cubeb_audio_stream.cpp +@@ -261,9 +261,9 @@ std::vector> AudioStream::GetCubebDriverName + std::vector> names; + names.emplace_back(std::string(), TRANSLATE_STR("AudioStream", "Default")); + +- const char** cubeb_names = cubeb_get_backend_names(); +- for (u32 i = 0; cubeb_names[i] != nullptr; i++) +- names.emplace_back(cubeb_names[i], cubeb_names[i]); ++ cubeb_backend_names backends = cubeb_get_backend_names(); ++ for (u32 i = 0; i < backends.count; i++) ++ names.emplace_back(backends.names[i], backends.names[i]); + return names; + } + diff --git a/nix/steam_deck/configuration/roles/duckstation/package/shaderc-patched.nix b/nix/steam_deck/configuration/roles/duckstation/package/shaderc-patched.nix new file mode 100644 index 0000000..3211925 --- /dev/null +++ b/nix/steam_deck/configuration/roles/duckstation/package/shaderc-patched.nix @@ -0,0 +1,20 @@ +{ + fetchpatch, + duckstation, + shaderc, +}: + +shaderc.overrideAttrs (old: { + pname = "shaderc-patched-for-duckstation"; + patches = (old.patches or [ ]) ++ [ + (fetchpatch { + url = "file://${duckstation.src}/scripts/shaderc-changes.patch"; + hash = "sha256-Ps/D+CdSbjVWg3ZGOEcgbpQbCNkI5Nuizm4E5qiM9Wo="; + excludes = [ + "CHANGES" + "CMakeLists.txt" + "libshaderc/CMakeLists.txt" + ]; + }) + ]; +}) diff --git a/nix/steam_deck/configuration/roles/duckstation/package/sources.nix b/nix/steam_deck/configuration/roles/duckstation/package/sources.nix new file mode 100644 index 0000000..8261f08 --- /dev/null +++ b/nix/steam_deck/configuration/roles/duckstation/package/sources.nix @@ -0,0 +1,166 @@ +{ + lib, + duckstation, + fetchFromGitHub, + fetchpatch, + shaderc, + spirv-cross, + discord-rpc, + stdenv, + cmake, + ninja, +}: + +{ + duckstation = + let + self = { + pname = "duckstation"; + version = "0.1-7465"; + src = fetchFromGitHub { + owner = "stenzek"; + repo = "duckstation"; + rev = "aa955b8ae28314ae061613f0ddf13183a98aca03"; + # + # Some files are filled by using Git commands; it requires deepClone. + # More info at `checkout_ref` function in nix-prefetch-git. + # However, `.git` is a bit nondeterministic (and Git itself makes no + # guarantees whatsoever). + # Then, in order to enhance reproducibility, what we will do here is: + # + # - Execute the desired Git commands; + # - Save the obtained info into files; + # - Remove `.git` afterwards. + # + deepClone = true; + postFetch = '' + cd $out + mkdir -p .nixpkgs-auxfiles/ + git rev-parse HEAD > .nixpkgs-auxfiles/git_hash + git rev-parse --abbrev-ref HEAD | tr -d '\r\n' > .nixpkgs-auxfiles/git_branch + git describe --dirty | tr -d '\r\n' > .nixpkgs-auxfiles/git_tag + git log -1 --date=iso8601-strict --format=%cd > .nixpkgs-auxfiles/git_date + find $out -name .git -print0 | xargs -0 rm -fr + ''; + hash = "sha256-ixrlr7Rm6GZAn/kh2sSeCCiK/qdmQ5+5jbbhAKjTx/E="; + }; + }; + in + self; + + shaderc-patched = shaderc.overrideAttrs ( + old: + let + version = "2024.3-unstable-2024-08-24"; + src = fetchFromGitHub { + owner = "stenzek"; + repo = "shaderc"; + rev = "f60bb80e255144e71776e2ad570d89b78ea2ab4f"; + hash = "sha256-puZxkrEVhhUT4UcCtEDmtOMX4ugkB6ooMhKRBlb++lE="; + }; + in + { + pname = "shaderc-patched-for-duckstation"; + inherit version src; + patches = (old.patches or [ ]); + cmakeFlags = (old.cmakeFlags or [ ]) ++ [ + (lib.cmakeBool "SHADERC_SKIP_EXAMPLES" true) + (lib.cmakeBool "SHADERC_SKIP_TESTS" true) + ]; + outputs = [ + "out" + "lib" + "dev" + ]; + postFixup = ''''; + } + ); + spirv-cross-patched = spirv-cross.overrideAttrs ( + old: + let + version = "1.3.290.0"; + src = fetchFromGitHub { + owner = "KhronosGroup"; + repo = "SPIRV-Cross"; + rev = "vulkan-sdk-${version}"; + hash = "sha256-h5My9PbPq1l03xpXQQFolNy7G1RhExtTH6qPg7vVF/8="; + }; + in + { + pname = "spirv-cross-patched-for-duckstation"; + inherit version src; + patches = (old.patches or [ ]); + cmakeFlags = (old.cmakeFlags or [ ]) ++ [ + (lib.cmakeBool "SPIRV_CROSS_CLI" false) + (lib.cmakeBool "SPIRV_CROSS_ENABLE_CPP" false) + (lib.cmakeBool "SPIRV_CROSS_ENABLE_C_API" true) + (lib.cmakeBool "SPIRV_CROSS_ENABLE_GLSL" true) + (lib.cmakeBool "SPIRV_CROSS_ENABLE_HLSL" false) + (lib.cmakeBool "SPIRV_CROSS_ENABLE_MSL" false) + (lib.cmakeBool "SPIRV_CROSS_ENABLE_REFLECT" false) + (lib.cmakeBool "SPIRV_CROSS_ENABLE_TESTS" false) + (lib.cmakeBool "SPIRV_CROSS_ENABLE_UTIL" true) + (lib.cmakeBool "SPIRV_CROSS_SHARED" true) + (lib.cmakeBool "SPIRV_CROSS_STATIC" false) + ]; + } + ); + discord-rpc-patched = discord-rpc.overrideAttrs (old: { + pname = "discord-rpc-patched-for-duckstation"; + version = "3.4.0-unstable-2024-08-02"; + src = fetchFromGitHub { + owner = "stenzek"; + repo = "discord-rpc"; + rev = "144f3a3f1209994d8d9e8a87964a989cb9911c1e"; + hash = "sha256-VyL8bEjY001eHWcEoUPIAFDAmaAbwcNb1hqlV2a3cWs="; + }; + patches = (old.patches or [ ]); + }); + + soundtouch-patched = stdenv.mkDerivation (finalAttrs: { + pname = "soundtouch-patched-for-duckstation"; + version = "2.2.3-unstable-2024-08-02"; + src = fetchFromGitHub { + owner = "stenzek"; + repo = "soundtouch"; + rev = "463ade388f3a51da078dc9ed062bf28e4ba29da7"; + hash = "sha256-hvBW/z+fmh/itNsJnlDBtiI1DZmUMO9TpHEztjo2pA0="; + }; + + nativeBuildInputs = [ + cmake + ninja + ]; + + meta = { + homepage = "https://github.com/stenzek/soundtouch"; + description = "SoundTouch Audio Processing Library (forked from https://codeberg.org/soundtouch/soundtouch)"; + license = lib.licenses.lgpl21; + platforms = lib.platforms.linux; + }; + + }); + + lunasvg = stdenv.mkDerivation (finalAttrs: { + pname = "lunasvg-patched-for-duckstation"; + version = "2.4.1-unstable-2024-08-24"; + src = fetchFromGitHub { + owner = "stenzek"; + repo = "lunasvg"; + rev = "9af1ac7b90658a279b372add52d6f77a4ebb482c"; + hash = "sha256-ZzOe84ZF5JRrJ9Lev2lwYOccqtEGcf76dyCDBDTvI2o="; + }; + + nativeBuildInputs = [ + cmake + ninja + ]; + + meta = { + homepage = "https://github.com/stenzek/lunasvg"; + description = "Standalone SVG rendering library in C++"; + license = lib.licenses.mit; + platforms = lib.platforms.linux; + }; + }); +}