From 317757ab60e79f22e21903d503a605fc116b3635 Mon Sep 17 00:00:00 2001 From: Morgan Jones Date: Tue, 2 Apr 2024 23:28:24 -0700 Subject: [PATCH 1/5] dwarf-fortress: update release notes --- nixos/doc/manual/release-notes/rl-2405.section.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/nixos/doc/manual/release-notes/rl-2405.section.md b/nixos/doc/manual/release-notes/rl-2405.section.md index a8cefa0da604..246213c77310 100644 --- a/nixos/doc/manual/release-notes/rl-2405.section.md +++ b/nixos/doc/manual/release-notes/rl-2405.section.md @@ -401,6 +401,14 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - `nomad_1_4` has been removed, as it is now unsupported upstream. +- Dwarf Fortress has been updated to version 50, and its derivations continue to menace with spikes of Nix and bash. Version 50 is identical to the version on Steam, but without the paid elements like tilepacks. + dfhack and Dwarf Therapist still work, and older versions are still packaged in case you'd like to roll back. Note that DF 50 saves will not be compatible with DF 0.47 and earlier. + See [Bay 12 Games](http://www.bay12games.com/dwarves/) for more details on what's new in Dwarf Fortress. + + - Running an earlier version can be achieved through an override: `dwarf-fortress-packages.dwarf-fortress-full.override { dfVersion = "0.47.5"; }` + + - Ruby plugin support has been disabled in DFHack. Many of the Ruby plugins have been converted to Lua, and support was removed upstream due to frequent crashes. + - The `livebook` package is now built as a `mix release` instead of an `escript`. This means that configuration now has to be done using [environment variables](https://hexdocs.pm/livebook/readme.html#environment-variables) instead of command line arguments. This has the further implication that the `livebook` service configuration has changed: From 55b7756b7d64a2ee9b2220475a5a8fd8dd1d8b90 Mon Sep 17 00:00:00 2001 From: Morgan Jones Date: Sat, 6 Apr 2024 00:47:23 -0700 Subject: [PATCH 2/5] dwarf-fortress: df_permission: Renew permission from Tarn for v50 Get permission from Tarn to publish a v50 Dwarf Fortress in nixpkgs. The last time we did this was in 2010. (moved to df_permission/2010) --- .../{df_permission => df_permission/2010} | 0 pkgs/games/dwarf-fortress/df_permission/2024 | 57 +++++++++++++++++++ 2 files changed, 57 insertions(+) rename pkgs/games/dwarf-fortress/{df_permission => df_permission/2010} (100%) create mode 100644 pkgs/games/dwarf-fortress/df_permission/2024 diff --git a/pkgs/games/dwarf-fortress/df_permission b/pkgs/games/dwarf-fortress/df_permission/2010 similarity index 100% rename from pkgs/games/dwarf-fortress/df_permission rename to pkgs/games/dwarf-fortress/df_permission/2010 diff --git a/pkgs/games/dwarf-fortress/df_permission/2024 b/pkgs/games/dwarf-fortress/df_permission/2024 new file mode 100644 index 000000000000..cdea6958fabd --- /dev/null +++ b/pkgs/games/dwarf-fortress/df_permission/2024 @@ -0,0 +1,57 @@ +From: Tarn Adams +Date: Thu, 4 Apr 2024 20:18:35 -0700 +Subject: Re: Dwarf Fortress v50 Redistribution for NixOS +To: Morgan + +Yeah, it's fine to continue redistributing the classic version as before. + +Ah, yeah, I'm aware of the command line issue. Hopefully it can be cleaned +up with some of the other missing functionality like legends mode image +export. + +Tarn + +On Wed, Apr 3, 2024 at 1:26 AM Morgan wrote: + +> Tarn, +> +> I maintain the Dwarf Fortress package for NixOS (), +> and wanted to double check with you that packaging v50.x and later is +> still okay. One of our maintainers previously received permission, but +> that was 14(!) years ago: +> +> +> https://github.com/NixOS/nixpkgs/blob/master/pkgs/games/dwarf-fortress/df_permission +> +> Users installing Dwarf Fortress using Nix automatically pull the +> tar.bz2 classic builds from the Bay 12 Games site. The Nix package +> recipes make minor changes to some of the executable files; namely, +> patching paths to shared object files like SDL, ld-linux.so, and +> libc++ using patchelf. Users who install Nix or run NixOS can run this +> whole process automatically and have a working Dwarf Fortress with: +> +> `nix run nixpkgs#dwarf-fortress` +> +> We don't and can't distribute any of the files from Steam, though +> users who buy the game can link the Steam game data directory into +> their Nix Dwarf Fortress data directory and use the tile packs from +> the Steam version, if they like. +> +> ~ +> +> Enough of that formality: thanks for the game, it's a blast and a joy +> for the imagination. I use it to make maps for large scale (50+ +> people) D&D campaigns in Southern California. +> +> BTW, automatic world generation mode using the command line seems to +> be broken in v50.12. It navigates to the worldgen menu but doesn't get +> farther. I'm hoping I can release some Nix scripts that people can use +> to export world images and such in batch mode at some point, so I +> don't have to even mess with extracting the game files to get +> interesting map exports. +> +> Thanks, +> Morgan Jones +> ---- +> < We are failing in translating hyperreal concepts > -The Board +> From e73e6907172af0a041de5e5e2e6694ad159a7b63 Mon Sep 17 00:00:00 2001 From: Morgan Jones Date: Sat, 30 Mar 2024 20:36:51 -0700 Subject: [PATCH 3/5] dwarf-fortress: update to 50 --- pkgs/games/dwarf-fortress/default.nix | 23 ++- pkgs/games/dwarf-fortress/dfhack/default.nix | 134 ++++++++++++++---- .../dwarf-therapist/default.nix | 16 ++- .../dwarf-therapist/wrapper.nix | 19 +-- pkgs/games/dwarf-fortress/game.json | 9 ++ pkgs/games/dwarf-fortress/game.nix | 81 +++++++++-- pkgs/games/dwarf-fortress/lazy-pack.nix | 3 + pkgs/games/dwarf-fortress/unfuck.nix | 33 +++-- pkgs/games/dwarf-fortress/update.sh | 4 +- pkgs/games/dwarf-fortress/wrapper/default.nix | 118 +++++++++++---- pkgs/games/dwarf-fortress/wrapper/dfhack.in | 11 -- .../wrapper/dwarf-fortress-init.in | 110 +++++++++++--- .../dwarf-fortress/wrapper/dwarf-fortress.in | 38 ++++- 13 files changed, 460 insertions(+), 139 deletions(-) delete mode 100755 pkgs/games/dwarf-fortress/wrapper/dfhack.in diff --git a/pkgs/games/dwarf-fortress/default.nix b/pkgs/games/dwarf-fortress/default.nix index 777866d8fb0e..ce2f9f401e6e 100644 --- a/pkgs/games/dwarf-fortress/default.nix +++ b/pkgs/games/dwarf-fortress/default.nix @@ -46,31 +46,28 @@ let # The latest Dwarf Fortress version. Maintainers: when a new version comes # out, ensure that (unfuck|dfhack|twbt) are all up to date before changing - # this. - latestVersion = "0.47.05"; + # this. Note that unfuck and twbt are not required for v50. + latestVersion = "50.12"; # Converts a version to a package name. versionToName = version: "dwarf-fortress_${replaceStrings ["."] ["_"] version}"; - dwarf-therapist-original = libsForQt5.callPackage ./dwarf-therapist { - texlive = texliveBasic.withPackages (ps: with ps; [ float caption wrapfig adjmulticol sidecap preprint enumitem ]); - }; - # A map of names to each Dwarf Fortress package we know about. df-games = listToAttrs (map (dfVersion: { name = versionToName dfVersion; value = let - # I can't believe this syntax works. Spikes of Nix code indeed... + isV50 = lib.versionAtLeast dfVersion "50.0"; + + dwarf-fortress-unfuck = if isV50 then null else callPackage ./unfuck.nix { inherit dfVersion; }; + dwarf-fortress = callPackage ./game.nix { inherit dfVersion; inherit dwarf-fortress-unfuck; }; - dwarf-fortress-unfuck = callPackage ./unfuck.nix { inherit dfVersion; }; - - twbt = callPackage ./twbt { inherit dfVersion; }; + twbt = if isV50 then null else callPackage ./twbt { inherit dfVersion; }; dfhack = callPackage ./dfhack { inherit (perlPackages) XMLLibXML XMLLibXSLT; @@ -80,7 +77,10 @@ let dwarf-therapist = libsForQt5.callPackage ./dwarf-therapist/wrapper.nix { inherit dwarf-fortress; - dwarf-therapist = dwarf-therapist-original; + dwarf-therapist = libsForQt5.callPackage ./dwarf-therapist { + texlive = texliveBasic.withPackages (ps: with ps; [ float caption wrapfig adjmulticol sidecap preprint enumitem ]); + inherit isV50; + }; }; in callPackage ./wrapper { @@ -97,7 +97,6 @@ let # Aliases for the latest Dwarf Fortress and the selected Therapist install dwarf-fortress = getAttr (versionToName latestVersion) df-games; - inherit dwarf-therapist-original; dwarf-therapist = dwarf-fortress.dwarf-therapist; dwarf-fortress-original = dwarf-fortress.dwarf-fortress; diff --git a/pkgs/games/dwarf-fortress/dfhack/default.nix b/pkgs/games/dwarf-fortress/dfhack/default.nix index 12d097c71415..fea74f3de07c 100644 --- a/pkgs/games/dwarf-fortress/dfhack/default.nix +++ b/pkgs/games/dwarf-fortress/dfhack/default.nix @@ -1,20 +1,27 @@ { stdenv -, buildEnv , lib , fetchFromGitHub , fetchpatch , cmake +, ninja , writeScriptBin , perl , XMLLibXML , XMLLibXSLT +, makeWrapper , zlib -, ruby , enableStoneSense ? false , allegro5 , libGLU , libGL , SDL +, SDL2 +, coreutils +, util-linux +, ncurses +, strace +, binutils +, gnused , dfVersion }: @@ -28,48 +35,73 @@ let optional optionals optionalString - platforms versionOlder + versionAtLeast ; dfhack-releases = { "0.44.10" = { dfHackRelease = "0.44.10-r2"; - sha256 = "19bxsghxzw3bilhr8sm4axz7p7z8lrvbdsd1vdjf5zbg04rs866i"; + hash = "sha256-0RikMwFv/eJk26Hptnam6J97flekapQhjWvw3+HTfaU="; xmlRev = "321bd48b10c4c3f694cc801a7dee6be392c09b7b"; - prerelease = false; }; "0.44.11" = { dfHackRelease = "0.44.11-beta2.1"; - sha256 = "1jgwcqg9m1ybv3szgnklp6zfpiw5mswla464dlj2gfi5v82zqbv2"; + hash = "sha256-Yi/8BdoluickbcQQRbmuhcfrvrl02vf12MuHmh5m/Mk="; xmlRev = "f27ebae6aa8fb12c46217adec5a812cd49a905c8"; prerelease = true; }; "0.44.12" = { dfHackRelease = "0.44.12-r1"; - sha256 = "0j03lq6j6w378z6cvm7jspxc7hhrqm8jaszlq0mzfvap0k13fgyy"; + hash = "sha256-3j83wgRXbfcrwPRrJVHFGcLD+tXy1M3MR2dwIw2mA0g="; xmlRev = "23500e4e9bd1885365d0a2ef1746c321c1dd5094"; - prerelease = false; }; "0.47.02" = { dfHackRelease = "0.47.02-alpha0"; - sha256 = "19lgykgqm0si9vd9hx4zw8b5m9188gg8r1a6h25np2m2ziqwbjj9"; + hash = "sha256-ScrFcfyiimuLgEaFjN5DKKRaFuKfdJjaTlGDit/0j6Y="; xmlRev = "23500e4e9bd1885365d0a2ef1746c321c1dd509a"; prerelease = true; }; "0.47.04" = { dfHackRelease = "0.47.04-r5"; - sha256 = "sha256-0s+/LKbqsS/mrxKPDeniqykE5+Gy3ZzCa8yEDzMyssY="; + hash = "sha256-0s+/LKbqsS/mrxKPDeniqykE5+Gy3ZzCa8yEDzMyssY="; xmlRev = "be0444cc165a1abff053d5893dc1f780f06526b7"; - prerelease = false; }; "0.47.05" = { dfHackRelease = "0.47.05-r7"; - sha256 = "sha256-vBKUTSjfCnalkBzfjaIKcxUuqsGGOTtoJC1RHJIDlNc="; + hash = "sha256-vBKUTSjfCnalkBzfjaIKcxUuqsGGOTtoJC1RHJIDlNc="; xmlRev = "f5019a5c6f19ef05a28bd974c3e8668b78e6e2a4"; + }; + "50.10" = { + dfHackRelease = "50.10-r1.1"; + hash = "sha256-k2j8G4kJ/RYE8W0YDOxcsRb5qjjn4El+rigf0v3AqZU="; + xmlRev = "041493b221e0799c106abeac1f86df4535ab80d3"; + needsPatches = true; + }; + "50.11" = { + dfHackRelease = "50.11-r7"; + hash = "sha256-3KsFc0i4XkzoeRvcl5GUlx/fJB1HyqfZm+xL6T4oT/A="; + xmlRev = "cca87907c1cbfcf4af957b0bea3a961a345b1581"; + needsPatches = true; + }; + "50.10" = { + dfHackRelease = "50.10-r1.1"; + hash = "sha256-k2j8G4kJ/RYE8W0YDOxcsRb5qjjn4El+rigf0v3AqZU="; + xmlRev = "041493b221e0799c106abeac1f86df4535ab80d3"; prerelease = false; }; - + "50.11" = { + dfHackRelease = "50.11-r7"; + hash = "sha256-3KsFc0i4XkzoeRvcl5GUlx/fJB1HyqfZm+xL6T4oT/A="; + xmlRev = "cca87907c1cbfcf4af957b0bea3a961a345b1581"; + prerelease = false; + }; + "50.12" = { + dfHackRelease = "50.12-r3rc1"; + hash = "sha256-EcM/FLulGVJgaERFMpYi9O5i1QKZyFb0X4HQagVnO8k="; + xmlRev = "425bb89041565432bb5e9574baadbc15a7c5db0e"; + prerelease = true; + }; }; release = @@ -80,6 +112,8 @@ let else throw "[DFHack] Unsupported Dwarf Fortress version: ${dfVersion}"; version = release.dfHackRelease; + isV50 = versionAtLeast version "50.0"; + needsV50Patches = isV50 && (release.needsPatches or false); # revision of library/xml submodule xmlRev = release.xmlRev; @@ -119,7 +153,7 @@ in owner = "DFHack"; repo = "dfhack"; rev = release.dfHackRelease; - sha256 = release.sha256; + inherit (release) hash; fetchSubmodules = true; }; @@ -133,6 +167,14 @@ in name = "fix-protobuf.patch"; url = "https://github.com/DFHack/dfhack/commit/7bdf958518d2892ee89a7173224a069c4a2190d8.patch"; hash = "sha256-p+mKhmYbnhWKNiGPMjbYO505Gcg634n0nudqH0NX3KY="; + }) ++ optional needsV50Patches (fetchpatch { + name = "use-system-sdl2.patch"; + url = "https://github.com/DFHack/dfhack/commit/734fb730d72e53ebe67f4a041a24dd7c50307ee3.patch"; + hash = "sha256-uLX0gdVSzKEVibyUc1UxcQzdYkRm6D8DF+1eSOxM+qU="; + }) ++ optional needsV50Patches (fetchpatch { + name = "rename-lerp.patch"; + url = "https://github.com/DFHack/dfhack/commit/389dcf5cfcdb8bfb8deeb05fa5756c9f4f5709d1.patch"; + hash = "sha256-QuDtGURhP+nM+x+8GIKO5LrMcmBkl9JSHHIeqzqGIPQ="; }); # gcc 11 fix @@ -150,27 +192,71 @@ in sed -i 's@cached_path = path_string.*@cached_path = getenv("DF_DIR");@' library/Process-linux.cpp ''; - nativeBuildInputs = [ cmake perl XMLLibXML XMLLibXSLT fakegit ]; + nativeBuildInputs = [ cmake ninja perl XMLLibXML XMLLibXSLT makeWrapper fakegit ]; + # We don't use system libraries because dfhack needs old C++ ABI. - buildInputs = [ zlib SDL ] + buildInputs = [ zlib ] + ++ optional isV50 SDL2 + ++ optional (!isV50) SDL ++ optionals enableStoneSense [ allegro5 libGLU libGL ]; preConfigure = '' - # Trick build system into believing we have .git + # Trick the build system into believing we have .git. mkdir -p .git/modules/library/xml touch .git/index .git/modules/library/xml/index ''; - cmakeFlags = [ "-DDFHACK_BUILD_ARCH=${arch}" "-DDOWNLOAD_RUBY=OFF" ] - ++ optionals enableStoneSense [ "-DBUILD_STONESENSE=ON" "-DSTONESENSE_INTERNAL_SO=OFF" ]; + cmakeFlags = [ + # Race condition in `Generating codegen.out.xml and df/headers` that is fixed when using Ninja. + "-GNinja" + "-DDFHACK_BUILD_ARCH=${arch}" - # dfhack expects an unversioned libruby.so to be present in the hack - # subdirectory for ruby plugins to function. - postInstall = '' - ln -s ${ruby}/lib/libruby-*.so $out/hack/libruby.so + # Don't download anything. + "-DDOWNLOAD_RUBY=OFF" + "-DUSE_SYSTEM_SDL2=ON" + + # Ruby support with dfhack is very spotty and was removed in version 50. + "-DBUILD_RUBY=OFF" + ] ++ optionals enableStoneSense [ "-DBUILD_STONESENSE=ON" "-DSTONESENSE_INTERNAL_SO=OFF" ]; + + NIX_CFLAGS_COMPILE = [ "-Wno-error=deprecated-enum-enum-conversion" ] + ++ optionals (versionOlder version "0.47") [ "-fpermissive" ]; + + preFixup = '' + # Wrap dfhack scripts. + if [ -f $out/dfhack ]; then + wrapProgram $out/dfhack \ + --inherit-argv0 \ + --set-default SteamAppId 0 \ + --set-default DFHACK_NO_RENAME_LIBSTDCXX 1 \ + --suffix PATH : ${lib.makeBinPath [ + coreutils util-linux strace gnused binutils ncurses + ]} + fi + + if [ -f $out/dfhack-run ]; then + wrapProgram $out/dfhack-run \ + --inherit-argv0 \ + --suffix PATH : ${lib.makeBinPath [ + coreutils + ]} + fi + + # Create a dfhackrc that changes to the correct home directory. + cat < $out/.dfhackrc + #!/usr/bin/env bash + # nixpkgs dfhackrc helper + if [ -d "\$NIXPKGS_DF_HOME" ]; then + cd "\$NIXPKGS_DF_HOME" + DF_DIR="\$NIXPKGS_DF_HOME" + fi + export DF_DIR + EOF ''; - passthru = { inherit dfVersion; }; + passthru = { + inherit dfVersion; + }; meta = { description = "Memory hacking library for Dwarf Fortress and a set of tools that use it"; diff --git a/pkgs/games/dwarf-fortress/dwarf-therapist/default.nix b/pkgs/games/dwarf-fortress/dwarf-therapist/default.nix index 55de9ffdf45e..e4bfe2d685dc 100644 --- a/pkgs/games/dwarf-fortress/dwarf-therapist/default.nix +++ b/pkgs/games/dwarf-fortress/dwarf-therapist/default.nix @@ -6,22 +6,32 @@ , cmake , texlive , ninja +, isV50 ? true }: stdenv.mkDerivation rec { pname = "dwarf-therapist"; - version = "41.2.2"; + + # 41.2.5 is the last version to support Dwarf Fortress 0.47. + version = if isV50 then "42.1.5" else "41.2.5"; src = fetchFromGitHub { owner = "Dwarf-Therapist"; repo = "Dwarf-Therapist"; rev = "v${version}"; - sha256 = "sha256-zsEG68ioSw64UfmqlTLO1i5sObg8C4zxvdPxdQGMhhU="; + hash = if isV50 then # latest + "sha256-aUakfUjnIZWNDhCkG3A6u7BaaCG8kPMV/Fu2S73CoDg=" + else # 41.2.5 + "sha256-xfYBtnO1n6OcliVt07GsQ9alDJIfWdVhtuyWwuvXSZs="; }; nativeBuildInputs = [ texlive cmake ninja ]; buildInputs = [ qtbase qtdeclarative ]; + enableParallelBuilding = true; + + cmakeFlags = [ "-GNinja" ]; + installPhase = if stdenv.isDarwin then '' mkdir -p $out/Applications @@ -31,8 +41,8 @@ stdenv.mkDerivation rec { dontWrapQtApps = true; meta = with lib; { - description = "Tool to manage dwarves in a running game of Dwarf Fortress"; mainProgram = "dwarftherapist"; + description = "Tool to manage dwarves in a running game of Dwarf Fortress"; maintainers = with maintainers; [ abbradar bendlas numinit jonringer ]; license = licenses.mit; platforms = platforms.x86; diff --git a/pkgs/games/dwarf-fortress/dwarf-therapist/wrapper.nix b/pkgs/games/dwarf-fortress/dwarf-therapist/wrapper.nix index eaf391bbe6b1..503dff90cd45 100644 --- a/pkgs/games/dwarf-fortress/dwarf-therapist/wrapper.nix +++ b/pkgs/games/dwarf-fortress/dwarf-therapist/wrapper.nix @@ -1,10 +1,12 @@ -{ stdenv, dwarf-therapist, dwarf-fortress, substituteAll, coreutils, wrapQtAppsHook }: +{ stdenv, dwarf-therapist, dwarf-fortress, substituteAll, coreutils, wrapQtAppsHook +}: let - platformSlug = - if stdenv.hostPlatform.is32bit then - "linux32" else "linux64"; - inifile = "linux/v0.${dwarf-fortress.baseVersion}.${dwarf-fortress.patchVersion}_${platformSlug}.ini"; + platformSlug = let + prefix = if dwarf-fortress.baseVersion >= 50 then "-classic_" else "_"; + base = if stdenv.hostPlatform.is32bit then "linux32" else "linux64"; + in prefix + base; + inifile = "linux/v0.${builtins.toString dwarf-fortress.baseVersion}.${dwarf-fortress.patchVersion}${platformSlug}.ini"; in @@ -40,8 +42,9 @@ stdenv.mkDerivation { wrapQtApp $out/bin/dwarftherapist # Fix up memory layouts - rm -rf $out/share/dwarftherapist/memory_layouts/linux - mkdir -p $out/share/dwarftherapist/memory_layouts/linux + ini_path="$out/share/dwarftherapist/memory_layouts/${inifile}" + rm -f "$ini_path" + mkdir -p "$(dirname -- "$ini_path")" orig_md5=$(cat "${dwarf-fortress}/hash.md5.orig" | cut -c1-8) patched_md5=$(cat "${dwarf-fortress}/hash.md5" | cut -c1-8) input_file="${dwarf-therapist}/share/dwarftherapist/memory_layouts/${inifile}" @@ -53,7 +56,7 @@ stdenv.mkDerivation { echo " Output: $output_file" echo " Replace: $patched_md5" - substitute "$input_file" "$output_file" --replace "$orig_md5" "$patched_md5" + substitute "$input_file" "$output_file" --replace-fail "$orig_md5" "$patched_md5" ''; preferLocalBuild = true; diff --git a/pkgs/games/dwarf-fortress/game.json b/pkgs/games/dwarf-fortress/game.json index 522cccdcda45..c287a4dd8449 100644 --- a/pkgs/games/dwarf-fortress/game.json +++ b/pkgs/games/dwarf-fortress/game.json @@ -135,5 +135,14 @@ "legacy_s": "1rb7h8lzlsjs08rvhhl3nwbrpj54zijijp4y0qdp4vyzsig6nisk", "legacy32": "0ayw09x9smihh8qp5pdvr6vvhwkvcqz36h3lh4g1b5kzxj7g9cyf", "legacy32_s": "10gfxlysfs9gyi1mv52idp5xk45g9h517g2jq4a8cqp2j7594v9c" + }, + "50.10": { + "linux": "13s5p7205r9ha2j5n7carrwd0y7krq34bcdl08khp0kh2v4470a3" + }, + "50.11": { + "linux": "0iz2d88gzvn0vjxlr99f13j4awhvh2lggjmipdwpbxhfsqih7dx0" + }, + "50.12": { + "linux": "070014fzwszfgjyxjyij0k0hadah6s62lpi91ykp3vs220azya1m" } } diff --git a/pkgs/games/dwarf-fortress/game.nix b/pkgs/games/dwarf-fortress/game.nix index 8d351cdbbd0d..bc79eadbc9fb 100644 --- a/pkgs/games/dwarf-fortress/game.nix +++ b/pkgs/games/dwarf-fortress/game.nix @@ -2,11 +2,15 @@ , lib , fetchurl , SDL +, SDL2 +, SDL2_image +, SDL2_mixer +, fmodex , dwarf-fortress-unfuck +, autoPatchelfHook # Our own "unfuck" libs for macOS , ncurses -, fmodex , gcc , dfVersion @@ -23,12 +27,13 @@ let licenses maintainers makeLibraryPath + optional + optionals optionalString splitVersion + toInt ; - libpath = makeLibraryPath [ stdenv.cc.cc stdenv.cc.libc dwarf-fortress-unfuck SDL ]; - # Map Dwarf Fortress platform names to Nixpkgs platform names. # Other srcs are avilable like 32-bit mac & win, but I have only # included the ones most likely to be needed by Nixpkgs users. @@ -41,9 +46,21 @@ let i686-cygwin = "win32"; }; - dfVersionTriple = splitVersion dfVersion; - baseVersion = elemAt dfVersionTriple 1; - patchVersion = elemAt dfVersionTriple 2; + dfVersionTuple = splitVersion dfVersion; + dfVersionBaseIndex = let + x = (builtins.length dfVersionTuple) - 2; + in if x >= 0 then x else 0; + baseVersion = toInt (elemAt dfVersionTuple dfVersionBaseIndex); + patchVersion = elemAt dfVersionTuple (dfVersionBaseIndex + 1); + + isV50 = baseVersion >= 50; + enableUnfuck = !isV50 && dwarf-fortress-unfuck != null; + + libpath = makeLibraryPath ( + [ stdenv.cc.cc stdenv.cc.libc ] + ++ optional (!isV50) SDL + ++ optional enableUnfuck dwarf-fortress-unfuck + ); game = if hasAttr dfVersion df-hashes @@ -57,7 +74,10 @@ let if hasAttr dfPlatform game then getAttr dfPlatform game else throw "Unsupported dfPlatform: ${dfPlatform}"; - + exe = if stdenv.isLinux then + if baseVersion >= 50 then "dwarfort" else "libs/Dwarf_Fortress" + else + "dwarfort.exe"; in stdenv.mkDerivation { @@ -65,21 +85,44 @@ stdenv.mkDerivation { version = dfVersion; src = fetchurl { - url = "https://www.bay12games.com/dwarves/df_${baseVersion}_${patchVersion}_${dfPlatform}.tar.bz2"; + url = "https://www.bay12games.com/dwarves/df_${toString baseVersion}_${toString patchVersion}_${dfPlatform}.tar.bz2"; inherit sha256; }; + sourceRoot = "."; + + postUnpack = optionalString stdenv.isLinux '' + if [ -d df_linux ]; then + mv df_linux/* . + fi + '' + optionalString stdenv.isDarwin '' + if [ -d df_osx ]; then + mv df_osx/* . + fi + ''; + + nativeBuildInputs = optional isV50 autoPatchelfHook; + buildInputs = optionals isV50 [ SDL2 SDL2_image SDL2_mixer stdenv.cc.cc.lib ]; + installPhase = '' + runHook preInstall + + exe=$out/${exe} mkdir -p $out cp -r * $out - rm $out/libs/lib* - exe=$out/${if stdenv.isLinux then "libs/Dwarf_Fortress" - else "dwarfort.exe"} + # Lots of files are +x in the newer releases... + find $out -type d -exec chmod 0755 {} \; + find $out -type f -exec chmod 0644 {} \; + chmod +x $exe + [ -f $out/df ] && chmod +x $out/df + [ -f $out/run_df ] && chmod +x $out/run_df # Store the original hash md5sum $exe | awk '{ print $1 }' > $out/hash.md5.orig - '' + optionalString stdenv.isLinux '' + echo "Original MD5: $(<$out/hash.md5.orig)" >&2 + '' + optionalString (!isV50 && stdenv.isLinux) '' + rm -f $out/libs/*.so patchelf \ --set-interpreter $(cat ${stdenv.cc}/nix-support/dynamic-linker) \ --set-rpath "${libpath}" \ @@ -101,12 +144,22 @@ stdenv.mkDerivation { @executable_path/libs/libstdc++.6.dylib \ $exe '' + '' - # Store the new hash + ls -al $out + runHook postInstall + ''; + + fixupPhase = '' + runHook preFixup + runHook postFixup + + # Store the new hash as the very last step. + exe=$out/${exe} md5sum $exe | awk '{ print $1 }' > $out/hash.md5 + echo "Patched MD5: $(<$out/hash.md5)" >&2 ''; passthru = { - inherit baseVersion patchVersion dfVersion; + inherit baseVersion patchVersion dfVersion exe; updateScript = ./update.sh; }; diff --git a/pkgs/games/dwarf-fortress/lazy-pack.nix b/pkgs/games/dwarf-fortress/lazy-pack.nix index dcaa8102ae98..d47292484561 100644 --- a/pkgs/games/dwarf-fortress/lazy-pack.nix +++ b/pkgs/games/dwarf-fortress/lazy-pack.nix @@ -41,6 +41,8 @@ let then getAttr dfGame df-games else throw "Unknown Dwarf Fortress version: ${dfVersion}"; dwarf-therapist = dwarf-fortress.dwarf-therapist; + + mainProgram = if enableDFHack then "dfhack" else "dwarf-fortress"; in buildEnv { name = "dwarf-fortress-full"; @@ -54,6 +56,7 @@ buildEnv { ++ optional enableLegendsBrowser legends-browser; meta = { + inherit mainProgram; description = "An opinionated wrapper for Dwarf Fortress"; maintainers = with maintainers; [ Baughn numinit ]; license = licenses.mit; diff --git a/pkgs/games/dwarf-fortress/unfuck.nix b/pkgs/games/dwarf-fortress/unfuck.nix index 3aeee27d87a5..a1baa2d83f75 100644 --- a/pkgs/games/dwarf-fortress/unfuck.nix +++ b/pkgs/games/dwarf-fortress/unfuck.nix @@ -1,6 +1,7 @@ { stdenv , lib , fetchFromGitHub +, fetchpatch , cmake , libGL , libSM @@ -32,43 +33,43 @@ let unfuck-releases = { "0.43.05" = { unfuckRelease = "0.43.05"; - sha256 = "173dyrbxlzqvjf1j3n7vpns4gfjkpyvk9z16430xnmd5m6nda8p2"; + hash = "sha256-4iLVrKmlVdvBICb8NLe/U7pHtL372CGDkxt/2lf2bZw="; }; "0.44.05" = { unfuckRelease = "0.44.05"; - sha256 = "00yj4l4gazxg4i6fj9rwri6vm17i6bviy2mpkx0z5c0mvsr7s14b"; + hash = "sha256-iwR9st4VsPJBn7cKH/cy8YS6Tcw8J+lMJK9/9Qgl0gM="; }; "0.44.09" = { unfuckRelease = "0.44.09"; - sha256 = "138p0v8z2x47f0fk9k6g75ikw5wb3vxldwv5ggbkf4hhvlw6lvzm"; + hash = "sha256-9W9qON0QEjfXe2XzRvseixc+YznPzDQdcId08dEGF40="; }; "0.44.10" = { unfuckRelease = "0.44.10"; - sha256 = "0vb19qx2ibc79j4bgbk9lskb883qfb0815zw1dfz9k7rqwal8mzj"; + hash = "sha256-8ldEFcf5zPRdC/yXgMByeCC0pqZprreITIetKDpOYW0="; }; "0.44.11" = { unfuckRelease = "0.44.11.1"; - sha256 = "1kszkb1d1vll8p04ja41nangsaxb5lv4p3xh2jhmsmipfixw7nvz"; + hash = "sha256-f9vDe3Q3Vl2hFLCPSzYtqyv9rLKBKEnARZTu0MKaX88="; }; "0.44.12" = { unfuckRelease = "0.44.12"; - sha256 = "1kszkb1d1vll8p04ja41nangsaxb5lv4p3xh2jhmsmipfixw7nvz"; + hash = "sha256-f9vDe3Q3Vl2hFLCPSzYtqyv9rLKBKEnARZTu0MKaX88="; }; "0.47.01" = { unfuckRelease = "0.47.01"; - sha256 = "11xvb3qh4crdf59pwfwpi73rzm3ysd1r1xp2k1jp7527jmqapk4k"; + hash = "sha256-k8yrcJVHlHNlmOL2kEPTftSfx4mXO35TcS0zAvFYu4c="; }; "0.47.02" = { unfuckRelease = "0.47.01"; - sha256 = "11xvb3qh4crdf59pwfwpi73rzm3ysd1r1xp2k1jp7527jmqapk4k"; + hash = "sha256-k8yrcJVHlHNlmOL2kEPTftSfx4mXO35TcS0zAvFYu4c="; }; "0.47.04" = { unfuckRelease = "0.47.04"; - sha256 = "1wa990xbsyiiz7abq153xmafvvk1dmgz33rp907d005kzl1z86i9"; + hash = "sha256-KRr0A/2zANAOSDeP8V9tYe7tVO2jBLzU+TF6vTpISfE="; }; "0.47.05" = { - unfuckRelease = "0.47.04"; - sha256 = "1wa990xbsyiiz7abq153xmafvvk1dmgz33rp907d005kzl1z86i9"; + unfuckRelease = "0.47.05-final"; + hash = "sha256-kBdzU6KDpODOBP9XHM7lQRIEWUGOj838vXF1FbSr0Xw="; }; }; @@ -86,9 +87,17 @@ stdenv.mkDerivation { owner = "svenstaro"; repo = "dwarf_fortress_unfuck"; rev = release.unfuckRelease; - sha256 = release.sha256; + inherit (release) hash; }; + patches = lib.optionals (versionOlder release.unfuckRelease "0.47.05") [( + fetchpatch { + name = "fix-noreturn-returning.patch"; + url = "https://github.com/svenstaro/dwarf_fortress_unfuck/commit/6dcfe5ae869fddd51940c6c37a95f7bc639f4389.patch"; + hash = "sha256-b9eI3iR7dmFqCrktPyn6QJ9U2A/7LvfYRS+vE3BOaqk="; + } + )]; + postPatch = '' # https://github.com/svenstaro/dwarf_fortress_unfuck/pull/27 substituteInPlace CMakeLists.txt --replace \''${GLEW_LIBRARIES} GLEW::glew diff --git a/pkgs/games/dwarf-fortress/update.sh b/pkgs/games/dwarf-fortress/update.sh index 5b99dff8aa77..892e031f7883 100755 --- a/pkgs/games/dwarf-fortress/update.sh +++ b/pkgs/games/dwarf-fortress/update.sh @@ -2,9 +2,7 @@ #! nix-shell -i bash -p jq nix coreutils curl # systems to generate hashes for -systems='linux linux32 osx osx32 - win win_s win32 win32_s - legacy legacy_s legacy32 legacy32_s' +systems='linux osx' if [ $# -eq 0 ]; then versions="$(curl http://www.bay12games.com/dwarves/ \ diff --git a/pkgs/games/dwarf-fortress/wrapper/default.nix b/pkgs/games/dwarf-fortress/wrapper/default.nix index a4433821d20d..3a207c548534 100644 --- a/pkgs/games/dwarf-fortress/wrapper/default.nix +++ b/pkgs/games/dwarf-fortress/wrapper/default.nix @@ -2,6 +2,7 @@ , lib , buildEnv , substituteAll +, makeWrapper , runCommand , coreutils , gawk @@ -12,6 +13,9 @@ , enableSoundSense ? false , soundSense , jdk +, expect +, xvfb-run +, writeText , enableStoneSense ? false , enableTWBT ? false , twbt @@ -31,10 +35,14 @@ }: let - dfhack_ = dfhack.override { + dfhack' = dfhack.override { inherit enableStoneSense; }; + isV50 = dwarf-fortress.baseVersion >= 50; + + enableTWBT' = enableTWBT && (twbt != null); + ptheme = if builtins.isString theme then builtins.getAttr theme themes @@ -46,19 +54,19 @@ let # These are in inverse order for first packages to override the next ones. paths = extraPackages ++ lib.optional (theme != null) ptheme - ++ lib.optional enableDFHack dfhack_ + ++ lib.optional enableDFHack dfhack' ++ lib.optional enableSoundSense soundSense - ++ lib.optionals enableTWBT [ twbt.lib twbt.art ] + ++ lib.optionals enableTWBT' [ twbt.lib twbt.art ] ++ [ dwarf-fortress ]; ignoreCollisions = true; }; - settings_ = lib.recursiveUpdate { + settings' = lib.recursiveUpdate { init = { PRINT_MODE = if enableTextMode then "TEXT" - else if enableTWBT then "TWBT" + else if enableTWBT' then "TWBT" else if stdenv.hostPlatform.isDarwin then "STANDARD" # https://www.bay12games.com/dwarves/mantisbt/view.php?id=11680 else null; INTRO = enableIntro; @@ -77,23 +85,31 @@ let else throw "dwarf-fortress: unsupported configuration value ${toString v}"; config = runCommand "dwarf-fortress-config" { - nativeBuildInputs = [ gawk ]; + nativeBuildInputs = [ gawk makeWrapper ]; } ('' mkdir -p $out/data/init edit_setting() { v=''${v//'&'/'\&'} - if ! gawk -i inplace -v RS='\r?\n' ' - { n += sub("\\[" ENVIRON["k"] ":[^]]*\\]", "[" ENVIRON["k"] ":" ENVIRON["v"] "]"); print } - END { exit(!n) } - ' "$out/$file"; then - echo "error: no setting named '$k' in $file" >&2 - exit 1 + if [ -f "$out/$file" ]; then + if ! gawk -i inplace -v RS='\r?\n' ' + { n += sub("\\[" ENVIRON["k"] ":[^]]*\\]", "[" ENVIRON["k"] ":" ENVIRON["v"] "]"); print } + END { exit(!n) } + ' "$out/$file"; then + echo "error: no setting named '$k' in $out/$file" >&2 + exit 1 + fi + else + echo "warning: no file $out/$file; cannot edit" >&2 fi } - '' + forEach settings_ (file: kv: '' + '' + forEach settings' (file: kv: '' file=data/init/${lib.escapeShellArg file}.txt - cp ${baseEnv}/"$file" "$out/$file" + if [ -f "${baseEnv}/$file" ]; then + cp "${baseEnv}/$file" "$out/$file" + else + echo "warning: no file ${baseEnv}/$file; cannot copy" >&2 + fi '' + forEach kv (k: v: lib.optionalString (v != null) '' export k=${lib.escapeShellArg k} v=${lib.escapeShellArg (toTxt v)} edit_setting @@ -103,7 +119,7 @@ let # Patch the MD5 orig_md5=$(< "${dwarf-fortress}/hash.md5.orig") patched_md5=$(< "${dwarf-fortress}/hash.md5") - input_file="${dfhack_}/hack/symbols.xml" + input_file="${dfhack'}/hack/symbols.xml" output_file="$out/hack/symbols.xml" echo "[DFHack Wrapper] Fixing Dwarf Fortress MD5:" @@ -112,7 +128,7 @@ let echo " Output: $output_file" echo " Replace: $patched_md5" - substitute "$input_file" "$output_file" --replace "$orig_md5" "$patched_md5" + substitute "$input_file" "$output_file" --replace-fail "$orig_md5" "$patched_md5" ''); # This is a separate environment because the config files to modify may come @@ -124,11 +140,11 @@ let }; in -lib.throwIf (enableTWBT && !enableDFHack) "dwarf-fortress: TWBT requires DFHack to be enabled" +lib.throwIf (enableTWBT' && !enableDFHack) "dwarf-fortress: TWBT requires DFHack to be enabled" lib.throwIf (enableStoneSense && !enableDFHack) "dwarf-fortress: StoneSense requires DFHack to be enabled" -lib.throwIf (enableTextMode && enableTWBT) "dwarf-fortress: text mode and TWBT are mutually exclusive" +lib.throwIf (enableTextMode && enableTWBT') "dwarf-fortress: text mode and TWBT are mutually exclusive" -stdenv.mkDerivation { +stdenv.mkDerivation rec { pname = "dwarf-fortress"; version = dwarf-fortress.dfVersion; @@ -136,36 +152,40 @@ stdenv.mkDerivation { name = "dwarf-fortress-init"; src = ./dwarf-fortress-init.in; inherit env; - exe = - if stdenv.isLinux then "libs/Dwarf_Fortress" - else "dwarfort.exe"; + inherit (dwarf-fortress) exe; stdenv_shell = "${stdenv.shell}"; cp = "${coreutils}/bin/cp"; rm = "${coreutils}/bin/rm"; ln = "${coreutils}/bin/ln"; cat = "${coreutils}/bin/cat"; mkdir = "${coreutils}/bin/mkdir"; + printf = "${coreutils}/bin/printf"; + uname = "${coreutils}/bin/uname"; }; runDF = ./dwarf-fortress.in; - runDFHack = ./dfhack.in; runSoundSense = ./soundSense.in; passthru = { inherit dwarf-fortress dwarf-therapist twbt env; - dfhack = dfhack_; + dfhack = dfhack'; }; - buildCommand = '' + dontUnpack = true; + dontBuild = true; + preferLocalBuild = true; + installPhase = '' mkdir -p $out/bin substitute $runDF $out/bin/dwarf-fortress \ --subst-var-by stdenv_shell ${stdenv.shell} \ + --subst-var-by dfExe ${dwarf-fortress.exe} \ --subst-var dfInit chmod 755 $out/bin/dwarf-fortress '' + lib.optionalString enableDFHack '' - substitute $runDFHack $out/bin/dfhack \ + substitute $runDF $out/bin/dfhack \ --subst-var-by stdenv_shell ${stdenv.shell} \ + --subst-var-by dfExe dfhack \ --subst-var dfInit chmod 755 $out/bin/dfhack '' + lib.optionalString enableSoundSense '' @@ -176,7 +196,51 @@ stdenv.mkDerivation { chmod 755 $out/bin/soundsense ''; - preferLocalBuild = true; + doInstallCheck = true; + nativeInstallCheckInputs = [ expect xvfb-run ]; + + installCheckPhase = let + commonExpectComponents = fmod: '' + ${lib.optionalString isV50 ''expect "Loading audio..."''} + ${lib.optionalString (!fmod && isV50) ''expect "Failed to load fmod, trying SDL_mixer"''} + ${lib.optionalString isV50 ''expect "Audio loaded successfully!"''} + expect "Loading bindings from data/init/interface.txt" + ''; + dfHackExpectScript = writeText "dfhack-test.exp" '' + spawn xvfb-run $env(out)/bin/dfhack + ${commonExpectComponents false} + expect "DFHack version ${version}" + expect "\[DFHack\]#" + send -- "lua print(os.getenv('out'))\r" + expect "$env(out)" + # Don't send 'die' here; just exit. Some versions of dfhack crash on exit. + exit 0 + ''; + vanillaExpectScript = fmod: writeText "vanilla-test.exp" '' + spawn ${lib.optionalString fmod "env NIXPKGS_DF_OPTS=fmod"} xvfb-run $env(out)/bin/dwarf-fortress + ${commonExpectComponents fmod} + exit 0 + ''; + in + '' + export HOME="$(mktemp -dt dwarf-fortress.XXXXXX)" + '' + lib.optionalString enableDFHack '' + expect ${dfHackExpectScript} + df_home="$(find ~ -name "df_*" | head -n1)" + test -f "$df_home/dfhack" + '' + lib.optionalString isV50 '' + expect ${vanillaExpectScript true} + df_home="$(find ~ -name "df_*" | head -n1)" + test ! -f "$df_home/dfhack" + test -f "$df_home/libfmod_plugin.so" + '' + '' + expect ${vanillaExpectScript false} + df_home="$(find ~ -name "df_*" | head -n1)" + test ! -f "$df_home/dfhack" + test ! -f "$df_home/libfmod_plugin.so" + '' + '' + test -d "$df_home/data" + ''; inherit (dwarf-fortress) meta; } diff --git a/pkgs/games/dwarf-fortress/wrapper/dfhack.in b/pkgs/games/dwarf-fortress/wrapper/dfhack.in deleted file mode 100755 index 0f74674baf29..000000000000 --- a/pkgs/games/dwarf-fortress/wrapper/dfhack.in +++ /dev/null @@ -1,11 +0,0 @@ -#!@stdenv_shell@ -e - -source @dfInit@ - -for i in *.init *.init-example dfhack-config/default dfhack-config/init hack/* stonesense/*; do - if [ -e "$i" ]; then update_path "$i"; fi -done - -cd "$DF_DIR" -LD_LIBRARY_PATH="$env_dir/hack/libs:$env_dir/hack${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH" \ - LD_PRELOAD="$env_dir/hack/libdfhack.so:$LD_PRELOAD" exec $env_dir/libs/Dwarf_Fortress "$@" diff --git a/pkgs/games/dwarf-fortress/wrapper/dwarf-fortress-init.in b/pkgs/games/dwarf-fortress/wrapper/dwarf-fortress-init.in index 27639e57f212..d6fb9267ecfa 100644 --- a/pkgs/games/dwarf-fortress/wrapper/dwarf-fortress-init.in +++ b/pkgs/games/dwarf-fortress/wrapper/dwarf-fortress-init.in @@ -1,45 +1,113 @@ #!@stdenv_shell@ -e shopt -s extglob -[ -z "$DF_DIR" ] && export DF_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/df_linux" env_dir="@env@" -exe="$env_dir/@exe@" + +if [ -n "$DF_DIR" ]; then + # Compatibility for users that were using DF_DIR, since the dfhack script clobbers this variable. + export NIXPKGS_DF_HOME="$DF_DIR" +fi + +if [ -z "$NIXPKGS_DF_HOME" ]; then + export NIXPKGS_DF_HOME="${XDG_DATA_HOME:-$HOME/.local/share}/df_linux" +fi + +# Compatibility. +export DF_DIR="$NIXPKGS_DF_HOME" update_path() { local path="$1" - @mkdir@ -p "$DF_DIR/$(dirname "$path")" + @mkdir@ -p "$NIXPKGS_DF_HOME/$(dirname "$path")" + # If user has replaced these data directories, let them stay. - if [ ! -e "$DF_DIR/$path" ] || [ -L "$DF_DIR/$path" ]; then - @rm@ -f "$DF_DIR/$path" - @ln@ -s "$env_dir/$path" "$DF_DIR/$path" + if [ ! -e "$NIXPKGS_DF_HOME/$path" ] || [ -L "$NIXPKGS_DF_HOME/$path" ]; then + @rm@ -f "$NIXPKGS_DF_HOME/$path" + @ln@ -s "$env_dir/$path" "$NIXPKGS_DF_HOME/$path" + fi +} + +cleanup_path() { + local path="$1" + + # Let them stay if not a link. + if [ ! -e "$NIXPKGS_DF_HOME/$path" ] || [ -L "$NIXPKGS_DF_HOME/$path" ]; then + @rm@ -f "$NIXPKGS_DF_HOME/$path" fi } forcecopy_path() { local path="$1" - @mkdir@ -p "$DF_DIR/$(dirname "$path")" - @rm@ -rf "$DF_DIR/$path" - @cp@ -rL --no-preserve=all "$env_dir/$path" "$DF_DIR/$path" + @mkdir@ -p "$NIXPKGS_DF_HOME/$(dirname "$path")" + @rm@ -rf "$NIXPKGS_DF_HOME/$path" + @cp@ -rL --no-preserve=all "$env_dir/$path" "$NIXPKGS_DF_HOME/$path" } -@mkdir@ -p "$DF_DIR" +declare -A _NIXPKGS_DF_OPTS + +# Don't use fmod by default. +_NIXPKGS_DF_OPTS[fmod]=0 + +IFS=',' read -ra split_options <<< "$NIXPKGS_DF_OPTS" +for option in "${split_options[@]}"; do + key="${option%=*}" + value="${option##*=}" + if [ -z "$value" ] || [ "$key" == "$value" ]; then + value=1 + fi + _NIXPKGS_DF_OPTS["$key"]="$value" +done + +@mkdir@ -p "$NIXPKGS_DF_HOME" @cat@ <&2 -Using $DF_DIR as Dwarf Fortress overlay directory. -If you do any changes in it, don't forget to clean it when updating the game version! -We try to detect changes based on data directories being symbolic links -- keep this in mind. - +/------------------------------------------------------------------------------\\ +| Hello from the nixpkgs Dwarf Fortress wrapper! | +| | +| Using the following Dwarf Fortress overlay directory as NIXPKGS_DF_HOME: | +| $(@printf@ '% -76s' "$NIXPKGS_DF_HOME") | +| | +| If you make any changes in it, don't forget to clean it when updating the | +| game version! We detect changes if data directories are symbolic links. | +| | +| Even though we do our best on our own, this script may miss some. Submit a | +| pull request if there are any that become a problem. | +| | +| We started with the following nixpkgs launch options as NIXPKGS_DF_OPTS: | +| $(@printf@ '% -76s' "$(IFS=',' echo "${_NIXPKGS_DF_OPTS[@]@K}")") | +| | +| If you want to try fmod over SDL_mixer, set NIXPKGS_DF_OPTS=fmod. | +\\------------------------------------------------------------------------------/ EOF cd "$env_dir" -for i in data/init/* data/!(init|index|announcement) raw; do - update_path "$i" + +# All potential important files in DF 50 and below. +for path in dwarfort *.so libs raw data/init/* data/!(init|index|announcement); do + force_delete=0 + if [[ "$path" == libfmod*.so* ]] && [ "${_NIXPKGS_DF_OPTS[fmod]}" -eq 0 ]; then + force_delete=1 + fi + + if [ -e "$path" ] && [ "$force_delete" -eq 0 ]; then + update_path "$path" + else + cleanup_path "$path" + fi done -forcecopy_path data/index -# For some reason, it's needed to be writable... -forcecopy_path data/announcement -forcecopy_path data/help -forcecopy_path data/dipscript +# These need to be copied due to read only flags on older versions of DF. +for path in index announcement help dipscript; do + if [ -e "data/$path" ]; then + forcecopy_path "data/$path" + else + @rm@ -f "$NIXPKGS_DF_HOME/$path" &>/dev/null + fi +done + +# Handle library paths on Darwin. +if [ "$(@uname@)" == Darwin ]; then + export DYLD_LIBRARY_PATH="$env_dir/libs" + export DYLD_FRAMEWORK_PATH="$env_dir/libs" +fi diff --git a/pkgs/games/dwarf-fortress/wrapper/dwarf-fortress.in b/pkgs/games/dwarf-fortress/wrapper/dwarf-fortress.in index 4448bd05fda5..55c259e919b0 100644 --- a/pkgs/games/dwarf-fortress/wrapper/dwarf-fortress.in +++ b/pkgs/games/dwarf-fortress/wrapper/dwarf-fortress.in @@ -2,8 +2,38 @@ source @dfInit@ -export DYLD_LIBRARY_PATH="$env_dir/libs" -export DYLD_FRAMEWORK_PATH="$env_dir/libs" +set -euo pipefail -cd "$DF_DIR" -exec "$exe" "$@" +exe="@dfExe@" + +# If we're switching back from dfhack to vanilla, cleanup all dfhack +# links so Dwarf Fortress doesn't autoload its leftover libdfhooks.so. +# Otherwise, populate them. +dfhack_files=( + dfhack + dfhack-run + .dfhackrc + libdfhooks.so + dfhack-config/default + dfhack-config/init + hack/* + stonesense/* + *.init *.init-example +) + +if [ "${exe##*/}" == dfhack ]; then + for i in "${dfhack_files[@]}"; do + if [ -e "$i" ]; then + update_path "$i" + else + cleanup_path "$i" + fi + done +else + for i in "${dfhack_files[@]}"; do + cleanup_path "$i" + done +fi + +# Go! +cd "$NIXPKGS_DF_HOME" && exec "./$exe" "$@" From 91899502a0d71109da09dbab9aba7107bb6852cf Mon Sep 17 00:00:00 2001 From: Morgan Jones Date: Sat, 6 Apr 2024 23:30:44 -0700 Subject: [PATCH 4/5] dwarf-fortress: address code review feedback --- pkgs/games/dwarf-fortress/default.nix | 19 ++- pkgs/games/dwarf-fortress/dfhack/default.nix | 24 +-- .../dwarf-therapist/default.nix | 11 +- pkgs/games/dwarf-fortress/game.nix | 56 ++++--- pkgs/games/dwarf-fortress/twbt/default.nix | 6 +- pkgs/games/dwarf-fortress/wrapper/default.nix | 35 +++-- .../wrapper/dwarf-fortress-init.in | 138 +++++++++++++----- .../dwarf-fortress/wrapper/dwarf-fortress.in | 10 +- .../dwarf-fortress/wrapper/soundSense.in | 8 +- 9 files changed, 183 insertions(+), 124 deletions(-) diff --git a/pkgs/games/dwarf-fortress/default.nix b/pkgs/games/dwarf-fortress/default.nix index ce2f9f401e6e..ee02364a40a4 100644 --- a/pkgs/games/dwarf-fortress/default.nix +++ b/pkgs/games/dwarf-fortress/default.nix @@ -38,15 +38,17 @@ let getAttr importJSON listToAttrs + optionalAttrs recurseIntoAttrs replaceStrings + versionAtLeast ; callPackage = newScope self; # The latest Dwarf Fortress version. Maintainers: when a new version comes # out, ensure that (unfuck|dfhack|twbt) are all up to date before changing - # this. Note that unfuck and twbt are not required for v50. + # this. Note that unfuck and twbt are not required for 50. latestVersion = "50.12"; # Converts a version to a package name. @@ -58,16 +60,16 @@ let name = versionToName dfVersion; value = let - isV50 = lib.versionAtLeast dfVersion "50.0"; + isAtLeast50 = versionAtLeast dfVersion "50.0"; - dwarf-fortress-unfuck = if isV50 then null else callPackage ./unfuck.nix { inherit dfVersion; }; + dwarf-fortress-unfuck = optionalAttrs (!isAtLeast50) (callPackage ./unfuck.nix { inherit dfVersion; }); dwarf-fortress = callPackage ./game.nix { inherit dfVersion; inherit dwarf-fortress-unfuck; }; - twbt = if isV50 then null else callPackage ./twbt { inherit dfVersion; }; + twbt = optionalAttrs (!isAtLeast50) (callPackage ./twbt { inherit dfVersion; }); dfhack = callPackage ./dfhack { inherit (perlPackages) XMLLibXML XMLLibXSLT; @@ -77,10 +79,13 @@ let dwarf-therapist = libsForQt5.callPackage ./dwarf-therapist/wrapper.nix { inherit dwarf-fortress; - dwarf-therapist = libsForQt5.callPackage ./dwarf-therapist { + dwarf-therapist = (libsForQt5.callPackage ./dwarf-therapist { texlive = texliveBasic.withPackages (ps: with ps; [ float caption wrapfig adjmulticol sidecap preprint enumitem ]); - inherit isV50; - }; + }).override (optionalAttrs (!isAtLeast50) { + # 41.2.5 is the last version to support Dwarf Fortress 0.47. + version = "41.2.5"; + hash = "sha256-xfYBtnO1n6OcliVt07GsQ9alDJIfWdVhtuyWwuvXSZs="; + }); }; in callPackage ./wrapper { diff --git a/pkgs/games/dwarf-fortress/dfhack/default.nix b/pkgs/games/dwarf-fortress/dfhack/default.nix index fea74f3de07c..87e12211d9c7 100644 --- a/pkgs/games/dwarf-fortress/dfhack/default.nix +++ b/pkgs/games/dwarf-fortress/dfhack/default.nix @@ -84,18 +84,6 @@ let xmlRev = "cca87907c1cbfcf4af957b0bea3a961a345b1581"; needsPatches = true; }; - "50.10" = { - dfHackRelease = "50.10-r1.1"; - hash = "sha256-k2j8G4kJ/RYE8W0YDOxcsRb5qjjn4El+rigf0v3AqZU="; - xmlRev = "041493b221e0799c106abeac1f86df4535ab80d3"; - prerelease = false; - }; - "50.11" = { - dfHackRelease = "50.11-r7"; - hash = "sha256-3KsFc0i4XkzoeRvcl5GUlx/fJB1HyqfZm+xL6T4oT/A="; - xmlRev = "cca87907c1cbfcf4af957b0bea3a961a345b1581"; - prerelease = false; - }; "50.12" = { dfHackRelease = "50.12-r3rc1"; hash = "sha256-EcM/FLulGVJgaERFMpYi9O5i1QKZyFb0X4HQagVnO8k="; @@ -112,8 +100,8 @@ let else throw "[DFHack] Unsupported Dwarf Fortress version: ${dfVersion}"; version = release.dfHackRelease; - isV50 = versionAtLeast version "50.0"; - needsV50Patches = isV50 && (release.needsPatches or false); + isAtLeast50 = versionAtLeast version "50.0"; + needs50Patches = isAtLeast50 && (release.needsPatches or false); # revision of library/xml submodule xmlRev = release.xmlRev; @@ -167,11 +155,11 @@ in name = "fix-protobuf.patch"; url = "https://github.com/DFHack/dfhack/commit/7bdf958518d2892ee89a7173224a069c4a2190d8.patch"; hash = "sha256-p+mKhmYbnhWKNiGPMjbYO505Gcg634n0nudqH0NX3KY="; - }) ++ optional needsV50Patches (fetchpatch { + }) ++ optional needs50Patches (fetchpatch { name = "use-system-sdl2.patch"; url = "https://github.com/DFHack/dfhack/commit/734fb730d72e53ebe67f4a041a24dd7c50307ee3.patch"; hash = "sha256-uLX0gdVSzKEVibyUc1UxcQzdYkRm6D8DF+1eSOxM+qU="; - }) ++ optional needsV50Patches (fetchpatch { + }) ++ optional needs50Patches (fetchpatch { name = "rename-lerp.patch"; url = "https://github.com/DFHack/dfhack/commit/389dcf5cfcdb8bfb8deeb05fa5756c9f4f5709d1.patch"; hash = "sha256-QuDtGURhP+nM+x+8GIKO5LrMcmBkl9JSHHIeqzqGIPQ="; @@ -196,8 +184,8 @@ in # We don't use system libraries because dfhack needs old C++ ABI. buildInputs = [ zlib ] - ++ optional isV50 SDL2 - ++ optional (!isV50) SDL + ++ optional isAtLeast50 SDL2 + ++ optional (!isAtLeast50) SDL ++ optionals enableStoneSense [ allegro5 libGLU libGL ]; preConfigure = '' diff --git a/pkgs/games/dwarf-fortress/dwarf-therapist/default.nix b/pkgs/games/dwarf-fortress/dwarf-therapist/default.nix index e4bfe2d685dc..d51c8274bb06 100644 --- a/pkgs/games/dwarf-fortress/dwarf-therapist/default.nix +++ b/pkgs/games/dwarf-fortress/dwarf-therapist/default.nix @@ -6,23 +6,20 @@ , cmake , texlive , ninja -, isV50 ? true +, version ? "42.1.5" +, hash ? "sha256-aUakfUjnIZWNDhCkG3A6u7BaaCG8kPMV/Fu2S73CoDg=" }: stdenv.mkDerivation rec { pname = "dwarf-therapist"; - # 41.2.5 is the last version to support Dwarf Fortress 0.47. - version = if isV50 then "42.1.5" else "41.2.5"; + inherit version; src = fetchFromGitHub { owner = "Dwarf-Therapist"; repo = "Dwarf-Therapist"; rev = "v${version}"; - hash = if isV50 then # latest - "sha256-aUakfUjnIZWNDhCkG3A6u7BaaCG8kPMV/Fu2S73CoDg=" - else # 41.2.5 - "sha256-xfYBtnO1n6OcliVt07GsQ9alDJIfWdVhtuyWwuvXSZs="; + inherit hash; }; nativeBuildInputs = [ texlive cmake ninja ]; diff --git a/pkgs/games/dwarf-fortress/game.nix b/pkgs/games/dwarf-fortress/game.nix index bc79eadbc9fb..9cf7847d1489 100644 --- a/pkgs/games/dwarf-fortress/game.nix +++ b/pkgs/games/dwarf-fortress/game.nix @@ -26,7 +26,6 @@ let hasAttr licenses maintainers - makeLibraryPath optional optionals optionalString @@ -53,14 +52,8 @@ let baseVersion = toInt (elemAt dfVersionTuple dfVersionBaseIndex); patchVersion = elemAt dfVersionTuple (dfVersionBaseIndex + 1); - isV50 = baseVersion >= 50; - enableUnfuck = !isV50 && dwarf-fortress-unfuck != null; - - libpath = makeLibraryPath ( - [ stdenv.cc.cc stdenv.cc.libc ] - ++ optional (!isV50) SDL - ++ optional enableUnfuck dwarf-fortress-unfuck - ); + isAtLeast50 = baseVersion >= 50; + enableUnfuck = !isAtLeast50 && dwarf-fortress-unfuck != null; game = if hasAttr dfVersion df-hashes @@ -92,17 +85,21 @@ stdenv.mkDerivation { sourceRoot = "."; postUnpack = optionalString stdenv.isLinux '' - if [ -d df_linux ]; then - mv df_linux/* . - fi - '' + optionalString stdenv.isDarwin '' - if [ -d df_osx ]; then - mv df_osx/* . + directory=${ + if stdenv.isLinux then "df_linux" + else if stdenv.isDarwin then "df_osx" + else throw "Unsupported system" + } + if [ -d "$directory" ]; then + mv "$directory/"* . fi ''; - nativeBuildInputs = optional isV50 autoPatchelfHook; - buildInputs = optionals isV50 [ SDL2 SDL2_image SDL2_mixer stdenv.cc.cc.lib ]; + nativeBuildInputs = [ autoPatchelfHook ]; + buildInputs = optionals isAtLeast50 [ SDL2 SDL2_image SDL2_mixer ] + ++ optional (!isAtLeast50) SDL + ++ optional enableUnfuck dwarf-fortress-unfuck + ++ [ stdenv.cc.cc.lib ]; installPhase = '' runHook preInstall @@ -118,15 +115,12 @@ stdenv.mkDerivation { [ -f $out/df ] && chmod +x $out/df [ -f $out/run_df ] && chmod +x $out/run_df + # We don't need any of these since they will just break autoPatchelf on $out/hash.md5.orig echo "Original MD5: $(<$out/hash.md5.orig)" >&2 - '' + optionalString (!isV50 && stdenv.isLinux) '' - rm -f $out/libs/*.so - patchelf \ - --set-interpreter $(cat ${stdenv.cc}/nix-support/dynamic-linker) \ - --set-rpath "${libpath}" \ - $exe '' + optionalString stdenv.isDarwin '' # My custom unfucked dwarfort.exe for macOS. Can't use # absolute paths because original doesn't have enough @@ -148,14 +142,16 @@ stdenv.mkDerivation { runHook postInstall ''; - fixupPhase = '' - runHook preFixup - runHook postFixup + preFixup = '' + recompute_hash() { + # Store the new hash as the very last step. + exe=$out/${exe} + md5sum $exe | awk '{ print $1 }' > $out/hash.md5 + echo "Patched MD5: $(<$out/hash.md5)" >&2 + } - # Store the new hash as the very last step. - exe=$out/${exe} - md5sum $exe | awk '{ print $1 }' > $out/hash.md5 - echo "Patched MD5: $(<$out/hash.md5)" >&2 + # Ensure that this runs after autoPatchelfHook. + trap recompute_hash EXIT ''; passthru = { diff --git a/pkgs/games/dwarf-fortress/twbt/default.nix b/pkgs/games/dwarf-fortress/twbt/default.nix index 3c582a67770e..0ccb859b5be3 100644 --- a/pkgs/games/dwarf-fortress/twbt/default.nix +++ b/pkgs/games/dwarf-fortress/twbt/default.nix @@ -81,8 +81,12 @@ stdenvNoCC.mkDerivation rec { cp -a *.png $art/data/art/ ''; + passthru = { + inherit dfVersion; + }; + meta = { - description = "A plugin for Dwarf Fortress / DFHack that improves various aspects the game interface"; + description = "A plugin for Dwarf Fortress / DFHack that improves various aspects of the game interface"; maintainers = with maintainers; [ Baughn numinit ]; license = licenses.mit; platforms = platforms.linux; diff --git a/pkgs/games/dwarf-fortress/wrapper/default.nix b/pkgs/games/dwarf-fortress/wrapper/default.nix index 3a207c548534..2dd771ee922d 100644 --- a/pkgs/games/dwarf-fortress/wrapper/default.nix +++ b/pkgs/games/dwarf-fortress/wrapper/default.nix @@ -39,9 +39,10 @@ let inherit enableStoneSense; }; - isV50 = dwarf-fortress.baseVersion >= 50; + isAtLeast50 = dwarf-fortress.baseVersion >= 50; - enableTWBT' = enableTWBT && (twbt != null); + # If TWBT is null or the dfVersion is wrong, it isn't supported (for example, on version 50). + enableTWBT' = enableTWBT && twbt != null && (twbt.dfVersion or null) == dwarf-fortress.version; ptheme = if builtins.isString theme @@ -200,27 +201,31 @@ stdenv.mkDerivation rec { nativeInstallCheckInputs = [ expect xvfb-run ]; installCheckPhase = let - commonExpectComponents = fmod: '' - ${lib.optionalString isV50 ''expect "Loading audio..."''} - ${lib.optionalString (!fmod && isV50) ''expect "Failed to load fmod, trying SDL_mixer"''} - ${lib.optionalString isV50 ''expect "Audio loaded successfully!"''} + commonExpectStatements = fmod: lib.optionalString isAtLeast50 '' + expect "Loading audio..." + '' + lib.optionalString (!fmod && isAtLeast50) '' + expect "Failed to load fmod, trying SDL_mixer" + '' + lib.optionalString isAtLeast50 '' + expect "Audio loaded successfully!" + '' + '' expect "Loading bindings from data/init/interface.txt" ''; - dfHackExpectScript = writeText "dfhack-test.exp" '' - spawn xvfb-run $env(out)/bin/dfhack - ${commonExpectComponents false} + dfHackExpectScript = writeText "dfhack-test.exp" ('' + spawn env NIXPKGS_DF_OPTS=debug xvfb-run $env(out)/bin/dfhack + '' + commonExpectStatements false + '' + expect "DFHack is ready. Have a nice day!" expect "DFHack version ${version}" expect "\[DFHack\]#" send -- "lua print(os.getenv('out'))\r" expect "$env(out)" # Don't send 'die' here; just exit. Some versions of dfhack crash on exit. exit 0 - ''; - vanillaExpectScript = fmod: writeText "vanilla-test.exp" '' - spawn ${lib.optionalString fmod "env NIXPKGS_DF_OPTS=fmod"} xvfb-run $env(out)/bin/dwarf-fortress - ${commonExpectComponents fmod} + ''); + vanillaExpectScript = fmod: writeText "vanilla-test.exp" ('' + spawn env NIXPKGS_DF_OPTS=debug,${lib.optionalString fmod "fmod"} xvfb-run $env(out)/bin/dwarf-fortress + '' + commonExpectStatements fmod + '' exit 0 - ''; + ''); in '' export HOME="$(mktemp -dt dwarf-fortress.XXXXXX)" @@ -228,7 +233,7 @@ stdenv.mkDerivation rec { expect ${dfHackExpectScript} df_home="$(find ~ -name "df_*" | head -n1)" test -f "$df_home/dfhack" - '' + lib.optionalString isV50 '' + '' + lib.optionalString isAtLeast50 '' expect ${vanillaExpectScript true} df_home="$(find ~ -name "df_*" | head -n1)" test ! -f "$df_home/dfhack" diff --git a/pkgs/games/dwarf-fortress/wrapper/dwarf-fortress-init.in b/pkgs/games/dwarf-fortress/wrapper/dwarf-fortress-init.in index d6fb9267ecfa..61b1b4da6168 100644 --- a/pkgs/games/dwarf-fortress/wrapper/dwarf-fortress-init.in +++ b/pkgs/games/dwarf-fortress/wrapper/dwarf-fortress-init.in @@ -1,63 +1,135 @@ #!@stdenv_shell@ -e +set -euo pipefail shopt -s extglob -env_dir="@env@" +export NIXPKGS_DF_ENV="@env@" -if [ -n "$DF_DIR" ]; then +if [[ -v DF_DIR ]] && [ -n "$DF_DIR" ] && { [[ ! -v NIXPKGS_DF_HOME ]] || [ -z "$NIXPKGS_DF_HOME" ]; }; then # Compatibility for users that were using DF_DIR, since the dfhack script clobbers this variable. export NIXPKGS_DF_HOME="$DF_DIR" fi -if [ -z "$NIXPKGS_DF_HOME" ]; then +if [[ ! -v NIXPKGS_DF_HOME ]] || [ -z "$NIXPKGS_DF_HOME" ]; then export NIXPKGS_DF_HOME="${XDG_DATA_HOME:-$HOME/.local/share}/df_linux" fi # Compatibility. export DF_DIR="$NIXPKGS_DF_HOME" +### BEGIN: Default DF options +declare -A _NIXPKGS_DF_OPTS +_NIXPKGS_DF_OPTS[fmod]=0 # Don't use fmod by default. +_NIXPKGS_DF_OPTS[debug]=0 # No debugging output by default. +### END: Default DF options + +# Read NIXPKGS_DF_OPTS. +if [[ ! -v NIXPKGS_DF_OPTS ]]; then + NIXPKGS_DF_OPTS='' +fi +IFS=',' read -ra options <<< "$NIXPKGS_DF_OPTS" +for option in ${options[@]+"${options[@]}"}; do + key="${option%=*}" + value="${option##*=}" + if [ -n "$key" ]; then + if [ -z "$value" ] || [ "$key" == "$value" ]; then + value=1 + fi + _NIXPKGS_DF_OPTS["$key"]="$value" + fi +done + +# Rebuild the canonical option string from the read options. +NIXPKGS_DF_OPTS='' +for key in "${!_NIXPKGS_DF_OPTS[@]}"; do + value="${_NIXPKGS_DF_OPTS["${key}"]}" + NIXPKGS_DF_OPTS="$NIXPKGS_DF_OPTS$key=$value," +done +NIXPKGS_DF_OPTS="${NIXPKGS_DF_OPTS%,}" + +# Echoes a log. +# $@: log messages +log() { + for msg in "$@"; do + echo "[nixpkgs] $msg" >&2 + done +} + +# Echoes a log if NIXPKGS_DF_OPTS includes debug. +# $@: log messages +debug() { + if [ "${_NIXPKGS_DF_OPTS[debug]}" -ne 0 ]; then + log "$@" + fi +} + +# Updates a path in $NIXPKGS_DF_HOME from $NIXPKGS_DF_ENV. +# $1: The environment path. update_path() { local path="$1" - - @mkdir@ -p "$NIXPKGS_DF_HOME/$(dirname "$path")" + local orig="$NIXPKGS_DF_ENV/$path" + local final="$NIXPKGS_DF_HOME/$path" # If user has replaced these data directories, let them stay. - if [ ! -e "$NIXPKGS_DF_HOME/$path" ] || [ -L "$NIXPKGS_DF_HOME/$path" ]; then - @rm@ -f "$NIXPKGS_DF_HOME/$path" - @ln@ -s "$env_dir/$path" "$NIXPKGS_DF_HOME/$path" + @mkdir@ -p "$(dirname -- "$final")" + if [ ! -e "$final" ] || [ -L "$final" ]; then + debug "Linking: $final -> $orig" + @rm@ -f "$final" + @ln@ -s "$orig" "$final" + else + debug "Not updating: $final" fi } +# Cleans up a path in $NIXPKGS_DF_HOME that may or may not be in $NIXPKGS_DF_ENV. +# $1: The environment path. cleanup_path() { local path="$1" + local final="$NIXPKGS_DF_HOME/$path" # Let them stay if not a link. - if [ ! -e "$NIXPKGS_DF_HOME/$path" ] || [ -L "$NIXPKGS_DF_HOME/$path" ]; then - @rm@ -f "$NIXPKGS_DF_HOME/$path" + if [ ! -e "$final" ] || [ -L "$final" ]; then + debug "Cleaning up: $final" + @rm@ -f "$final" + else + debug "Not cleaning: $final" fi } +# Force copies a path in $NIXPKGS_DF_HOME that may or may not be in $NIXPKGS_DF_ENV. +# $1: The environment path. forcecopy_path() { local path="$1" - @mkdir@ -p "$NIXPKGS_DF_HOME/$(dirname "$path")" - @rm@ -rf "$NIXPKGS_DF_HOME/$path" - @cp@ -rL --no-preserve=all "$env_dir/$path" "$NIXPKGS_DF_HOME/$path" + if [ -z "$NIXPKGS_DF_ENV" ] || [ -z "$path" ]; then + # Avoid producing "/" for any `rm -rf` + return + fi + + local orig="$NIXPKGS_DF_ENV/$path" + local final="$NIXPKGS_DF_HOME/$path" + + if [ -e "$orig" ]; then + debug "Force copying: $orig -> $final" + @mkdir@ -p "$(dirname -- "$final")" + @rm@ -rf "$final" + @cp@ -rL --no-preserve=all "$orig" "$final" + else + debug "Removing: $final" + @rm@ -rf "$final" + fi } -declare -A _NIXPKGS_DF_OPTS +# Runs the final executable. Expects NIXPKGS_DF_HOME and NIXPKGS_DF_EXE to be set. +go() { + cd "$NIXPKGS_DF_HOME" + debug "Executing: $NIXPKGS_DF_HOME/$NIXPKGS_DF_EXE" -# Don't use fmod by default. -_NIXPKGS_DF_OPTS[fmod]=0 - -IFS=',' read -ra split_options <<< "$NIXPKGS_DF_OPTS" -for option in "${split_options[@]}"; do - key="${option%=*}" - value="${option##*=}" - if [ -z "$value" ] || [ "$key" == "$value" ]; then - value=1 - fi - _NIXPKGS_DF_OPTS["$key"]="$value" -done + # If we make it past here, we want to log. + # shellcheck disable=SC2093 + exec -a "$NIXPKGS_DF_EXE" "$NIXPKGS_DF_HOME/$NIXPKGS_DF_EXE" + log "Execution of $NIXPKGS_DF_HOME/$NIXPKGS_DF_EXE failed!" + exit 1 +} @mkdir@ -p "$NIXPKGS_DF_HOME" @@ -75,13 +147,13 @@ done | pull request if there are any that become a problem. | | | | We started with the following nixpkgs launch options as NIXPKGS_DF_OPTS: | -| $(@printf@ '% -76s' "$(IFS=',' echo "${_NIXPKGS_DF_OPTS[@]@K}")") | +| $(@printf@ '% -76s' "$NIXPKGS_DF_OPTS") | | | | If you want to try fmod over SDL_mixer, set NIXPKGS_DF_OPTS=fmod. | \\------------------------------------------------------------------------------/ EOF -cd "$env_dir" +cd "$NIXPKGS_DF_ENV" # All potential important files in DF 50 and below. for path in dwarfort *.so libs raw data/init/* data/!(init|index|announcement); do @@ -99,15 +171,11 @@ done # These need to be copied due to read only flags on older versions of DF. for path in index announcement help dipscript; do - if [ -e "data/$path" ]; then - forcecopy_path "data/$path" - else - @rm@ -f "$NIXPKGS_DF_HOME/$path" &>/dev/null - fi + forcecopy_path "data/$path" done # Handle library paths on Darwin. if [ "$(@uname@)" == Darwin ]; then - export DYLD_LIBRARY_PATH="$env_dir/libs" - export DYLD_FRAMEWORK_PATH="$env_dir/libs" + export DYLD_LIBRARY_PATH="$NIXPKGS_DF_ENV/libs" + export DYLD_FRAMEWORK_PATH="$NIXPKGS_DF_ENV/libs" fi diff --git a/pkgs/games/dwarf-fortress/wrapper/dwarf-fortress.in b/pkgs/games/dwarf-fortress/wrapper/dwarf-fortress.in index 55c259e919b0..29db9c128f4c 100644 --- a/pkgs/games/dwarf-fortress/wrapper/dwarf-fortress.in +++ b/pkgs/games/dwarf-fortress/wrapper/dwarf-fortress.in @@ -1,11 +1,8 @@ #!@stdenv_shell@ -e +export NIXPKGS_DF_EXE="@dfExe@" source @dfInit@ -set -euo pipefail - -exe="@dfExe@" - # If we're switching back from dfhack to vanilla, cleanup all dfhack # links so Dwarf Fortress doesn't autoload its leftover libdfhooks.so. # Otherwise, populate them. @@ -21,7 +18,7 @@ dfhack_files=( *.init *.init-example ) -if [ "${exe##*/}" == dfhack ]; then +if [ "${NIXPKGS_DF_EXE##*/}" == dfhack ]; then for i in "${dfhack_files[@]}"; do if [ -e "$i" ]; then update_path "$i" @@ -35,5 +32,4 @@ else done fi -# Go! -cd "$NIXPKGS_DF_HOME" && exec "./$exe" "$@" +go diff --git a/pkgs/games/dwarf-fortress/wrapper/soundSense.in b/pkgs/games/dwarf-fortress/wrapper/soundSense.in index 28357ed7579f..16818156934a 100644 --- a/pkgs/games/dwarf-fortress/wrapper/soundSense.in +++ b/pkgs/games/dwarf-fortress/wrapper/soundSense.in @@ -1,10 +1,10 @@ #!@stdenv_shell@ -e +export NIXPKGS_DF_EXE="soundsense/soundSense.sh" source @dfInit@ -for p in soundsense/*; do - update_path "$p" +for path in soundsense/*; do + update_path "$path" done -cd "$DF_DIR" -PATH=@jre@/bin exec $DF_DIR/soundsense/soundSense.sh +PATH="@jre@/bin:$PATH" go From e683c1658d06c145b342fb6e503f3d60f61069b4 Mon Sep 17 00:00:00 2001 From: Morgan Jones Date: Thu, 11 Apr 2024 20:09:06 -0700 Subject: [PATCH 5/5] dwarf-fortress: dfhack: update to 50.12-r3 --- pkgs/games/dwarf-fortress/dfhack/default.nix | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/pkgs/games/dwarf-fortress/dfhack/default.nix b/pkgs/games/dwarf-fortress/dfhack/default.nix index 87e12211d9c7..156dac32c472 100644 --- a/pkgs/games/dwarf-fortress/dfhack/default.nix +++ b/pkgs/games/dwarf-fortress/dfhack/default.nix @@ -85,10 +85,9 @@ let needsPatches = true; }; "50.12" = { - dfHackRelease = "50.12-r3rc1"; - hash = "sha256-EcM/FLulGVJgaERFMpYi9O5i1QKZyFb0X4HQagVnO8k="; - xmlRev = "425bb89041565432bb5e9574baadbc15a7c5db0e"; - prerelease = true; + dfHackRelease = "50.12-r3"; + hash = "sha256-2mO8DpNmZRCV7IRY0arf3SMvlO4Pxs61Kxfh3q3k3HU="; + xmlRev = "980b1af13acc31660dce632f913c968f52e2b275"; }; };