From a3ec50791f8023c84a69336f59909ebc5ea1b720 Mon Sep 17 00:00:00 2001 From: Adam Russell Date: Sat, 26 Sep 2015 18:13:06 -0500 Subject: [PATCH] dwarf-fortress: add dfhack --- pkgs/games/dwarf-fortress/default.nix | 203 ++++++++++++++---- pkgs/games/dwarf-fortress/dfhack-run.in | 11 + .../dwarf-fortress/dwarf-fortress-hacked.in | 13 ++ pkgs/games/dwarf-fortress/dwarf-fortress.in | 14 ++ pkgs/games/dwarf-fortress/export-libs.sh.in | 12 ++ .../games/dwarf-fortress/export-workaround.sh | 1 + .../install-df-data-content-to-home.sh | 4 + .../dwarf-fortress/install-df-data-to-home.sh | 12 ++ .../install-dfhack-data-to-home.sh | 16 ++ pkgs/top-level/all-packages.nix | 2 + 10 files changed, 242 insertions(+), 46 deletions(-) create mode 100644 pkgs/games/dwarf-fortress/dfhack-run.in create mode 100644 pkgs/games/dwarf-fortress/dwarf-fortress-hacked.in create mode 100644 pkgs/games/dwarf-fortress/dwarf-fortress.in create mode 100644 pkgs/games/dwarf-fortress/export-libs.sh.in create mode 100644 pkgs/games/dwarf-fortress/export-workaround.sh create mode 100644 pkgs/games/dwarf-fortress/install-df-data-content-to-home.sh create mode 100644 pkgs/games/dwarf-fortress/install-df-data-to-home.sh create mode 100644 pkgs/games/dwarf-fortress/install-dfhack-data-to-home.sh diff --git a/pkgs/games/dwarf-fortress/default.nix b/pkgs/games/dwarf-fortress/default.nix index 4e34453a1e8a..ad2733df079d 100644 --- a/pkgs/games/dwarf-fortress/default.nix +++ b/pkgs/games/dwarf-fortress/default.nix @@ -1,6 +1,14 @@ { stdenv, fetchgit, fetchurl, cmake, glew, ncurses , SDL, SDL_image, SDL_ttf, gtk2, glib -, mesa, openal, pango, atk, gdk_pixbuf, glibc, libsndfile }: +, mesa, openal, pango, atk, gdk_pixbuf, glibc, libsndfile +# begin dfhack-only parameters +, XMLLibXML +, XMLLibXSLT +, perl +, zlib +# end dfhack-only parameters +, enableDFHack ? false +}: let baseVersion = "40"; @@ -12,12 +20,21 @@ let sha256 = "19vwx6kpv1sf93bx5v8x47f7x2cgxsqk82v6j1a72sa3q7m5cpc7"; }; + dfhack = fetchgit { + url = "https://github.com/DFHack/dfhack.git"; + rev = "0849099f2083e100cae6f64940b4eff4c28ce2eb"; + sha256 = "0lnqrayi8hwfivkrxb7fw8lb6v95i04pskny1px7084n7nzvyv8b"; + }; + df = fetchurl { url = "http://www.bay12games.com/dwarves/df_${baseVersion}_${patchVersion}_linux.tar.bz2"; sha256 = "0d4jrs45qj89vq9mjg7fxxhis7zivvb0vzjpmkk274b778kccdys"; }; }; + dfHackWorksWithCurrentVersion = true; + dfHackEnabled = dfHackWorksWithCurrentVersion && enableDFHack; + in assert stdenv.system == "i686-linux"; @@ -27,11 +44,31 @@ stdenv.mkDerivation rec { inherit baseVersion patchVersion; - buildInputs = [ SDL SDL_image SDL_ttf gtk2 glib glew mesa ncurses openal glibc libsndfile pango atk cmake gdk_pixbuf]; - src = "${srcs.df_unfuck} ${srcs.df}"; - phases = "unpackPhase patchPhase configurePhase buildPhase installPhase"; + buildInputs = [ + SDL + SDL_image + SDL_ttf + gtk2 + glib + glew + mesa + ncurses + openal + glibc + libsndfile + pango + atk + cmake + gdk_pixbuf + XMLLibXML + XMLLibXSLT + perl + zlib + ]; + src = "${srcs.df_unfuck} ${srcs.df}" + stdenv.lib.optionalString dfHackEnabled " ${srcs.dfhack}"; sourceRoot = srcs.df_unfuck.name; + dfHackSourceRoot = srcs.dfhack.name; cmakeFlags = [ "-DGTK2_GLIBCONFIG_INCLUDE_DIR=${glib}/lib/glib-2.0/include" @@ -39,68 +76,142 @@ stdenv.mkDerivation rec { ]; permission = ./df_permission; + dfHackTemplate = ./dwarf-fortress-hacked.in; + dfHackRunTemplate = ./dfhack-run.in; + dwarfFortressTemplate = ./dwarf-fortress.in; + installDfDataToHome = ./install-df-data-to-home.sh; + installDfhackDataToHome = ./install-dfhack-data-to-home.sh; + installDfDataContentToHome = ./install-df-data-content-to-home.sh; + exportLibsTemplate = ./export-libs.sh.in; + exportWorkaround = ./export-workaround.sh; + + postUnpack = stdenv.lib.optionalString dfHackEnabled '' + if [ "$dontMakeSourcesWritable" != 1 ]; then + chmod -R u+w "$dfHackSourceRoot" + fi + ''; + + preConfigure = stdenv.lib.optionalString dfHackEnabled '' + export cmakeFlags="-DCMAKE_INSTALL_PREFIX=$out/share/df_linux $cmakeFlags" + export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$(pwd)/build/depends/protobuf + ''; + + postConfigure = stdenv.lib.optionalString dfHackEnabled '' + if [ -z "$originalSourceRoot" ]; then + + originalSourceRoot=$sourceRoot + export sourceRoot=$dfHackSourceRoot + + pushd ../../$sourceRoot + + eval "''${configurePhase:-configurePhase}" + + popd + + export sourceRoot=$originalSourceRoot + unset originalSourceRoot + fi + ''; installPhase = '' set -x mkdir -p $out/bin mkdir -p $out/share/df_linux - cd ../../ + pushd ../../ cp -r ./df_linux/* $out/share/df_linux rm $out/share/df_linux/libs/lib* - # Store the original hash for dwarf-therapist - echo $(md5sum $out/share/df_linux/libs/Dwarf_Fortress | cut -c1-8) > $out/share/df_linux/hash.md5.orig - # Fix rpath - patchelf --set-rpath "${stdenv.lib.makeLibraryPath [ stdenv.cc.cc stdenv.glibc ]}:$out/share/df_linux/libs" $out/share/df_linux/libs/Dwarf_Fortress + # Store the original hash + orig_hash=$(md5sum $out/share/df_linux/libs/Dwarf_Fortress | awk '{ print $1 }') + echo $orig_hash | cut -c1-8 > $out/share/df_linux/hash.md5.orig # for dwarf-therapist + echo $orig_hash > $out/share/df_linux/full-hash-orig.md5 # for dfhack + cp -f ./${srcs.df_unfuck.name}/build/libgraphics.so $out/share/df_linux/libs/libgraphics.so cp $permission $out/share/df_linux/nix_permission + # Placeholder files for hashes of patched binary + touch $out/share/df_linux/hash.md5.patched + touch $out/share/df_linux/full-hash-patched.md5 + + mkdir -p $out/share/df_linux/shell + cp $installDfDataToHome $out/share/df_linux/shell/install-df-data-to-home.sh + cp $installDfhackDataToHome $out/share/df_linux/shell/install-dfhack-data-to-home.sh + cp $installDfDataContentToHome $out/share/df_linux/shell/install-df-data-content-to-home.sh + cp $exportWorkaround $out/share/df_linux/shell/export-workaround.sh + substitute $exportLibsTemplate $out/share/df_linux/shell/export-libs.sh \ + --subst-var-by stdenv_cc ${stdenv.cc} \ + --subst-var-by SDL ${SDL} \ + --subst-var-by SDL_image ${SDL_image} \ + --subst-var-by SDL_ttf ${SDL_ttf} \ + --subst-var-by gtk2 ${gtk2} \ + --subst-var-by glib ${glib} \ + --subst-var-by libsndfile ${libsndfile} \ + --subst-var-by mesa ${mesa} \ + --subst-var-by openal ${openal} \ + --subst-var-by zlib ${zlib} \ + + substitute $dwarfFortressTemplate $out/bin/dwarf-fortress \ + --subst-var-by stdenv_shell ${stdenv.shell} \ + --subst-var prefix + + chmod 755 $out/bin/dwarf-fortress + + popd + '' + stdenv.lib.optionalString dfHackEnabled '' + + originalSourceRoot=$sourceRoot + export sourceRoot=$dfHackSourceRoot + + pushd ../../$sourceRoot/build + + mkdir -p $out/dfhack + + make install + + cp ../package/linux/dfhack $out/dfhack/ + + mkdir -p $out/bin + + substitute $dfHackTemplate $out/bin/dfhack \ + --subst-var-by stdenv_shell ${stdenv.shell} \ + --subst-var prefix + chmod 755 $out/bin/dfhack + + substitute $dfHackRunTemplate $out/bin/dfhack-run \ + --subst-var-by stdenv_shell ${stdenv.shell} \ + --subst-var prefix + chmod 755 $out/bin/dfhack-run + + popd + + export sourceRoot=$originalSourceRoot + unset originalSourceRoot + ''; + + fixupPhase = '' + # Fix rpath + patchelf --set-rpath "${stdenv.lib.makeLibraryPath [ stdenv.cc.cc stdenv.glibc ]}:$out/share/df_linux/libs" $out/share/df_linux/libs/Dwarf_Fortress + patchelf --set-interpreter ${glibc}/lib/ld-linux.so.2 $out/share/df_linux/libs/Dwarf_Fortress - # Store new hash for dwarf-therapist - echo $(md5sum $out/share/df_linux/libs/Dwarf_Fortress | cut -c1-8) > $out/share/df_linux/hash.md5.patched + # Store new hash + patched_hash=$(md5sum $out/share/df_linux/libs/Dwarf_Fortress | awk '{ print $1 }') + echo $patched_hash | cut -c1-8 > $out/share/df_linux/hash.md5.patched # for dwarf-therapist + echo $patched_hash > $out/share/df_linux/full-hash-patched.md5 # for dfhack + '' + stdenv.lib.optionalString dfHackEnabled '' + find $out/share/df_linux/hack \( \ + \( -type f -a -name "*.so*" \) -o \ + \( -type f -a -perm +0100 \) \ + \) -print -exec patchelf --shrink-rpath {} \; - cat > $out/bin/dwarf-fortress << EOF - #!${stdenv.shell} - - set -ex - - export DF_DIR="\$HOME/.config/df_linux" - if [ -n "\$XDG_DATA_HOME" ] - then export DF_DIR="\$XDG_DATA_HOME/df_linux" - fi - - if [[ ! -d "\$DF_DIR" ]]; then - mkdir -p "\$DF_DIR" - ln -s $out/share/df_linux/raw "\$DF_DIR/raw" - ln -s $out/share/df_linux/libs "\$DF_DIR/libs" - mkdir -p "\$DF_DIR/data/init" - cp -rn $out/share/df_linux/data/init "\$DF_DIR/data/" - fi - - for link in announcement art dipscript help index initial_movies movies shader.fs shader.vs sound speech; do - cp -r $out/share/df_linux/data/\$link "\$DF_DIR/data/\$link" - chmod -R u+rw "\$DF_DIR/data/\$link" - done - - # now run Dwarf Fortress! - export LD_LIBRARY_PATH=\${stdenv.cc}/lib:${SDL}/lib:${SDL_image}/lib/:${SDL_ttf}/lib/:${gtk2}/lib/:${glib}/lib/:${mesa}/lib/:${openal}/lib/:${libsndfile}/lib:\$DF_DIR/df_linux/libs/ - - export SDL_DISABLE_LOCK_KEYS=1 # Work around for bug in Debian/Ubuntu SDL patch. - #export SDL_VIDEO_CENTERED=1 # Centre the screen. Messes up resizing. - - cd \$DF_DIR - $out/share/df_linux/libs/Dwarf_Fortress "$@" - EOF - - chmod +x $out/bin/dwarf-fortress + sed -i "s/$(cat $out/share/df_linux/full-hash-orig.md5)/$(cat $out/share/df_linux/full-hash-patched.md5)/" $out/share/df_linux/hack/symbols.xml ''; meta = { description = "A single-player fantasy game with a randomly generated adventure world"; homepage = http://www.bay12games.com/dwarves; license = stdenv.lib.licenses.unfreeRedistributable; - maintainers = with stdenv.lib.maintainers; [ roconnor the-kenny ]; + maintainers = with stdenv.lib.maintainers; [ a1russell robbinch roconnor the-kenny ]; }; } diff --git a/pkgs/games/dwarf-fortress/dfhack-run.in b/pkgs/games/dwarf-fortress/dfhack-run.in new file mode 100644 index 000000000000..590e5b25acf3 --- /dev/null +++ b/pkgs/games/dwarf-fortress/dfhack-run.in @@ -0,0 +1,11 @@ +#!@stdenv_shell@ + +data_dir=${XDG_DATA_HOME:-$HOME/.local/share}/df_linux +pkg_dir=@prefix@/share/df_linux + +. $pkg_dir/shell/install-df-data-to-home.sh +. $pkg_dir/shell/install-dfhack-data-to-home.sh +. $pkg_dir/shell/export-libs.sh + +cd "$data_dir" +exec ./dfhack-run "$@" diff --git a/pkgs/games/dwarf-fortress/dwarf-fortress-hacked.in b/pkgs/games/dwarf-fortress/dwarf-fortress-hacked.in new file mode 100644 index 000000000000..027720fc3785 --- /dev/null +++ b/pkgs/games/dwarf-fortress/dwarf-fortress-hacked.in @@ -0,0 +1,13 @@ +#!@stdenv_shell@ + +data_dir=${XDG_DATA_HOME:-$HOME/.local/share}/df_linux +pkg_dir=@prefix@/share/df_linux + +. $pkg_dir/shell/install-df-data-to-home.sh +. $pkg_dir/shell/install-dfhack-data-to-home.sh +. $pkg_dir/shell/install-df-data-content-to-home.sh +. $pkg_dir/shell/export-libs.sh +. $pkg_dir/shell/export-workaround.sh + +cd "$data_dir" +exec ./dfhack "$@" diff --git a/pkgs/games/dwarf-fortress/dwarf-fortress.in b/pkgs/games/dwarf-fortress/dwarf-fortress.in new file mode 100644 index 000000000000..db06d34efd05 --- /dev/null +++ b/pkgs/games/dwarf-fortress/dwarf-fortress.in @@ -0,0 +1,14 @@ +#!@stdenv_shell@ + +set -ex + +data_dir=${XDG_DATA_HOME:-$HOME/.local/share}/df_linux +pkg_dir=@prefix@/share/df_linux + +. $pkg_dir/shell/install-df-data-to-home.sh +. $pkg_dir/shell/install-df-data-content-to-home.sh +. $pkg_dir/shell/export-libs.sh +. $pkg_dir/shell/export-workaround.sh + +cd $data_dir +$pkg_dir/libs/Dwarf_Fortress "$@" diff --git a/pkgs/games/dwarf-fortress/export-libs.sh.in b/pkgs/games/dwarf-fortress/export-libs.sh.in new file mode 100644 index 000000000000..453295ca6ddb --- /dev/null +++ b/pkgs/games/dwarf-fortress/export-libs.sh.in @@ -0,0 +1,12 @@ +export LD_LIBRARY_PATH=\ +@stdenv_cc@/lib:\ +@SDL@/lib:\ +@SDL_image@/lib/:\ +@SDL_ttf@/lib/:\ +@gtk2@/lib/:\ +@glib@/lib/:\ +@mesa@/lib/:\ +@openal@/lib/:\ +@libsndfile@/lib:\ +@zlib@/lib:\ +$data_dir/df_linux/libs/ diff --git a/pkgs/games/dwarf-fortress/export-workaround.sh b/pkgs/games/dwarf-fortress/export-workaround.sh new file mode 100644 index 000000000000..716d171625c3 --- /dev/null +++ b/pkgs/games/dwarf-fortress/export-workaround.sh @@ -0,0 +1 @@ +export SDL_DISABLE_LOCK_KEYS=1 # Work around for bug in Debian/Ubuntu SDL patch. diff --git a/pkgs/games/dwarf-fortress/install-df-data-content-to-home.sh b/pkgs/games/dwarf-fortress/install-df-data-content-to-home.sh new file mode 100644 index 000000000000..600af6773223 --- /dev/null +++ b/pkgs/games/dwarf-fortress/install-df-data-content-to-home.sh @@ -0,0 +1,4 @@ +for link in announcement art dipscript help index initial_movies movies shader.fs shader.vs sound speech; do + cp -r $pkg_dir/data/$link "$data_dir/data/$link" + chmod -R u+rw "$data_dir/data/$link" +done diff --git a/pkgs/games/dwarf-fortress/install-df-data-to-home.sh b/pkgs/games/dwarf-fortress/install-df-data-to-home.sh new file mode 100644 index 000000000000..42c8c4648092 --- /dev/null +++ b/pkgs/games/dwarf-fortress/install-df-data-to-home.sh @@ -0,0 +1,12 @@ +mkdir -p $data_dir +if [[ $(readlink $data_dir/raw) != "$pkg_dir/raw" ]]; then + rm -f $data_dir/raw + ln -s $pkg_dir/raw $data_dir/raw +fi +if [[ $(readlink $data_dir/libs) != "$pkg_dir/libs" ]]; then + rm -f $data_dir/libs + ln -s $pkg_dir/libs $data_dir/libs +fi +mkdir -p "$data_dir/data" +cp -rn $pkg_dir/data/init $data_dir/data/init +chmod -R u+rw $data_dir/data/init diff --git a/pkgs/games/dwarf-fortress/install-dfhack-data-to-home.sh b/pkgs/games/dwarf-fortress/install-dfhack-data-to-home.sh new file mode 100644 index 000000000000..9d316fde9495 --- /dev/null +++ b/pkgs/games/dwarf-fortress/install-dfhack-data-to-home.sh @@ -0,0 +1,16 @@ +if [[ $(readlink $data_dir/hack) != "$pkg_dir/hack" ]]; then + rm -f $data_dir/hack + ln -s $pkg_dir/hack $data_dir/hack +fi +if [[ $(readlink $data_dir/dfhack) != "$pkg_dir/dfhack" ]]; then + rm -f $data_dir/dfhack + ln -s $pkg_dir/dfhack $data_dir/dfhack +fi +if [[ $(readlink $data_dir/dfhack.init-example) != "$pkg_dir/dfhack.init-example" ]]; then + rm -f $data_dir/dfhack.init-example + ln -s $pkg_dir/dfhack.init-example $data_dir/dfhack.init-example +fi +if [[ $(readlink $data_dir/dfhack-run) != "$pkg_dir/dfhack-run" ]]; then + rm -f $data_dir/dfhack-run + ln -s $pkg_dir/dfhack-run $data_dir/dfhack-run +fi diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index daebffa64409..3ad13b487483 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -13780,6 +13780,8 @@ let SDL_image = pkgsi686Linux.SDL_image.override { libpng = pkgsi686Linux.libpng12; }; + inherit (pkgsi686Linux.perlPackages) XMLLibXML XMLLibXSLT; + enableDFHack = config.dwarfFortress.enableDFHack or false; }; dwarf-therapist = callPackage ../games/dwarf-therapist { };