diff options
Diffstat (limited to 'pkgs/applications/emulators')
7 files changed, 668 insertions, 583 deletions
diff --git a/pkgs/applications/emulators/retroarch/cores.nix b/pkgs/applications/emulators/retroarch/cores.nix index 65b117629306..a738432a8ec3 100644 --- a/pkgs/applications/emulators/retroarch/cores.nix +++ b/pkgs/applications/emulators/retroarch/cores.nix @@ -6,6 +6,7 @@ , cmake , curl , fetchFromGitHub +, fetchpatch , ffmpeg , fluidsynth , gettext @@ -38,7 +39,6 @@ , xxd , xz , zlib -, fetchpatch }: let @@ -47,297 +47,283 @@ let getCoreSrc = core: fetchFromGitHub (builtins.getAttr core hashesFile); - mkLibRetroCore = + mkLibretroCore = { core - , description - # Check https://github.com/libretro/libretro-core-info for license information - , license - , stdenvOverride ? stdenv , src ? (getCoreSrc core) - , broken ? false , version ? "unstable-2022-10-18" - , platforms ? retroarch.meta.platforms - # The resulting core file is based on core name - # Setting `normalizeCore` to `true` will convert `-` to `_` on the core filename - , normalizeCore ? true , ... }@args: - stdenvOverride.mkDerivation ( - let - inherit (stdenvOverride) hostPlatform; - d2u = if normalizeCore then (lib.replaceChars [ "-" ] [ "_" ]) else (x: x); - in - (rec { - pname = "libretro-${core}"; - inherit version src; - - buildInputs = [ zlib ] ++ args.extraBuildInputs or [ ]; - nativeBuildInputs = [ makeWrapper ] ++ args.extraNativeBuildInputs or [ ]; - - makefile = "Makefile.libretro"; - makeFlags = [ - "platform=${{ - linux = "unix"; - darwin = "osx"; - windows = "win"; - }.${hostPlatform.parsed.kernel.name} or hostPlatform.parsed.kernel.name}" - "ARCH=${{ - armv7l = "arm"; - armv6l = "arm"; - i686 = "x86"; - }.${hostPlatform.parsed.cpu.name} or hostPlatform.parsed.cpu.name}" - ] ++ (args.makeFlags or [ ]); - - coreDir = "${placeholder "out"}/lib/retroarch/cores"; - - installPhase = '' - runHook preInstall - - mkdir -p $out/bin - mkdir -p $coreDir - mv ${d2u args.core}_libretro${hostPlatform.extensions.sharedLibrary} $coreDir - makeWrapper ${retroarch}/bin/retroarch $out/bin/retroarch-${core} \ - --add-flags "-L $coreDir/${d2u core}_libretro${hostPlatform.extensions.sharedLibrary} $@" - - runHook postInstall - ''; - - enableParallelBuilding = true; - - passthru = { - inherit core; - libretroCore = "/lib/retroarch/cores"; - }; - - meta = with lib; { - inherit broken description license platforms; - homepage = "https://www.libretro.com/"; - maintainers = with maintainers; teams.libretro.members ++ [ hrdinka ]; - }; - }) // builtins.removeAttrs args [ "core" "src" "description" "license" "makeFlags" ] - ); + import ./mkLibretroCore.nix ({ + inherit lib stdenv core src version makeWrapper retroarch zlib; + } // args); in { - inherit mkLibRetroCore; + inherit mkLibretroCore; - atari800 = mkLibRetroCore { + atari800 = mkLibretroCore { core = "atari800"; - description = "Port of Atari800 to libretro"; - license = lib.licenses.gpl2Only; makefile = "Makefile"; makeFlags = [ "GIT_VERSION=" ]; + meta = { + description = "Port of Atari800 to libretro"; + license = lib.licenses.gpl2Only; + }; }; - beetle-gba = mkLibRetroCore { + beetle-gba = mkLibretroCore { core = "mednafen-gba"; src = getCoreSrc "beetle-gba"; - description = "Port of Mednafen's GameBoy Advance core to libretro"; - license = lib.licenses.gpl2Only; makefile = "Makefile"; + meta = { + description = "Port of Mednafen's GameBoy Advance core to libretro"; + license = lib.licenses.gpl2Only; + }; }; - beetle-lynx = mkLibRetroCore { + beetle-lynx = mkLibretroCore { core = "mednafen-lynx"; src = getCoreSrc "beetle-lynx"; - description = "Port of Mednafen's Lynx core to libretro"; - license = lib.licenses.gpl2Only; makefile = "Makefile"; + meta = { + description = "Port of Mednafen's Lynx core to libretro"; + license = lib.licenses.gpl2Only; + }; }; - beetle-ngp = mkLibRetroCore { + beetle-ngp = mkLibretroCore { core = "mednafen-ngp"; src = getCoreSrc "beetle-ngp"; - description = "Port of Mednafen's NeoGeo Pocket core to libretro"; - license = lib.licenses.gpl2Only; makefile = "Makefile"; + meta = { + description = "Port of Mednafen's NeoGeo Pocket core to libretro"; + license = lib.licenses.gpl2Only; + }; }; - beetle-pce-fast = mkLibRetroCore { + beetle-pce-fast = mkLibretroCore { core = "mednafen-pce-fast"; src = getCoreSrc "beetle-pce-fast"; - description = "Port of Mednafen's PC Engine core to libretro"; - license = lib.licenses.gpl2Only; makefile = "Makefile"; + meta = { + description = "Port of Mednafen's PC Engine core to libretro"; + license = lib.licenses.gpl2Only; + }; }; - beetle-pcfx = mkLibRetroCore { + beetle-pcfx = mkLibretroCore { core = "mednafen-pcfx"; src = getCoreSrc "beetle-pcfx"; - description = "Port of Mednafen's PCFX core to libretro"; - license = lib.licenses.gpl2Only; makefile = "Makefile"; + meta = { + description = "Port of Mednafen's PCFX core to libretro"; + license = lib.licenses.gpl2Only; + }; }; - beetle-psx = mkLibRetroCore { + beetle-psx = mkLibretroCore { core = "mednafen-psx"; src = getCoreSrc "beetle-psx"; - description = "Port of Mednafen's PSX Engine core to libretro"; - license = lib.licenses.gpl2Only; makefile = "Makefile"; makeFlags = [ "HAVE_HW=0" "HAVE_LIGHTREC=1" ]; + meta = { + description = "Port of Mednafen's PSX Engine core to libretro"; + license = lib.licenses.gpl2Only; + }; }; - beetle-psx-hw = mkLibRetroCore { + beetle-psx-hw = mkLibretroCore { core = "mednafen-psx-hw"; src = getCoreSrc "beetle-psx"; - description = "Port of Mednafen's PSX Engine (with HW accel) core to libretro"; - license = lib.licenses.gpl2Only; extraBuildInputs = [ libGL libGLU ]; makefile = "Makefile"; makeFlags = [ "HAVE_VULKAN=1" "HAVE_OPENGL=1" "HAVE_HW=1" "HAVE_LIGHTREC=1" ]; + meta = { + description = "Port of Mednafen's PSX Engine (with HW accel) core to libretro"; + license = lib.licenses.gpl2Only; + }; }; - beetle-saturn = mkLibRetroCore { + beetle-saturn = mkLibretroCore { core = "mednafen-saturn"; src = getCoreSrc "beetle-saturn"; - description = "Port of Mednafen's Saturn core to libretro"; - license = lib.licenses.gpl2Only; makefile = "Makefile"; - platforms = [ "x86_64-linux" "aarch64-linux" ]; + meta = { + description = "Port of Mednafen's Saturn core to libretro"; + license = lib.licenses.gpl2Only; + platforms = [ "aarch64-linux" "x86_64-linux" ]; + }; }; - beetle-snes = mkLibRetroCore { + beetle-snes = mkLibretroCore { core = "mednafen-snes"; src = getCoreSrc "beetle-snes"; - description = "Port of Mednafen's SNES core to libretro"; - license = lib.licenses.gpl2Only; makefile = "Makefile"; + meta = { + description = "Port of Mednafen's SNES core to libretro"; + license = lib.licenses.gpl2Only; + }; }; - beetle-supafaust = mkLibRetroCore { + beetle-supafaust = mkLibretroCore { core = "mednafen-supafaust"; src = getCoreSrc "beetle-supafaust"; - description = "Port of Mednafen's experimental snes_faust core to libretro"; - license = lib.licenses.gpl2Plus; makefile = "Makefile"; + meta = { + description = "Port of Mednafen's experimental snes_faust core to libretro"; + license = lib.licenses.gpl2Plus; + }; }; - beetle-supergrafx = mkLibRetroCore { + beetle-supergrafx = mkLibretroCore { core = "mednafen-supergrafx"; src = getCoreSrc "beetle-supergrafx"; - description = "Port of Mednafen's SuperGrafx core to libretro"; - license = lib.licenses.gpl2Only; makefile = "Makefile"; + meta = { + description = "Port of Mednafen's SuperGrafx core to libretro"; + license = lib.licenses.gpl2Only; + }; }; - beetle-vb = mkLibRetroCore { + beetle-vb = mkLibretroCore { core = "mednafen-vb"; src = getCoreSrc "beetle-vb"; - description = "Port of Mednafen's VirtualBoy core to libretro"; - license = lib.licenses.gpl2Only; makefile = "Makefile"; + meta = { + description = "Port of Mednafen's VirtualBoy core to libretro"; + license = lib.licenses.gpl2Only; + }; }; - beetle-wswan = mkLibRetroCore { + beetle-wswan = mkLibretroCore { core = "mednafen-wswan"; src = getCoreSrc "beetle-wswan"; - description = "Port of Mednafen's WonderSwan core to libretro"; - license = lib.licenses.gpl2Only; makefile = "Makefile"; + meta = { + description = "Port of Mednafen's WonderSwan core to libretro"; + license = lib.licenses.gpl2Only; + }; }; - blastem = mkLibRetroCore { + blastem = mkLibretroCore { core = "blastem"; - description = "Port of BlastEm to libretro"; - license = lib.licenses.gpl3Only; - platforms = lib.platforms.x86; + meta = { + description = "Port of BlastEm to libretro"; + license = lib.licenses.gpl3Only; + platforms = lib.platforms.x86; + }; }; - bluemsx = mkLibRetroCore { + bluemsx = mkLibretroCore { core = "bluemsx"; - description = "Port of BlueMSX to libretro"; - license = lib.licenses.gpl2Only; + meta = { + description = "Port of BlueMSX to libretro"; + license = lib.licenses.gpl2Only; + }; }; - bsnes = mkLibRetroCore { + bsnes = mkLibretroCore { core = "bsnes"; - description = "Port of bsnes to libretro"; - license = lib.licenses.gpl3Only; makefile = "Makefile"; + meta = { + description = "Port of bsnes to libretro"; + license = lib.licenses.gpl3Only; + }; }; - bsnes-hd = - let - # linux = bsd - # https://github.com/DerKoun/bsnes-hd/blob/f0b6cf34e9780d53516977ed2de64137a8bcc3c5/bsnes/GNUmakefile#L37 - platform = if stdenv.isDarwin then "macos" else "linux"; - in - mkLibRetroCore { - core = "bsnes-hd-beta"; - src = getCoreSrc "bsnes-hd"; - description = "Port of bsnes-hd to libretro"; - license = lib.licenses.gpl3Only; - makefile = "GNUmakefile"; - makeFlags = [ + bsnes-hd = mkLibretroCore { + core = "bsnes-hd-beta"; + src = getCoreSrc "bsnes-hd"; + makefile = "GNUmakefile"; + makeFlags = + let + # linux = bsd + # https://github.com/DerKoun/bsnes-hd/blob/f0b6cf34e9780d53516977ed2de64137a8bcc3c5/bsnes/GNUmakefile#L37 + platform = if stdenv.isDarwin then "macos" else "linux"; + in + [ "-C" "bsnes" "target=libretro" "platform=${platform}" ]; - extraBuildInputs = [ xorg.libX11 xorg.libXext ]; - postBuild = "cd bsnes/out"; + extraBuildInputs = [ xorg.libX11 xorg.libXext ]; + postBuild = "cd bsnes/out"; + meta = { + description = "Port of bsnes-hd to libretro"; + license = lib.licenses.gpl3Only; }; + }; - bsnes-mercury = mkLibRetroCore { + bsnes-mercury = mkLibretroCore { core = "bsnes-mercury-accuracy"; src = getCoreSrc "bsnes-mercury"; - description = "Fork of bsnes with HLE DSP emulation restored"; - license = lib.licenses.gpl3Only; makefile = "Makefile"; makeFlags = [ "PROFILE=accuracy" ]; + meta = { + description = "Fork of bsnes with HLE DSP emulation restored (accuracy profile)"; + license = lib.licenses.gpl3Only; + }; }; - bsnes-mercury-balanced = mkLibRetroCore { + bsnes-mercury-balanced = mkLibretroCore { core = "bsnes-mercury-balanced"; src = getCoreSrc "bsnes-mercury"; - description = "Fork of bsnes with HLE DSP emulation restored"; - license = lib.licenses.gpl3Only; makefile = "Makefile"; makeFlags = [ "PROFILE=balanced" ]; + meta = { + description = "Fork of bsnes with HLE DSP emulation restored (balanced profile)"; + license = lib.licenses.gpl3Only; + }; }; - bsnes-mercury-performance = mkLibRetroCore { + bsnes-mercury-performance = mkLibretroCore { core = "bsnes-mercury-performance"; src = getCoreSrc "bsnes-mercury"; - description = "Fork of bsnes with HLE DSP emulation restored"; - license = lib.licenses.gpl3Only; makefile = "Makefile"; makeFlags = [ "PROFILE=performance" ]; + meta = { + description = "Fork of bsnes with HLE DSP emulation restored (performance profile)"; + license = lib.licenses.gpl3Only; + }; }; - citra = mkLibRetroCore { + citra = mkLibretroCore { core = "citra"; - description = "Port of Citra to libretro"; - license = lib.licenses.gpl2Plus; extraBuildInputs = [ libGLU libGL boost ffmpeg nasm ]; makefile = "Makefile"; makeFlags = [ "HAVE_FFMPEG_STATIC=0" ]; + meta = { + description = "Port of Citra to libretro"; + license = lib.licenses.gpl2Plus; + }; }; - desmume = mkLibRetroCore { + desmume = mkLibretroCore { core = "desmume"; - description = "libretro wrapper for desmume NDS emulator"; - license = lib.licenses.gpl2Plus; - extraBuildInputs = [ libpcap libGLU libGL xorg.libX11 ]; preBuild = "cd desmume/src/frontend/libretro"; + extraBuildInputs = [ libpcap libGLU libGL xorg.libX11 ]; makeFlags = lib.optional stdenv.hostPlatform.isAarch32 "platform=armv-unix" ++ lib.optional (!stdenv.hostPlatform.isx86) "DESMUME_JIT=0"; + meta = { + description = "Port of DeSmuME to libretro"; + license = lib.licenses.gpl2Plus; + }; }; - desmume2015 = mkLibRetroCore { + desmume2015 = mkLibretroCore { core = "desmume2015"; - description = "libretro wrapper for desmume NDS emulator from 2015"; - license = lib.licenses.gpl2Plus; extraBuildInputs = [ libpcap libGLU libGL xorg.libX11 ]; makeFlags = lib.optional stdenv.hostPlatform.isAarch32 "platform=armv-unix" ++ lib.optional (!stdenv.hostPlatform.isx86) "DESMUME_JIT=0"; preBuild = "cd desmume"; + meta = { + description = "Port of DeSmuME ~2015 to libretro"; + license = lib.licenses.gpl2Plus; + }; }; - dolphin = mkLibRetroCore { + dolphin = mkLibretroCore { core = "dolphin"; - description = "Port of Dolphin to libretro"; - license = lib.licenses.gpl2Plus; extraNativeBuildInputs = [ cmake curl pkg-config ]; extraBuildInputs = [ libGLU @@ -359,284 +345,354 @@ in "-DUSE_DISCORD_PRESENCE=OFF" ]; dontUseCmakeBuildDir = true; + meta = { + description = "Port of Dolphin to libretro"; + license = lib.licenses.gpl2Plus; + }; }; - dosbox = mkLibRetroCore { + dosbox = mkLibretroCore { core = "dosbox"; - description = "Port of DOSBox to libretro"; - license = lib.licenses.gpl2Only; CXXFLAGS = "-std=gnu++11"; + meta = { + description = "Port of DOSBox to libretro"; + license = lib.licenses.gpl2Only; + }; }; - eightyone = mkLibRetroCore { + eightyone = mkLibretroCore { core = "81"; src = getCoreSrc "eightyone"; - description = "Port of EightyOne to libretro"; - license = lib.licenses.gpl3Only; + meta = { + description = "Port of EightyOne to libretro"; + license = lib.licenses.gpl3Only; + }; }; - fbalpha2012 = mkLibRetroCore { + fbalpha2012 = mkLibretroCore { core = "fbalpha2012"; - description = "Port of Final Burn Alpha ~2012 to libretro"; - license = "Non-commercial"; makefile = "makefile.libretro"; preBuild = "cd svn-current/trunk"; + meta = { + description = "Port of Final Burn Alpha ~2012 to libretro"; + license = "Non-commercial"; + }; }; - fbneo = mkLibRetroCore { + fbneo = mkLibretroCore { core = "fbneo"; - description = "Port of FBNeo to libretro"; - license = "Non-commercial"; makefile = "Makefile"; preBuild = "cd src/burner/libretro"; + meta = { + description = "Port of FBNeo to libretro"; + license = "Non-commercial"; + }; }; - fceumm = mkLibRetroCore { + fceumm = mkLibretroCore { core = "fceumm"; - description = "FCEUmm libretro port"; - license = lib.licenses.gpl2Only; + meta = { + description = "FCEUmm libretro port"; + license = lib.licenses.gpl2Only; + }; }; - flycast = mkLibRetroCore { + flycast = mkLibretroCore { core = "flycast"; - description = "Flycast libretro port"; - license = lib.licenses.gpl2Only; extraBuildInputs = [ libGL libGLU ]; makefile = "Makefile"; makeFlags = lib.optionals stdenv.hostPlatform.isAarch64 [ "platform=arm64" ]; patches = [ ./fix-flycast-makefile.patch ]; - platforms = [ "aarch64-linux" "x86_64-linux" ]; + meta = { + description = "Flycast libretro port"; + license = lib.licenses.gpl2Only; + platforms = [ "aarch64-linux" "x86_64-linux" ]; + }; }; - fmsx = mkLibRetroCore { + fmsx = mkLibretroCore { core = "fmsx"; - description = "FMSX libretro port"; - license = "Non-commercial"; makefile = "Makefile"; + meta = { + description = "FMSX libretro port"; + license = "Non-commercial"; + }; }; - freeintv = mkLibRetroCore { + freeintv = mkLibretroCore { core = "freeintv"; - description = "FreeIntv libretro port"; - license = lib.licenses.gpl3Only; makefile = "Makefile"; + meta = { + description = "FreeIntv libretro port"; + license = lib.licenses.gpl3Only; + }; }; - gambatte = mkLibRetroCore { + gambatte = mkLibretroCore { core = "gambatte"; - description = "Gambatte libretro port"; - license = lib.licenses.gpl2Only; + meta = { + description = "Gambatte libretro port"; + license = lib.licenses.gpl2Only; + }; }; - genesis-plus-gx = mkLibRetroCore { + genesis-plus-gx = mkLibretroCore { core = "genesis-plus-gx"; - description = "Enhanced Genesis Plus libretro port"; - license = "Non-commercial"; + meta = { + description = "Enhanced Genesis Plus libretro port"; + license = "Non-commercial"; + }; }; - gpsp = mkLibRetroCore { + gpsp = mkLibretroCore { core = "gpsp"; - description = "Port of gpSP to libretro"; - license = lib.licenses.gpl2Only; makefile = "Makefile"; + meta = { + description = "Port of gpSP to libretro"; + license = lib.licenses.gpl2Only; + }; }; - gw = mkLibRetroCore { + gw = mkLibretroCore { core = "gw"; - description = "Port of Game and Watch to libretro"; - license = lib.licenses.zlib; makefile = "Makefile"; + meta = { + description = "Port of Game and Watch to libretro"; + license = lib.licenses.zlib; + }; }; - handy = mkLibRetroCore { + handy = mkLibretroCore { core = "handy"; - description = "Port of Handy to libretro"; - license = lib.licenses.zlib; makefile = "Makefile"; + meta = { + description = "Port of Handy to libretro"; + license = lib.licenses.zlib; + }; }; - hatari = mkLibRetroCore { + hatari = mkLibretroCore { core = "hatari"; - description = "Port of Hatari to libretro"; - license = lib.licenses.gpl2Only; extraNativeBuildInputs = [ which ]; dontConfigure = true; - # zlib is already included in mkLibRetroCore as buildInputs + # zlib is already included in mkLibretroCore as buildInputs makeFlags = [ "EXTERNAL_ZLIB=1" ]; + meta = { + description = "Port of Hatari to libretro"; + license = lib.licenses.gpl2Only; + }; }; - mame = mkLibRetroCore { + mame = mkLibretroCore { core = "mame"; - description = "Port of MAME to libretro"; - license = with lib.licenses; [ bsd3 gpl2Plus ]; extraBuildInputs = [ alsa-lib libGLU libGL portaudio python3 xorg.libX11 ]; + meta = { + description = "Port of MAME to libretro"; + license = with lib.licenses; [ bsd3 gpl2Plus ]; + }; }; - mame2000 = mkLibRetroCore { + mame2000 = mkLibretroCore { core = "mame2000"; - description = "Port of MAME ~2000 to libretro, compatible with MAME 0.37b5 sets"; - license = "MAME"; makefile = "Makefile"; makeFlags = lib.optional (!stdenv.hostPlatform.isx86) "IS_X86=0"; + meta = { + description = "Port of MAME ~2000 to libretro, compatible with MAME 0.37b5 sets"; + license = "MAME"; + }; }; - mame2003 = mkLibRetroCore { + mame2003 = mkLibretroCore { core = "mame2003"; - description = "Port of MAME ~2003 to libretro, compatible with MAME 0.78 sets"; - license = "MAME"; makefile = "Makefile"; + meta = { + description = "Port of MAME ~2003 to libretro, compatible with MAME 0.78 sets"; + license = "MAME"; + }; }; - mame2003-plus = mkLibRetroCore { + mame2003-plus = mkLibretroCore { core = "mame2003-plus"; - description = "Port of MAME ~2003+ to libretro, compatible with MAME 0.78 sets"; - license = "MAME"; makefile = "Makefile"; + meta = { + description = "Port of MAME ~2003+ to libretro, compatible with MAME 0.78 sets"; + license = "MAME"; + }; }; - mame2010 = mkLibRetroCore { + mame2010 = mkLibretroCore { core = "mame2010"; - description = "Port of MAME ~2010 to libretro, compatible with MAME 0.139 sets"; - license = "MAME"; makefile = "Makefile"; makeFlags = lib.optionals stdenv.hostPlatform.isAarch64 [ "PTR64=1" "ARM_ENABLED=1" "X86_SH2DRC=0" "FORCE_DRC_C_BACKEND=1" ]; + meta = { + description = "Port of MAME ~2010 to libretro, compatible with MAME 0.139 sets"; + license = "MAME"; + }; }; - mame2015 = mkLibRetroCore { + mame2015 = mkLibretroCore { core = "mame2015"; - description = "Port of MAME ~2015 to libretro, compatible with MAME 0.160 sets"; - license = "MAME"; makeFlags = [ "PYTHON=python3" ]; extraNativeBuildInputs = [ python3 ]; extraBuildInputs = [ alsa-lib ]; makefile = "Makefile"; enableParallelBuilding = false; + meta = { + description = "Port of MAME ~2015 to libretro, compatible with MAME 0.160 sets"; + license = "MAME"; + }; }; - mame2016 = mkLibRetroCore { + mame2016 = mkLibretroCore { core = "mame2016"; - description = "Port of MAME ~2016 to libretro, compatible with MAME 0.174 sets"; - license = with lib.licenses; [ bsd3 gpl2Plus ]; extraNativeBuildInputs = [ python3 ]; extraBuildInputs = [ alsa-lib ]; makeFlags = [ "PYTHON_EXECUTABLE=python3" ]; enableParallelBuilding = false; + meta = { + description = "Port of MAME ~2016 to libretro, compatible with MAME 0.174 sets"; + license = with lib.licenses; [ bsd3 gpl2Plus ]; + }; }; - melonds = mkLibRetroCore { + melonds = mkLibretroCore { core = "melonds"; - description = "Port of MelonDS to libretro"; - license = lib.licenses.gpl3Only; extraBuildInputs = [ libGL libGLU ]; makefile = "Makefile"; + meta = { + description = "Port of MelonDS to libretro"; + license = lib.licenses.gpl3Only; + }; }; - mesen = mkLibRetroCore { + mesen = mkLibretroCore { core = "mesen"; - description = "Port of Mesen to libretro"; - license = lib.licenses.gpl3Only; makefile = "Makefile"; preBuild = "cd Libretro"; + meta = { + description = "Port of Mesen to libretro"; + license = lib.licenses.gpl3Only; + }; }; - mesen-s = mkLibRetroCore { + mesen-s = mkLibretroCore { core = "mesen-s"; - description = "Port of Mesen-S to libretro"; - license = lib.licenses.gpl3Only; makefile = "Makefile"; preBuild = "cd Libretro"; normalizeCore = false; + meta = { + description = "Port of Mesen-S to libretro"; + license = lib.licenses.gpl3Only; + }; }; - meteor = mkLibRetroCore { + meteor = mkLibretroCore { core = "meteor"; - description = "Port of Meteor to libretro"; - license = lib.licenses.gpl3Only; makefile = "Makefile"; preBuild = "cd libretro"; + meta = { + description = "Port of Meteor to libretro"; + license = lib.licenses.gpl3Only; + }; }; - mgba = mkLibRetroCore { + mgba = mkLibretroCore { core = "mgba"; - description = "Port of mGBA to libretro"; - license = lib.licenses.mpl20; + meta = { + description = "Port of mGBA to libretro"; + license = lib.licenses.mpl20; + }; }; - mupen64plus = mkLibRetroCore { + mupen64plus = mkLibretroCore { core = "mupen64plus-next"; src = getCoreSrc "mupen64plus"; - description = "Libretro port of Mupen64 Plus, GL only"; - license = lib.licenses.gpl3Only; extraBuildInputs = [ libGLU libGL libpng nasm xorg.libX11 ]; makefile = "Makefile"; + meta = { + description = "Libretro port of Mupen64 Plus, GL only"; + license = lib.licenses.gpl3Only; + }; }; - neocd = mkLibRetroCore { + neocd = mkLibretroCore { core = "neocd"; - description = "NeoCD libretro port"; - license = lib.licenses.lgpl3Only; makefile = "Makefile"; + meta = { + description = "NeoCD libretro port"; + license = lib.licenses.lgpl3Only; + }; }; - nestopia = mkLibRetroCore { + nestopia = mkLibretroCore { core = "nestopia"; - description = "Nestopia libretro port"; - license = lib.licenses.gpl2Only; makefile = "Makefile"; preBuild = "cd libretro"; + meta = { + description = "Nestopia libretro port"; + license = lib.licenses.gpl2Only; + }; }; - nxengine = mkLibRetroCore { + nxengine = mkLibretroCore { core = "nxengine"; - description = "NXEngine libretro port"; - license = lib.licenses.gpl3Only; makefile = "Makefile"; + meta = { + description = "NXEngine libretro port"; + license = lib.licenses.gpl3Only; + }; }; - np2kai = mkLibRetroCore rec { + np2kai = mkLibretroCore rec { core = "np2kai"; src = getCoreSrc core; - description = "Neko Project II kai libretro port"; - license = lib.licenses.mit; makeFlags = [ # See https://github.com/AZO234/NP2kai/tags "NP2KAI_VERSION=rev.22" "NP2KAI_HASH=${src.rev}" ]; preBuild = "cd sdl"; + meta = { + description = "Neko Project II kai libretro port"; + license = lib.licenses.mit; + }; }; - o2em = mkLibRetroCore { + o2em = mkLibretroCore { core = "o2em"; - description = "Port of O2EM to libretro"; - license = lib.licenses.artistic1; makefile = "Makefile"; + meta = { + description = "Port of O2EM to libretro"; + license = lib.licenses.artistic1; + }; }; - opera = mkLibRetroCore { + opera = mkLibretroCore { core = "opera"; - description = "Opera is a port of 4DO/libfreedo to libretro"; - license = "Non-commercial"; makefile = "Makefile"; makeFlags = [ "CC_PREFIX=${stdenv.cc.targetPrefix}" ]; + meta = { + description = "Opera is a port of 4DO/libfreedo to libretro"; + license = "Non-commercial"; + }; }; - parallel-n64 = mkLibRetroCore { + parallel-n64 = mkLibretroCore { core = "parallel-n64"; - description = "Parallel Mupen64plus rewrite for libretro."; - license = lib.licenses.gpl3Only; extraBuildInputs = [ libGLU libGL libpng ]; makefile = "Makefile"; postPatch = lib.optionalString stdenv.hostPlatform.isAarch64 '' sed -i -e '1 i\CPUFLAGS += -DARM_FIX -DNO_ASM -DARM_ASM -DDONT_WANT_ARM_OPTIMIZATIONS -DARM64' Makefile \ && sed -i -e 's,CPUFLAGS :=,,g' Makefile ''; + meta = { + description = "Parallel Mupen64plus rewrite for libretro."; + license = lib.licenses.gpl3Only; + }; }; - pcsx2 = mkLibRetroCore { + pcsx2 = mkLibretroCore { core = "pcsx2"; - description = "Port of PCSX2 to libretro"; - license = lib.licenses.gpl3Plus; extraNativeBuildInputs = [ cmake gettext @@ -661,39 +717,47 @@ in substituteInPlace CMakeLists.txt --replace "ccache" "" ''; postBuild = "cd /build/source/build/pcsx2"; - platforms = lib.platforms.x86; + meta = { + description = "Port of PCSX2 to libretro"; + license = lib.licenses.gpl3Plus; + platforms = lib.platforms.x86; + }; }; - pcsx-rearmed = mkLibRetroCore { + pcsx-rearmed = mkLibretroCore { core = "pcsx_rearmed"; - description = "Port of PCSX ReARMed with GNU lightning to libretro"; - license = lib.licenses.gpl2Only; dontConfigure = true; + meta = { + description = "Port of PCSX ReARMed with GNU lightning to libretro"; + license = lib.licenses.gpl2Only; + }; }; - picodrive = mkLibRetroCore { + picodrive = mkLibretroCore { core = "picodrive"; - description = "Fast MegaDrive/MegaCD/32X emulator"; - license = "MAME"; dontConfigure = true; makeFlags = lib.optionals stdenv.hostPlatform.isAarch64 [ "platform=aarch64" ]; + meta = { + description = "Fast MegaDrive/MegaCD/32X emulator"; + license = "MAME"; + }; }; - play = mkLibRetroCore { + play = mkLibretroCore { core = "play"; - description = "Port of Play! to libretro"; - license = lib.licenses.bsd2; extraBuildInputs = [ boost bzip2 curl openssl icu libGL libGLU xorg.libX11 ]; extraNativeBuildInputs = [ cmake ]; makefile = "Makefile"; cmakeFlags = [ "-DBUILD_PLAY=OFF" "-DBUILD_LIBRETRO_CORE=ON" ]; postBuild = "cd Source/ui_libretro"; + meta = { + description = "Port of Play! to libretro"; + license = lib.licenses.bsd2; + }; }; - ppsspp = mkLibRetroCore { + ppsspp = mkLibretroCore { core = "ppsspp"; - description = "ppsspp libretro port"; - license = lib.licenses.gpl2Plus; extraNativeBuildInputs = [ cmake pkg-config python3 ]; extraBuildInputs = [ libGLU libGL libzip ffmpeg snappy xorg.libX11 ]; makefile = "Makefile"; @@ -705,149 +769,186 @@ in "-DOpenGL_GL_PREFERENCE=GLVND" ]; postBuild = "cd lib"; + meta = { + description = "ppsspp libretro port"; + license = lib.licenses.gpl2Plus; + }; }; - prboom = mkLibRetroCore { + prboom = mkLibretroCore { core = "prboom"; - description = "Prboom libretro port"; - license = lib.licenses.gpl2Only; makefile = "Makefile"; + meta = { + description = "Prboom libretro port"; + license = lib.licenses.gpl2Only; + }; }; - prosystem = mkLibRetroCore { + prosystem = mkLibretroCore { core = "prosystem"; - description = "Port of ProSystem to libretro"; - license = lib.licenses.gpl2Only; makefile = "Makefile"; + meta = { + description = "Port of ProSystem to libretro"; + license = lib.licenses.gpl2Only; + }; }; - puae = mkLibRetroCore { + puae = mkLibretroCore { core = "puae"; - description = "Amiga emulator based on WinUAE"; - license = lib.licenses.gpl2Only; makefile = "Makefile"; + # https://github.com/libretro/libretro-uae/pull/529 patches = fetchpatch { - url = "https://github.com/libretro/libretro-uae/commit/90ba4c9bb940e566781c3590553270ad69cf212e.patch"; - sha256 = "sha256-9xkRravvyFZc0xsIj0OSm2ux5BqYogfQ1TDnH9l6jKw="; + url = "https://github.com/libretro/libretro-uae/commit/90ba4c9bb940e566781c3590553270ad69cf212e.patch"; + sha256 = "sha256-9xkRravvyFZc0xsIj0OSm2ux5BqYogfQ1TDnH9l6jKw="; + }; + meta = { + description = "Amiga emulator based on WinUAE"; + license = lib.licenses.gpl2Only; }; }; - quicknes = mkLibRetroCore { + quicknes = mkLibretroCore { core = "quicknes"; - description = "QuickNES libretro port"; - license = lib.licenses.lgpl21Plus; makefile = "Makefile"; + meta = { + description = "QuickNES libretro port"; + license = lib.licenses.lgpl21Plus; + }; }; - sameboy = mkLibRetroCore { + sameboy = mkLibretroCore { core = "sameboy"; - description = "SameBoy libretro port"; - license = lib.licenses.mit; extraNativeBuildInputs = [ which hexdump ]; preBuild = "cd libretro"; makefile = "Makefile"; + meta = { + description = "SameBoy libretro port"; + license = lib.licenses.mit; + }; }; - scummvm = mkLibRetroCore { + scummvm = mkLibretroCore { core = "scummvm"; - description = "Libretro port of ScummVM"; - license = lib.licenses.gpl2Only; extraBuildInputs = [ fluidsynth libjpeg libvorbis libGLU libGL ]; makefile = "Makefile"; preConfigure = "cd backends/platform/libretro/build"; + meta = { + description = "Libretro port of ScummVM"; + license = lib.licenses.gpl2Only; + }; }; - smsplus-gx = mkLibRetroCore { + smsplus-gx = mkLibretroCore { core = "smsplus"; src = getCoreSrc "smsplus-gx"; - description = "SMS Plus GX libretro port"; - license = lib.licenses.gpl2Plus; + meta = { + description = "SMS Plus GX libretro port"; + license = lib.licenses.gpl2Plus; + }; }; - snes9x = mkLibRetroCore { + snes9x = mkLibretroCore { core = "snes9x"; - description = "Port of SNES9x git to libretro"; - license = "Non-commercial"; makefile = "Makefile"; preBuild = "cd libretro"; + meta = { + description = "Port of SNES9x git to libretro"; + license = "Non-commercial"; + }; }; - snes9x2002 = mkLibRetroCore { + snes9x2002 = mkLibretroCore { core = "snes9x2002"; - description = "Optimized port/rewrite of SNES9x 1.39 to Libretro"; - license = "Non-commercial"; makefile = "Makefile"; + meta = { + description = "Optimized port/rewrite of SNES9x 1.39 to Libretro"; + license = "Non-commercial"; + }; }; - snes9x2005 = mkLibRetroCore { + snes9x2005 = mkLibretroCore { core = "snes9x2005"; - description = "Optimized port/rewrite of SNES9x 1.43 to Libretro"; - license = "Non-commercial"; makefile = "Makefile"; + meta = { + description = "Optimized port/rewrite of SNES9x 1.43 to Libretro"; + license = "Non-commercial"; + }; }; - snes9x2005-plus = mkLibRetroCore { + snes9x2005-plus = mkLibretroCore { core = "snes9x2005-plus"; src = getCoreSrc "snes9x2005"; - description = "Optimized port/rewrite of SNES9x 1.43 to Libretro, with Blargg's APU"; - license = "Non-commercial"; makefile = "Makefile"; makeFlags = [ "USE_BLARGG_APU=1" ]; + meta = { + description = "Optimized port/rewrite of SNES9x 1.43 to Libretro, with Blargg's APU"; + license = "Non-commercial"; + }; }; - snes9x2010 = mkLibRetroCore { + snes9x2010 = mkLibretroCore { core = "snes9x2010"; - description = "Optimized port/rewrite of SNES9x 1.52+ to Libretro"; - license = "Non-commercial"; + meta = { + description = "Optimized port/rewrite of SNES9x 1.52+ to Libretro"; + license = "Non-commercial"; + }; }; - stella = mkLibRetroCore { + stella = mkLibretroCore { core = "stella"; - description = "Port of Stella to libretro"; - license = lib.licenses.gpl2Only; makefile = "Makefile"; preBuild = "cd src/os/libretro"; dontConfigure = true; + meta = { + description = "Port of Stella to libretro"; + license = lib.licenses.gpl2Only; + }; }; - stella2014 = mkLibRetroCore { + stella2014 = mkLibretroCore { core = "stella2014"; - description = "Port of Stella to libretro"; - license = lib.licenses.gpl2Only; makefile = "Makefile"; + meta = { + description = "Port of Stella ~2014 to libretro"; + license = lib.licenses.gpl2Only; + }; }; - swanstation = mkLibRetroCore { + swanstation = mkLibretroCore { core = "swanstation"; - description = "Port of SwanStation (a fork of DuckStation) to libretro"; - license = lib.licenses.gpl3Only; extraNativeBuildInputs = [ cmake ]; makefile = "Makefile"; cmakeFlags = [ "-DBUILD_LIBRETRO_CORE=ON" ]; + meta = { + description = "Port of SwanStation (a fork of DuckStation) to libretro"; + license = lib.licenses.gpl3Only; + }; }; - tgbdual = mkLibRetroCore { + tgbdual = mkLibretroCore { core = "tgbdual"; - description = "Port of TGBDual to libretro"; - license = lib.licenses.gpl2Only; makefile = "Makefile"; + meta = { + description = "Port of TGBDual to libretro"; + license = lib.licenses.gpl2Only; + }; }; - thepowdertoy = mkLibRetroCore { + thepowdertoy = mkLibretroCore { core = "thepowdertoy"; - description = "Port of The Powder Toy to libretro"; - license = lib.licenses.gpl3Only; extraNativeBuildInputs = [ cmake ]; makefile = "Makefile"; postBuild = "cd src"; + meta = { + description = "Port of The Powder Toy to libretro"; + license = lib.licenses.gpl3Only; + }; }; - tic80 = mkLibRetroCore { + tic80 = mkLibretroCore { core = "tic80"; - description = "Port of TIC-80 to libretro"; - license = lib.licenses.mit; extraNativeBuildInputs = [ cmake pkg-config ]; makefile = "Makefile"; cmakeFlags = [ @@ -860,44 +961,58 @@ in ]; preConfigure = "cd core"; postBuild = "cd lib"; + meta = { + description = "Port of TIC-80 to libretro"; + license = lib.licenses.mit; + }; }; - vba-m = mkLibRetroCore { + vba-m = mkLibretroCore { core = "vbam"; src = getCoreSrc "vba-m"; - description = "vanilla VBA-M libretro port"; - license = lib.licenses.gpl2Only; makefile = "Makefile"; preBuild = "cd src/libretro"; + meta = { + description = "vanilla VBA-M libretro port"; + license = lib.licenses.gpl2Only; + }; }; - vba-next = mkLibRetroCore { + vba-next = mkLibretroCore { core = "vba-next"; - description = "VBA-M libretro port with modifications for speed"; - license = lib.licenses.gpl2Only; + meta = { + description = "VBA-M libretro port with modifications for speed"; + license = lib.licenses.gpl2Only; + }; }; - vecx = mkLibRetroCore { + vecx = mkLibretroCore { core = "vecx"; - description = "Port of Vecx to libretro"; - license = lib.licenses.gpl3Only; extraBuildInputs = [ libGL libGLU ]; + meta = { + description = "Port of Vecx to libretro"; + license = lib.licenses.gpl3Only; + }; }; - virtualjaguar = mkLibRetroCore { + virtualjaguar = mkLibretroCore { core = "virtualjaguar"; - description = "Port of VirtualJaguar to libretro"; - license = lib.licenses.gpl3Only; makefile = "Makefile"; + meta = { + description = "Port of VirtualJaguar to libretro"; + license = lib.licenses.gpl3Only; + }; }; - yabause = mkLibRetroCore { + yabause = mkLibretroCore { core = "yabause"; - description = "Port of Yabause to libretro"; - license = lib.licenses.gpl2Only; makefile = "Makefile"; # Disable SSE for non-x86. DYNAREC doesn't build on aarch64. makeFlags = lib.optional (!stdenv.hostPlatform.isx86) "HAVE_SSE=0"; preBuild = "cd yabause/src/libretro"; + meta = { + description = "Port of Yabause to libretro"; + license = lib.licenses.gpl2Only; + }; }; } diff --git a/pkgs/applications/emulators/retroarch/default.nix b/pkgs/applications/emulators/retroarch/default.nix index a8a20682afd4..d0a281afc373 100644 --- a/pkgs/applications/emulators/retroarch/default.nix +++ b/pkgs/applications/emulators/retroarch/default.nix @@ -6,18 +6,17 @@ , withVulkan ? stdenv.isLinux , withWayland ? stdenv.isLinux , alsa-lib -, AppKit , dbus , fetchFromGitHub , ffmpeg_4 -, Foundation +, flac , freetype , gamemode , libdrm , libGL , libGLU -, libobjc , libpulseaudio +, libretro-core-info , libv4l , libX11 , libXdmcp @@ -26,71 +25,61 @@ , libxml2 , libXxf86vm , makeWrapper +, mbedtls , mesa , nvidia_cg_toolkit , pkg-config , python3 , SDL2 +, substituteAll , udev , vulkan-loader , wayland +, zlib }: let - version = "1.12.0"; - libretroCoreInfo = fetchFromGitHub { - owner = "libretro"; - repo = "libretro-core-info"; - sha256 = "sha256-9Sfp/JkMJIe34YGNRxf93fONOBuQxR2pduoJU+xtuF0="; - # Upstream didn't tag a new libretro-core-info in 1.12.0 release - rev = "v1.11.1"; - }; runtimeLibs = lib.optional withVulkan vulkan-loader ++ lib.optional withGamemode (lib.getLib gamemode); in stdenv.mkDerivation rec { pname = "retroarch-bare"; - inherit version; + version = "1.12.0"; src = fetchFromGitHub { owner = "libretro"; repo = "RetroArch"; - sha256 = "sha256-doLWNA8aTAllxx3zABtvZaegBQEPIi8276zbytPSdBU="; + hash = "sha256-doLWNA8aTAllxx3zABtvZaegBQEPIi8276zbytPSdBU="; rev = "v${version}"; }; patches = [ - ./use-fixed-paths.patch + (substituteAll { + src = ./use-fixed-path-for-libretro_core_info.patch; + libretro_info_path = libretro-core-info; + }) ]; - postPatch = '' - substituteInPlace "frontend/drivers/platform_unix.c" \ - --subst-var-by libretro_directory "$out/lib" \ - --subst-var-by libretro_info_path "$out/share/libretro/info" \ - --subst-var-by out "$out" - substituteInPlace "frontend/drivers/platform_darwin.m" \ - --subst-var-by libretro_directory "$out/lib" \ - --subst-var-by libretro_info_path "$out/share/libretro/info" - ''; - nativeBuildInputs = [ pkg-config ] ++ lib.optional withWayland wayland ++ lib.optional (runtimeLibs != [ ]) makeWrapper; buildInputs = [ ffmpeg_4 + flac freetype libGL libGLU libxml2 + mbedtls python3 SDL2 + zlib ] ++ lib.optional enableNvidiaCgToolkit nvidia_cg_toolkit ++ lib.optional withVulkan vulkan-loader ++ lib.optional withWayland wayland ++ - lib.optionals stdenv.isDarwin [ libobjc AppKit Foundation ] ++ lib.optionals stdenv.isLinux [ alsa-lib dbus @@ -110,6 +99,9 @@ stdenv.mkDerivation rec { configureFlags = [ "--disable-update_cores" + "--disable-builtinmbedtls" + "--disable-builtinzlib" + "--disable-builtinflac" ] ++ lib.optionals stdenv.isLinux [ "--enable-dbus" @@ -117,39 +109,13 @@ stdenv.mkDerivation rec { "--enable-kms" ]; - postInstall = '' - # TODO: ideally each core should have its own core information - mkdir -p $out/share/libretro/info - cp -r ${libretroCoreInfo}/* $out/share/libretro/info - '' + - lib.optionalString (runtimeLibs != [ ]) '' + postInstall = lib.optionalString (runtimeLibs != [ ]) '' wrapProgram $out/bin/retroarch \ --prefix LD_LIBRARY_PATH ':' ${lib.makeLibraryPath runtimeLibs} - '' + - lib.optionalString stdenv.isDarwin '' - # https://github.com/libretro/RetroArch/blob/master/retroarch-apple-packaging.sh - app=$out/Applications/RetroArch.app - mkdir -p $app/Contents/MacOS - cp -r pkg/apple/OSX/* $app/Contents - cp $out/bin/retroarch $app/Contents/MacOS - # FIXME: using Info_Metal.plist results in input not working - # mv $app/Contents/Info_Metal.plist $app/Contents/Info.plist - - substituteInPlace $app/Contents/Info.plist \ - --replace '${"\${EXECUTABLE_NAME}"}' 'RetroArch' \ - --replace '$(PRODUCT_BUNDLE_IDENTIFIER)' 'com.libretro.RetroArch' \ - --replace '${"\${PRODUCT_NAME}"}' 'RetroArch' \ - --replace '${"\${MACOSX_DEPLOYMENT_TARGET}"}' '10.13' - - cp media/retroarch.icns $app/Contents/Resources/ ''; preFixup = "rm $out/bin/retroarch-cg2glsl"; - # Workaround for the following error affecting newer versions of Clang: - # ./config.def.h:xxx:x: error: 'TARGET_OS_TV' is not defined, evaluates to 0 [-Werror,-Wundef-prefix=TARGET_OS_] - NIX_CFLAGS_COMPILE = lib.optionals stdenv.cc.isClang [ "-Wno-undef-prefix" ]; - passthru.tests = nixosTests.retroarch; meta = with lib; { @@ -159,9 +125,11 @@ stdenv.mkDerivation rec { platforms = platforms.unix; changelog = "https://github.com/libretro/RetroArch/blob/v${version}/CHANGES.md"; maintainers = with maintainers; teams.libretro.members ++ [ matthewbauer kolbycrouch ]; - # FIXME: error while building in macOS: - # "Undefined symbols for architecture <arch>" - # See also retroarch/wrapper.nix that is also broken in macOS + mainProgram = "retroarch"; + # If you want to (re)-add support for macOS, see: + # https://docs.libretro.com/development/retroarch/compilation/osx/ + # and + # https://github.com/libretro/RetroArch/blob/71eb74d256cb4dc5b8b43991aec74980547c5069/.gitlab-ci.yml#L330 broken = stdenv.isDarwin; }; } diff --git a/pkgs/applications/emulators/retroarch/libretro-core-info.nix b/pkgs/applications/emulators/retroarch/libretro-core-info.nix new file mode 100644 index 000000000000..1dd8b0e4b748 --- /dev/null +++ b/pkgs/applications/emulators/retroarch/libretro-core-info.nix @@ -0,0 +1,28 @@ +{ lib +, stdenvNoCC +, fetchFromGitHub +}: + +stdenvNoCC.mkDerivation rec { + pname = "libretro-core-info"; + version = "1.12.0"; + + src = fetchFromGitHub { + owner = "libretro"; + repo = "libretro-core-info"; + hash = "sha256-ByATDM0V40UJxigqVLyTWkHY5tiCC2dvZebksl8GsUI="; + rev = "v${version}"; + }; + + makeFlags = [ "PREFIX=$(out)" ]; + + dontBuild = true; + + meta = with lib; { + description = "Libretro's core info files"; + homepage = "https://libretro.com"; + license = licenses.mit; + maintainers = with maintainers; teams.libretro.members ++ [ ]; + platforms = platforms.all; + }; +} diff --git a/pkgs/applications/emulators/retroarch/mkLibretroCore.nix b/pkgs/applications/emulators/retroarch/mkLibretroCore.nix new file mode 100644 index 000000000000..6ab652127009 --- /dev/null +++ b/pkgs/applications/emulators/retroarch/mkLibretroCore.nix @@ -0,0 +1,80 @@ +{ lib +, stdenv +, core +, makeWrapper +, retroarch +, zlib +, makefile ? "Makefile.libretro" +, extraBuildInputs ? [ ] +, extraNativeBuildInputs ? [ ] + # Location of resulting RetroArch core on $out +, libretroCore ? "/lib/retroarch/cores" + # The core filename is derivated from the core name + # Setting `normalizeCore` to `true` will convert `-` to `_` on the core filename +, normalizeCore ? true +, ... +}@args: + +let + d2u = if normalizeCore then (lib.replaceChars [ "-" ] [ "_" ]) else (x: x); + coreDir = placeholder "out" + libretroCore; + coreFilename = "${d2u core}_libretro${stdenv.hostPlatform.extensions.sharedLibrary}"; + mainProgram = "retroarch-${core}"; + extraArgs = builtins.removeAttrs args [ + "lib" + "stdenv" + "core" + "makeWrapper" + "retroarch" + "zlib" + "makefile" + "extraBuildInputs" + "extraNativeBuildInputs" + "libretroCore" + "normalizeCore" + "makeFlags" + "meta" + ]; +in +stdenv.mkDerivation ({ + pname = "libretro-${core}"; + + buildInputs = [ zlib ] ++ extraBuildInputs; + nativeBuildInputs = [ makeWrapper ] ++ extraNativeBuildInputs; + + inherit makefile; + + makeFlags = [ + "platform=${{ + linux = "unix"; + darwin = "osx"; + windows = "win"; + }.${stdenv.hostPlatform.parsed.kernel.name} or stdenv.hostPlatform.parsed.kernel.name}" + "ARCH=${{ + armv7l = "arm"; + armv6l = "arm"; + i686 = "x86"; + }.${stdenv.hostPlatform.parsed.cpu.name} or stdenv.hostPlatform.parsed.cpu.name}" + ] ++ (args.makeFlags or [ ]); + + installPhase = '' + runHook preInstall + + install -Dt ${coreDir} ${coreFilename} + makeWrapper ${retroarch}/bin/retroarch $out/bin/${mainProgram} \ + --add-flags "-L ${coreDir}/${coreFilename} $@" + + runHook postInstall + ''; + + enableParallelBuilding = true; + + passthru = { inherit core libretroCore; }; + + meta = with lib; { + inherit mainProgram; + inherit (retroarch.meta) platforms; + homepage = "https://www.libretro.com/"; + maintainers = with maintainers; teams.libretro.members ++ [ hrdinka ]; + } // (args.meta or { }); +} // extraArgs) diff --git a/pkgs/applications/emulators/retroarch/use-fixed-path-for-libretro_core_info.patch b/pkgs/applications/emulators/retroarch/use-fixed-path-for-libretro_core_info.patch new file mode 100644 index 000000000000..256397fd49ea --- /dev/null +++ b/pkgs/applications/emulators/retroarch/use-fixed-path-for-libretro_core_info.patch @@ -0,0 +1,41 @@ +From 6145cb9ed935621f1974655fe1ab44cf2f0fbcce Mon Sep 17 00:00:00 2001 +From: Thiago Kenji Okada <thiagokokada@gmail.com> +Date: Sat, 29 Oct 2022 12:27:55 +0100 +Subject: [PATCH] Use fixed path for libretro_core_info + +--- + configuration.c | 2 +- + frontend/drivers/platform_unix.c | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/configuration.c b/configuration.c +index af3fc8f43c..c6d56308b3 100644 +--- a/configuration.c ++++ b/configuration.c +@@ -1468,7 +1468,7 @@ static struct config_path_setting *populate_settings_path( + SETTING_PATH("core_options_path", + settings->paths.path_core_options, false, NULL, true); + SETTING_PATH("libretro_info_path", +- settings->paths.path_libretro_info, false, NULL, true); ++ settings->paths.path_libretro_info, false, NULL, false); + SETTING_PATH("content_database_path", + settings->paths.path_content_database, false, NULL, true); + SETTING_PATH("cheat_database_path", +diff --git a/frontend/drivers/platform_unix.c b/frontend/drivers/platform_unix.c +index fe5f7341c9..c2a91f8c99 100644 +--- a/frontend/drivers/platform_unix.c ++++ b/frontend/drivers/platform_unix.c +@@ -1799,8 +1799,8 @@ static void frontend_unix_get_env(int *argc, + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE_INFO], base_path, + "core_info", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE_INFO])); + #else +- fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE_INFO], base_path, +- "cores", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE_INFO])); ++ fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE_INFO], "@libretro_info_path@", ++ "share/libretro/info", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE_INFO])); + #endif + fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_AUTOCONFIG], base_path, + "autoconfig", sizeof(g_defaults.dirs[DEFAULT_DIR_AUTOCONFIG])); +-- +2.38.0 + diff --git a/pkgs/applications/emulators/retroarch/use-fixed-paths.patch b/pkgs/applications/emulators/retroarch/use-fixed-paths.patch deleted file mode 100644 index a4837e63af7f..000000000000 --- a/pkgs/applications/emulators/retroarch/use-fixed-paths.patch +++ /dev/null @@ -1,154 +0,0 @@ -From 8a1cffebb23f9d2a28228cd8cbf4fd80836157e8 Mon Sep 17 00:00:00 2001 -From: Thiago Kenji Okada <thiagokokada@gmail.com> -Date: Tue, 18 Oct 2022 17:41:33 +0100 -Subject: [PATCH] Use fixed paths - ---- - configuration.c | 2 +- - frontend/drivers/platform_darwin.m | 4 +-- - frontend/drivers/platform_unix.c | 56 +++++++++++++++--------------- - 3 files changed, 31 insertions(+), 31 deletions(-) - -diff --git a/configuration.c b/configuration.c -index ac4779b2d7..d980892dda 100644 ---- a/configuration.c -+++ b/configuration.c -@@ -1468,7 +1468,7 @@ static struct config_path_setting *populate_settings_path( - SETTING_PATH("core_options_path", - settings->paths.path_core_options, false, NULL, true); - SETTING_PATH("libretro_info_path", -- settings->paths.path_libretro_info, false, NULL, true); -+ settings->paths.path_libretro_info, false, NULL, false); - SETTING_PATH("content_database_path", - settings->paths.path_content_database, false, NULL, true); - SETTING_PATH("cheat_database_path", -diff --git a/frontend/drivers/platform_darwin.m b/frontend/drivers/platform_darwin.m -index c771ec0f55..d5e21a1f4d 100644 ---- a/frontend/drivers/platform_darwin.m -+++ b/frontend/drivers/platform_darwin.m -@@ -400,9 +400,9 @@ static void frontend_darwin_get_env(int *argc, char *argv[], - home_dir_buf, "cores", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE])); - #else - fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE], -- bundle_path_buf, "modules", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE])); -+ "@libretro_directory@", "", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE])); - #endif -- fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE_INFO], home_dir_buf, "info", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE_INFO])); -+ fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE_INFO], "@libretro_info_path@", "", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE_INFO])); - fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_OVERLAY], home_dir_buf, "overlays", sizeof(g_defaults.dirs[DEFAULT_DIR_OVERLAY])); - #ifdef HAVE_VIDEO_LAYOUT - fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_VIDEO_LAYOUT], home_dir_buf, "layouts", sizeof(g_defaults.dirs[DEFAULT_DIR_VIDEO_LAYOUT])); -diff --git a/frontend/drivers/platform_unix.c b/frontend/drivers/platform_unix.c -index 29e9a0d633..dba8abe941 100644 ---- a/frontend/drivers/platform_unix.c -+++ b/frontend/drivers/platform_unix.c -@@ -1792,8 +1792,8 @@ static void frontend_unix_get_env(int *argc, - strlcpy(g_defaults.dirs[DEFAULT_DIR_CORE], libretro_directory, - sizeof(g_defaults.dirs[DEFAULT_DIR_CORE])); - else -- fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE], base_path, -- "cores", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE])); -+ fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE], "@libretro_directory@", -+ "", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE])); - #if defined(DINGUX) - /* On platforms that require manual core installation/ - * removal, placing core info files in the same directory -@@ -1802,27 +1802,27 @@ static void frontend_unix_get_env(int *argc, - fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE_INFO], base_path, - "core_info", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE_INFO])); - #else -- fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE_INFO], base_path, -- "cores", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE_INFO])); -+ fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE_INFO], "@libretro_info_path@", -+ "", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE_INFO])); - #endif - fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_AUTOCONFIG], base_path, - "autoconfig", sizeof(g_defaults.dirs[DEFAULT_DIR_AUTOCONFIG])); - -- if (path_is_directory("/usr/local/share/retroarch/assets")) -+ if (path_is_directory("@out@/local/share/retroarch/assets")) - fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_ASSETS], -- "/usr/local/share/retroarch", -+ "@out@/local/share/retroarch", - "assets", sizeof(g_defaults.dirs[DEFAULT_DIR_ASSETS])); -- else if (path_is_directory("/usr/share/retroarch/assets")) -+ else if (path_is_directory("@out@/share/retroarch/assets")) - fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_ASSETS], -- "/usr/share/retroarch", -+ "@out@/share/retroarch", - "assets", sizeof(g_defaults.dirs[DEFAULT_DIR_ASSETS])); -- else if (path_is_directory("/usr/local/share/games/retroarch/assets")) -+ else if (path_is_directory("@out@/local/share/games/retroarch/assets")) - fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_ASSETS], -- "/usr/local/share/games/retroarch", -+ "@out@/local/share/games/retroarch", - "assets", sizeof(g_defaults.dirs[DEFAULT_DIR_ASSETS])); -- else if (path_is_directory("/usr/share/games/retroarch/assets")) -+ else if (path_is_directory("@out@/share/games/retroarch/assets")) - fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_ASSETS], -- "/usr/share/games/retroarch", -+ "@out@/share/games/retroarch", - "assets", sizeof(g_defaults.dirs[DEFAULT_DIR_ASSETS])); - else - fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_ASSETS], base_path, -@@ -1834,41 +1834,41 @@ static void frontend_unix_get_env(int *argc, - fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_VIDEO_FILTER], base_path, - "filters/video", sizeof(g_defaults.dirs[DEFAULT_DIR_VIDEO_FILTER])); - #else -- if (path_is_directory("/usr/local/share/retroarch/filters/audio")) -+ if (path_is_directory("@out@/local/share/retroarch/filters/audio")) - fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_AUDIO_FILTER], -- "/usr/local/share/retroarch", -+ "@out@/local/share/retroarch", - "filters/audio", sizeof(g_defaults.dirs[DEFAULT_DIR_AUDIO_FILTER])); -- else if (path_is_directory("/usr/share/retroarch/filters/audio")) -+ else if (path_is_directory("@out@/share/retroarch/filters/audio")) - fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_AUDIO_FILTER], -- "/usr/share/retroarch", -+ "@out@/share/retroarch", - "filters/audio", sizeof(g_defaults.dirs[DEFAULT_DIR_AUDIO_FILTER])); -- else if (path_is_directory("/usr/local/share/games/retroarch/filters/audio")) -+ else if (path_is_directory("@out@/local/share/games/retroarch/filters/audio")) - fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_AUDIO_FILTER], -- "/usr/local/share/games/retroarch", -+ "@out@/local/share/games/retroarch", - "filters/audio", sizeof(g_defaults.dirs[DEFAULT_DIR_AUDIO_FILTER])); -- else if (path_is_directory("/usr/share/games/retroarch/filters/audio")) -+ else if (path_is_directory("@out@/share/games/retroarch/filters/audio")) - fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_AUDIO_FILTER], -- "/usr/share/games/retroarch", -+ "@out@/share/games/retroarch", - "filters/audio", sizeof(g_defaults.dirs[DEFAULT_DIR_AUDIO_FILTER])); - else - fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_AUDIO_FILTER], base_path, - "filters/audio", sizeof(g_defaults.dirs[DEFAULT_DIR_AUDIO_FILTER])); - -- if (path_is_directory("/usr/local/share/retroarch/filters/video")) -+ if (path_is_directory("@out@/local/share/retroarch/filters/video")) - fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_VIDEO_FILTER], -- "/usr/local/share/retroarch", -+ "@out@/local/share/retroarch", - "filters/video", sizeof(g_defaults.dirs[DEFAULT_DIR_VIDEO_FILTER])); -- else if (path_is_directory("/usr/share/retroarch/filters/video")) -+ else if (path_is_directory("@out@/share/retroarch/filters/video")) - fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_VIDEO_FILTER], -- "/usr/share/retroarch", -+ "@out@/share/retroarch", - "filters/video", sizeof(g_defaults.dirs[DEFAULT_DIR_VIDEO_FILTER])); -- else if (path_is_directory("/usr/local/share/games/retroarch/filters/video")) -+ else if (path_is_directory("@out@/local/share/games/retroarch/filters/video")) - fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_VIDEO_FILTER], -- "/usr/local/share/games/retroarch", -+ "@out@/local/share/games/retroarch", - "filters/video", sizeof(g_defaults.dirs[DEFAULT_DIR_VIDEO_FILTER])); -- else if (path_is_directory("/usr/share/games/retroarch/filters/video")) -+ else if (path_is_directory("@out@/share/games/retroarch/filters/video")) - fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_VIDEO_FILTER], -- "/usr/share/games/retroarch", -+ "@out@/share/games/retroarch", - "filters/video", sizeof(g_defaults.dirs[DEFAULT_DIR_VIDEO_FILTER])); - else - fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_VIDEO_FILTER], base_path, --- -2.37.3 - diff --git a/pkgs/applications/emulators/retroarch/wrapper.nix b/pkgs/applications/emulators/retroarch/wrapper.nix index 535cd40db6c3..4136d263eac4 100644 --- a/pkgs/applications/emulators/retroarch/wrapper.nix +++ b/pkgs/applications/emulators/retroarch/wrapper.nix @@ -1,41 +1,48 @@ -{ stdenv, lib, makeWrapper, retroarch, cores ? [ ] }: - -stdenv.mkDerivation { - pname = "retroarch"; - version = lib.getVersion retroarch; +{ lib +, stdenv +, makeWrapper +, retroarch +, symlinkJoin +, writeTextDir +, cores ? [ ] +}: + +let + # All cores should be located in the same path after symlinkJoin, + # but let's be safe here + coresPath = lib.lists.unique (map (c: c.libretroCore) cores); + wrapperArgs = lib.strings.escapeShellArgs + (lib.lists.flatten + (map (p: [ "--add-flags" "-L ${placeholder "out" + p}" ]) coresPath)); +in +symlinkJoin { + name = "retroarch-with-cores-${lib.getVersion retroarch}"; + + paths = [ retroarch ] ++ cores; nativeBuildInputs = [ makeWrapper ]; - buildCommand = '' - mkdir -p $out/lib - for coreDir in $cores; do - ln -s $coreDir/* $out/lib/. - done - - ln -s -t $out ${retroarch}/share + passthru = { + inherit cores; + unwrapped = retroarch; + }; - if [ -d ${retroarch}/Applications ]; then - ln -s -t $out ${retroarch}/Applications - fi + postBuild = '' + # remove core specific binaries + find $out/bin -name 'retroarch-*' -type l -delete - makeWrapper ${retroarch}/bin/retroarch $out/bin/retroarch \ - --suffix-each LD_LIBRARY_PATH ':' "$cores" \ - --add-flags "-L $out/lib/" \ + # wrap binary to load cores from the proper location(s) + wrapProgram $out/bin/retroarch ${wrapperArgs} ''; - cores = map (x: x + x.libretroCore) cores; - preferLocalBuild = true; - meta = with retroarch.meta; { inherit changelog description homepage license maintainers platforms; longDescription = '' RetroArch is the reference frontend for the libretro API. - - The following cores are included: - ${lib.concatStringsSep "\n" (map (x: " - ${x.name}") cores)} + '' + + lib.optionalString (cores != [ ]) '' + The following cores are included: ${lib.concatStringsSep ", " (map (c: c.core) cores)} ''; - # FIXME: exit with error on macOS: - # No Info.plist file in application bundle or no NSPrincipalClass in the Info.plist file, exiting - broken = stdenv.isDarwin; + mainProgram = "retroarch"; }; } |