diff options
author | Sandro <sandro.jaeckel@gmail.com> | 2024-04-17 10:30:32 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-17 10:30:32 +0200 |
commit | f703aa17e08fdc42558e996be35f67d9b58d36a7 (patch) | |
tree | d024e13f33e911417ebac7e7209155afced6bdd8 /pkgs | |
parent | f1d26bc49b5d01ccf6e0904f27e25c1ea7a9a20b (diff) | |
parent | e683c1658d06c145b342fb6e503f3d60f61069b4 (diff) |
Merge pull request #300402 from numinit/df50
dwarf-fortress: update to 50
Diffstat (limited to 'pkgs')
17 files changed, 589 insertions, 153 deletions
diff --git a/pkgs/games/dwarf-fortress/default.nix b/pkgs/games/dwarf-fortress/default.nix index 777866d8fb0e5..ee02364a40a4a 100644 --- a/pkgs/games/dwarf-fortress/default.nix +++ b/pkgs/games/dwarf-fortress/default.nix @@ -38,39 +38,38 @@ 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. - latestVersion = "0.47.05"; + # this. Note that unfuck and twbt are not required for 50. + 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... + isAtLeast50 = versionAtLeast dfVersion "50.0"; + + dwarf-fortress-unfuck = optionalAttrs (!isAtLeast50) (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 = optionalAttrs (!isAtLeast50) (callPackage ./twbt { inherit dfVersion; }); dfhack = callPackage ./dfhack { inherit (perlPackages) XMLLibXML XMLLibXSLT; @@ -80,7 +79,13 @@ 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 ]); + }).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 { @@ -97,7 +102,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/df_permission b/pkgs/games/dwarf-fortress/df_permission/2010 index dc1c0c151e0b2..dc1c0c151e0b2 100644 --- a/pkgs/games/dwarf-fortress/df_permission +++ b/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 0000000000000..cdea6958fabd0 --- /dev/null +++ b/pkgs/games/dwarf-fortress/df_permission/2024 @@ -0,0 +1,57 @@ +From: Tarn Adams <tarn.adams@gmail.com> +Date: Thu, 4 Apr 2024 20:18:35 -0700 +Subject: Re: Dwarf Fortress v50 Redistribution for NixOS +To: Morgan <me@numin.it> + +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 <me@numin.it> wrote: + +> Tarn, +> +> I maintain the Dwarf Fortress package for NixOS (<https://nixos.org>), +> 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 +> diff --git a/pkgs/games/dwarf-fortress/dfhack/default.nix b/pkgs/games/dwarf-fortress/dfhack/default.nix index 12d097c714155..156dac32c472b 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,60 @@ 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"; - prerelease = false; }; - + "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.12" = { + dfHackRelease = "50.12-r3"; + hash = "sha256-2mO8DpNmZRCV7IRY0arf3SMvlO4Pxs61Kxfh3q3k3HU="; + xmlRev = "980b1af13acc31660dce632f913c968f52e2b275"; + }; }; release = @@ -80,6 +99,8 @@ let else throw "[DFHack] Unsupported Dwarf Fortress version: ${dfVersion}"; version = release.dfHackRelease; + isAtLeast50 = versionAtLeast version "50.0"; + needs50Patches = isAtLeast50 && (release.needsPatches or false); # revision of library/xml submodule xmlRev = release.xmlRev; @@ -119,7 +140,7 @@ in owner = "DFHack"; repo = "dfhack"; rev = release.dfHackRelease; - sha256 = release.sha256; + inherit (release) hash; fetchSubmodules = true; }; @@ -133,6 +154,14 @@ in name = "fix-protobuf.patch"; url = "https://github.com/DFHack/dfhack/commit/7bdf958518d2892ee89a7173224a069c4a2190d8.patch"; hash = "sha256-p+mKhmYbnhWKNiGPMjbYO505Gcg634n0nudqH0NX3KY="; + }) ++ optional needs50Patches (fetchpatch { + name = "use-system-sdl2.patch"; + url = "https://github.com/DFHack/dfhack/commit/734fb730d72e53ebe67f4a041a24dd7c50307ee3.patch"; + hash = "sha256-uLX0gdVSzKEVibyUc1UxcQzdYkRm6D8DF+1eSOxM+qU="; + }) ++ optional needs50Patches (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 +179,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 isAtLeast50 SDL2 + ++ optional (!isAtLeast50) 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}" + + # 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 - # 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 + # Create a dfhackrc that changes to the correct home directory. + cat <<EOF > $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 55de9ffdf45e4..d51c8274bb066 100644 --- a/pkgs/games/dwarf-fortress/dwarf-therapist/default.nix +++ b/pkgs/games/dwarf-fortress/dwarf-therapist/default.nix @@ -6,22 +6,29 @@ , cmake , texlive , ninja +, version ? "42.1.5" +, hash ? "sha256-aUakfUjnIZWNDhCkG3A6u7BaaCG8kPMV/Fu2S73CoDg=" }: stdenv.mkDerivation rec { pname = "dwarf-therapist"; - version = "41.2.2"; + + inherit version; src = fetchFromGitHub { owner = "Dwarf-Therapist"; repo = "Dwarf-Therapist"; rev = "v${version}"; - sha256 = "sha256-zsEG68ioSw64UfmqlTLO1i5sObg8C4zxvdPxdQGMhhU="; + inherit hash; }; nativeBuildInputs = [ texlive cmake ninja ]; buildInputs = [ qtbase qtdeclarative ]; + enableParallelBuilding = true; + + cmakeFlags = [ "-GNinja" ]; + installPhase = if stdenv.isDarwin then '' mkdir -p $out/Applications @@ -31,8 +38,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 eaf391bbe6b18..503dff90cd45a 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 522cccdcda45b..c287a4dd84490 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 8d351cdbbd0d1..9cf7847d14893 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 @@ -22,13 +26,13 @@ let hasAttr 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 +45,15 @@ 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); + + isAtLeast50 = baseVersion >= 50; + enableUnfuck = !isAtLeast50 && dwarf-fortress-unfuck != null; game = if hasAttr dfVersion df-hashes @@ -57,7 +67,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,25 +78,49 @@ 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 '' + 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 = [ autoPatchelfHook ]; + buildInputs = optionals isAtLeast50 [ SDL2 SDL2_image SDL2_mixer ] + ++ optional (!isAtLeast50) SDL + ++ optional enableUnfuck dwarf-fortress-unfuck + ++ [ 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 + + # We don't need any of these since they will just break autoPatchelf on <version 50. + [ -d $out/libs ] && rm -f $out/libs/*.so $out/libs/*.so.* # Store the original hash md5sum $exe | awk '{ print $1 }' > $out/hash.md5.orig - '' + optionalString stdenv.isLinux '' - patchelf \ - --set-interpreter $(cat ${stdenv.cc}/nix-support/dynamic-linker) \ - --set-rpath "${libpath}" \ - $exe + echo "Original MD5: $(<$out/hash.md5.orig)" >&2 '' + optionalString stdenv.isDarwin '' # My custom unfucked dwarfort.exe for macOS. Can't use # absolute paths because original doesn't have enough @@ -101,12 +138,24 @@ stdenv.mkDerivation { @executable_path/libs/libstdc++.6.dylib \ $exe '' + '' - # Store the new hash - md5sum $exe | awk '{ print $1 }' > $out/hash.md5 + ls -al $out + runHook postInstall + ''; + + 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 + } + + # Ensure that this runs after autoPatchelfHook. + trap recompute_hash EXIT ''; 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 dcaa8102ae989..d472924845618 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/twbt/default.nix b/pkgs/games/dwarf-fortress/twbt/default.nix index 3c582a67770eb..0ccb859b5be32 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/unfuck.nix b/pkgs/games/dwarf-fortress/unfuck.nix index 3aeee27d87a50..a1baa2d83f757 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 5b99dff8aa77a..892e031f7883e 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 a4433821d20de..2dd771ee922db 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,15 @@ }: let - dfhack_ = dfhack.override { + dfhack' = dfhack.override { inherit enableStoneSense; }; + isAtLeast50 = dwarf-fortress.baseVersion >= 50; + + # 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 then builtins.getAttr theme themes @@ -46,19 +55,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 +86,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 +120,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 +129,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 +141,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 +153,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 +197,55 @@ stdenv.mkDerivation { chmod 755 $out/bin/soundsense ''; - preferLocalBuild = true; + doInstallCheck = true; + nativeInstallCheckInputs = [ expect xvfb-run ]; + + installCheckPhase = let + 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 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 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)" + '' + lib.optionalString enableDFHack '' + expect ${dfHackExpectScript} + df_home="$(find ~ -name "df_*" | head -n1)" + test -f "$df_home/dfhack" + '' + lib.optionalString isAtLeast50 '' + 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 0f74674baf299..0000000000000 --- 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 27639e57f212e..61b1b4da61682 100644 --- a/pkgs/games/dwarf-fortress/wrapper/dwarf-fortress-init.in +++ b/pkgs/games/dwarf-fortress/wrapper/dwarf-fortress-init.in @@ -1,45 +1,181 @@ #!@stdenv_shell@ -e +set -euo pipefail shopt -s extglob -[ -z "$DF_DIR" ] && export DF_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/df_linux" -env_dir="@env@" -exe="$env_dir/@exe@" +export NIXPKGS_DF_ENV="@env@" +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 [[ ! -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" + local orig="$NIXPKGS_DF_ENV/$path" + local final="$NIXPKGS_DF_HOME/$path" - @mkdir@ -p "$DF_DIR/$(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" + @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 "$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 "$DF_DIR/$(dirname "$path")" - @rm@ -rf "$DF_DIR/$path" - @cp@ -rL --no-preserve=all "$env_dir/$path" "$DF_DIR/$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 } -@mkdir@ -p "$DF_DIR" +# 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" -@cat@ <<EOF >&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. + # 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" + +@cat@ <<EOF >&2 +/------------------------------------------------------------------------------\\ +| 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' "$NIXPKGS_DF_OPTS") | +| | +| 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" +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 + 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 + +# These need to be copied due to read only flags on older versions of DF. +for path in index announcement help dipscript; do + forcecopy_path "data/$path" 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 +# Handle library paths on Darwin. +if [ "$(@uname@)" == Darwin ]; then + 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 4448bd05fda57..29db9c128f4c0 100644 --- a/pkgs/games/dwarf-fortress/wrapper/dwarf-fortress.in +++ b/pkgs/games/dwarf-fortress/wrapper/dwarf-fortress.in @@ -1,9 +1,35 @@ #!@stdenv_shell@ -e +export NIXPKGS_DF_EXE="@dfExe@" source @dfInit@ -export DYLD_LIBRARY_PATH="$env_dir/libs" -export DYLD_FRAMEWORK_PATH="$env_dir/libs" +# 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 +) -cd "$DF_DIR" -exec "$exe" "$@" +if [ "${NIXPKGS_DF_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 diff --git a/pkgs/games/dwarf-fortress/wrapper/soundSense.in b/pkgs/games/dwarf-fortress/wrapper/soundSense.in index 28357ed7579fe..16818156934ac 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 |