Merge pull request #43470 from numinit/df

dwarf-fortress: Refactor, round 2: let the user pick which version of the lazy pack to install
This commit is contained in:
Matthew Bauer 2018-09-09 13:27:12 -05:00 committed by GitHub
commit e4db8a903a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 322 additions and 95 deletions

View File

@ -5,67 +5,112 @@
# This directory menaces with spikes of Nix code. It is terrifying.
#
# If this is your first time here, you should probably install the dwarf-fortress-full package,
# for instance with `environment.systempackages = [ pkgs.dwarf-fortress.dwarf-fortress-full ];`.
# for instance with:
#
# environment.systemPackages = [ pkgs.dwarf-fortress-packages.dwarf-fortress-full ];
#
# You can adjust its settings by using override, or compile your own package by
# using the other packages here. Take a look at lazy-pack.nix to get an idea of
# how.
# using the other packages here.
#
# For example, you can enable the FPS indicator, disable the intro, pick a
# theme other than phoebus (the default for dwarf-fortress-full), _and_ use
# an older version with something like:
#
# environment.systemPackages = [
# (pkgs.dwarf-fortress-packages.dwarf-fortress-full.override {
# dfVersion = "0.44.11";
# theme = "cla";
# enableIntro = false;
# enableFPS = true;
# })
# ]
#
# Take a look at lazy-pack.nix to see all the other options.
#
# You will find the configuration files in ~/.local/share/df_linux/data/init. If
# you un-symlink them and edit, then the scripts will avoid overwriting your
# changes on later launches, but consider extending the wrapper with your
# desired options instead.
#
# Although both dfhack and dwarf therapist are included in the lazy pack, you
# can only use one at a time. DFHack does have therapist-like features, so this
# may or may not be a problem.
with lib;
let
callPackage = pkgs.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.44.12";
# Converts a version to a package name.
versionToName = version: "dwarf-fortress_${lib.replaceStrings ["."] ["_"] version}";
# A map of names to each Dwarf Fortress package we know about.
df-games = lib.listToAttrs (map (dfVersion: {
name = "dwarf-fortress_${lib.replaceStrings ["."] ["_"] dfVersion}";
value = callPackage ./wrapper {
inherit (self) themes;
dwarf-fortress = callPackage ./game.nix { inherit dfVersion; };
name = versionToName dfVersion;
value =
let
# I can't believe this syntax works. Spikes of Nix code indeed...
dwarf-fortress = callPackage ./game.nix {
inherit dfVersion;
inherit dwarf-fortress-unfuck;
};
}) (lib.attrNames self.df-hashes));
self = rec {
df-hashes = builtins.fromJSON (builtins.readFile ./game.json);
dwarf-fortress = df-games.dwarf-fortress_0_44_12;
# unfuck is linux-only right now, we will only use it there.
dwarf-fortress-unfuck = if stdenv.isLinux then callPackage ./unfuck.nix { inherit dfVersion; }
else null;
dwarf-fortress-full = callPackage ./lazy-pack.nix { };
twbt = callPackage ./twbt { inherit dfVersion; };
dfhack = callPackage ./dfhack {
inherit (pkgs.perlPackages) XMLLibXML XMLLibXSLT;
inherit dfVersion twbt;
stdenv = gccStdenv;
};
soundSense = callPackage ./soundsense.nix { };
# unfuck is linux-only right now, we will only use it there.
dwarf-fortress-unfuck = if stdenv.isLinux then callPackage ./unfuck.nix { }
else null;
dwarf-therapist = callPackage ./dwarf-therapist/wrapper.nix {
inherit (dwarf-fortress) dwarf-fortress;
inherit dwarf-fortress;
dwarf-therapist = pkgs.qt5.callPackage ./dwarf-therapist {
texlive = pkgs.texlive.combine {
inherit (pkgs.texlive) scheme-basic float caption wrapfig adjmulticol sidecap preprint enumitem;
};
};
};
in
callPackage ./wrapper {
inherit (self) themes;
dwarf-fortress = dwarf-fortress;
dwarf-fortress-unfuck = dwarf-fortress-unfuck;
twbt = twbt;
dfhack = dfhack;
dwarf-therapist = dwarf-therapist;
};
}) (lib.attrNames self.df-hashes));
self = rec {
df-hashes = builtins.fromJSON (builtins.readFile ./game.json);
# Aliases for the latest Dwarf Fortress and the selected Therapist install
dwarf-fortress = getAttr (versionToName latestVersion) df-games;
dwarf-therapist = dwarf-fortress.dwarf-therapist;
dwarf-fortress-original = dwarf-fortress.dwarf-fortress;
dwarf-fortress-full = callPackage ./lazy-pack.nix {
inherit df-games versionToName latestVersion;
};
soundSense = callPackage ./soundsense.nix { };
legends-browser = callPackage ./legends-browser {};
twbt = callPackage ./twbt {};
themes = recurseIntoAttrs (callPackage ./themes { });
themes = recurseIntoAttrs (callPackage ./themes {
stdenv = stdenvNoCC;
});
# aliases
# Theme aliases
phoebus-theme = themes.phoebus;
cla-theme = themes.cla;
dwarf-fortress-original = dwarf-fortress.dwarf-fortress;
};
in self // df-games

View File

@ -3,14 +3,62 @@
, enableStoneSense ? false, allegro5, libGLU_combined
, enableTWBT ? true, twbt
, SDL
, dfVersion
}:
with lib;
let
dfVersion = "0.44.12";
version = "${dfVersion}-r1";
dfhack-releases = {
"0.43.05" = {
dfHackRelease = "0.43.05-r3.1";
sha256 = "1ds366i0qcfbn62w9qv98lsqcrm38npzgvcr35hf6ihqa6nc6xrl";
xmlRev = "860a9041a75305609643d465123a4b598140dd7f";
prerelease = false;
};
"0.44.05" = {
dfHackRelease = "0.44.05-r2";
sha256 = "1cwifdhi48a976xc472nf6q2k0ibwqffil5a4llcymcxdbgxdcc9";
xmlRev = "2794f8a6d7405d4858bac486a0bb17b94740c142";
prerelease = false;
};
"0.44.09" = {
dfHackRelease = "0.44.09-r1";
sha256 = "1nkfaa43pisbyik5inj5q2hja2vza5lwidg5z02jyh136jm64hwk";
xmlRev = "3c0bf63674d5430deadaf7befaec42f0ec1e8bc5";
prerelease = false;
};
"0.44.10" = {
dfHackRelease = "0.44.10-r2";
sha256 = "19bxsghxzw3bilhr8sm4axz7p7z8lrvbdsd1vdjf5zbg04rs866i";
xmlRev = "321bd48b10c4c3f694cc801a7dee6be392c09b7b";
prerelease = false;
};
"0.44.11" = {
dfHackRelease = "0.44.11-beta2.1";
sha256 = "1jgwcqg9m1ybv3szgnklp6zfpiw5mswla464dlj2gfi5v82zqbv2";
xmlRev = "f27ebae6aa8fb12c46217adec5a812cd49a905c8";
prerelease = true;
};
"0.44.12" = {
dfHackRelease = "0.44.12-r1";
sha256 = "0j03lq6j6w378z6cvm7jspxc7hhrqm8jaszlq0mzfvap0k13fgyy";
xmlRev = "23500e4e9bd1885365d0a2ef1746c321c1dd5094";
prerelease = false;
};
};
release = if hasAttr dfVersion dfhack-releases
then getAttr dfVersion dfhack-releases
else throw "[DFHack] Unsupported Dwarf Fortress version: ${dfVersion}";
version = release.dfHackRelease;
warning = if release.prerelease then builtins.trace "[DFHack] Version ${version} is a prerelease. Careful!"
else null;
# revision of library/xml submodule
xmlRev = "23500e4e9bd1885365d0a2ef1746c321c1dd5094";
xmlRev = release.xmlRev;
arch =
if stdenv.hostPlatform.system == "x86_64-linux" then "64"
@ -21,6 +69,10 @@ let
#! ${stdenv.shell}
if [ "$*" = "describe --tags --long" ]; then
echo "${version}-unknown"
elif [ "$*" = "describe --tags --abbrev=8 --long" ]; then
echo "${version}-unknown"
elif [ "$*" = "describe --tags --abbrev=8 --exact-match" ]; then
echo "${version}"
elif [ "$*" = "rev-parse HEAD" ]; then
if [ "$(dirname "$(pwd)")" = "xml" ]; then
echo "${xmlRev}"
@ -41,8 +93,8 @@ let
src = fetchFromGitHub {
owner = "DFHack";
repo = "dfhack";
sha256 = "0j03lq6j6w378z6cvm7jspxc7hhrqm8jaszlq0mzfvap0k13fgyy";
rev = version;
rev = release.dfHackRelease;
sha256 = release.sha256;
fetchSubmodules = true;
};

View File

@ -0,0 +1,26 @@
#!@stdenv_shell@ -e
[ -z "$DT_DIR" ] && DT_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/dwarftherapist"
install_dir="@install@"
therapist_dir="@therapist@"
cat <<EOF >&2
Using $DT_DIR as Dwarf Therapist overlay directory.
EOF
update_path() {
local path="$1"
mkdir -p "$DT_DIR/$(dirname "$path")"
if [ ! -e "$DT_DIR/$path" ] || [ -L "$DT_DIR/$path" ]; then
rm -f "$DT_DIR/$path"
ln -s "$install_dir/share/dwarftherapist/$path" "$DT_DIR/$path"
fi
}
cd "$install_dir/share/dwarftherapist"
update_path memory_layouts
QT_QPA_PLATFORM_PLUGIN_PATH="@qt_plugin_path@" \
exec "$therapist_dir/bin/dwarftherapist" "$@"

View File

@ -1,33 +1,50 @@
{ stdenv, symlinkJoin, dwarf-therapist, dwarf-fortress, makeWrapper }:
{ pkgs, stdenv, symlinkJoin, lib, dwarf-therapist, dwarf-fortress, makeWrapper }:
let
platformSlug = if stdenv.targetPlatform.is32bit then
"linux32" else "linux64";
inifile = "linux/v0.${dwarf-fortress.baseVersion}.${dwarf-fortress.patchVersion}_${platformSlug}.ini";
in symlinkJoin {
in
stdenv.mkDerivation rec {
name = "dwarf-therapist-${dwarf-therapist.version}";
wrapper = ./dwarf-therapist.in;
paths = [ dwarf-therapist ];
buildInputs = [ makeWrapper ];
passthru = { inherit dwarf-fortress dwarf-therapist; };
postBuild = ''
# DwarfTherapist assumes it's run in $out/share/dwarftherapist and
# therefore uses many relative paths.
wrapProgram $out/bin/dwarftherapist \
--run "cd $out/share/dwarftherapist"
buildCommand = ''
mkdir -p $out/bin
ln -s $out/bin/dwarftherapist $out/bin/DwarfTherapist
substitute $wrapper $out/bin/dwarftherapist \
--subst-var-by stdenv_shell ${stdenv.shell} \
--subst-var-by install $out \
--subst-var-by therapist ${dwarf-therapist} \
--subst-var-by qt_plugin_path "${pkgs.qt5.qtbase}/lib/qt-${pkgs.qt5.qtbase.qtCompatVersion}/plugins/platforms"
chmod 755 $out/bin/dwarftherapist
# Fix up memory layouts
rm -rf $out/share/dwarftherapist/memory_layouts/linux
mkdir -p $out/share/dwarftherapist/memory_layouts/linux
origmd5=$(cat "${dwarf-fortress}/hash.md5.orig" | cut -c1-8)
patchedmd5=$(cat "${dwarf-fortress}/hash.md5" | cut -c1-8)
substitute \
${dwarf-therapist}/share/dwarftherapist/memory_layouts/${inifile} \
$out/share/dwarftherapist/memory_layouts/${inifile} \
--replace "$origmd5" "$patchedmd5"
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}"
output_file="$out/share/dwarftherapist/memory_layouts/${inifile}"
echo "[Dwarf Therapist Wrapper] Fixing Dwarf Fortress MD5 prefix:"
echo " Input: $input_file"
echo " Search: $orig_md5"
echo " Output: $output_file"
echo " Replace: $patched_md5"
substitute "$input_file" "$output_file" --replace "$orig_md5" "$patched_md5"
'';
preferLocalBuild = true;
}

View File

@ -42,9 +42,6 @@ let
in
assert dwarf-fortress-unfuck != null ->
dwarf-fortress-unfuck.dfVersion == dfVersion;
stdenv.mkDerivation {
name = "dwarf-fortress-${dfVersion}";

View File

@ -1,13 +1,14 @@
{ stdenvNoCC, lib, buildEnv
, dwarf-fortress, themes
{ stdenvNoCC, lib, buildEnv, callPackage
, df-games, themes, latestVersion, versionToName
, dfVersion ? latestVersion
# This package should, at any given time, provide an opinionated "optimal"
# DF experience. It's the equivalent of the Lazy Newbie Pack, that is, and
# should contain every utility available.
# should contain every utility available unless you disable them.
, enableDFHack ? stdenvNoCC.isLinux
, enableTWBT ? enableDFHack
, enableSoundSense ? true
, enableStoneSense ? false # StoneSense is currently broken.
, enableDwarfTherapist ? true, dwarf-therapist
, enableStoneSense ? true
, enableDwarfTherapist ? true
, enableLegendsBrowser ? true, legends-browser
, theme ? themes.phoebus
# General config options:
@ -16,6 +17,15 @@
, enableFPS ? false
}:
with lib;
let
dfGame = versionToName dfVersion;
dwarf-fortress = if hasAttr dfGame df-games
then getAttr dfGame df-games
else throw "Unknown Dwarf Fortress version: ${dfVersion}";
dwarf-therapist = dwarf-fortress.dwarf-therapist;
in
buildEnv {
name = "dwarf-fortress-full";
paths = [
@ -28,7 +38,7 @@ buildEnv {
meta = with stdenvNoCC.lib; {
description = "An opinionated wrapper for Dwarf Fortress";
maintainers = with maintainers; [ Baughn ];
maintainers = with maintainers; [ Baughn numinit ];
license = licenses.mit;
platforms = platforms.all;
homepage = https://github.com/NixOS/nixpkgs/;

View File

@ -1,4 +1,4 @@
{lib, fetchFromGitHub}:
{lib, fetchFromGitHub, ...}:
with builtins;

View File

@ -1,14 +1,59 @@
{ stdenvNoCC, fetchurl, unzip }:
{ stdenvNoCC, lib, fetchurl, unzip
, dfVersion
}:
with lib;
let
twbt-releases = {
"0.43.05" = {
twbtRelease = "6.22";
sha256 = "0di5d38f6jj9smsz0wjcs1zav4zba6hrk8cbn59kwpb1wamsh5c7";
prerelease = false;
};
"0.44.05" = {
twbtRelease = "6.35";
sha256 = "0qjkgl7dsqzsd7pdq8a5bihhi1wplfkv1id7sj6dp3swjpsfxp8g";
prerelease = false;
};
"0.44.09" = {
twbtRelease = "6.41";
sha256 = "0nsq15z05pbhqjvw2xqs1a9b1n2ma0aalhc3vh3mi4cd4k7lxh44";
prerelease = false;
};
"0.44.10" = {
twbtRelease = "6.49";
sha256 = "1qjkc7k33qhxj2g18njzasccjqsis5y8zrw5vl90h4rs3i8ld9xz";
prerelease = false;
};
"0.44.11" = {
twbtRelease = "6.51";
sha256 = "1yclqmarjd97ch054h425a12r8a5ailmflsd7b39cg4qhdr1nii5";
prerelease = true;
};
"0.44.12" = {
twbtRelease = "6.54";
sha256 = "10gfd6vv0vk4v1r5hjbz7vf1zqys06dsad695gysc7fbcik2dakh";
prerelease = false;
};
};
release = if hasAttr dfVersion twbt-releases
then getAttr dfVersion twbt-releases
else throw "[TWBT] Unsupported Dwarf Fortress version: ${dfVersion}";
warning = if release.prerelease then builtins.trace "[TWBT] Version ${version} is a prerelease. Careful!"
else null;
in
stdenvNoCC.mkDerivation rec {
name = "twbt-${version}";
version = "6.54";
dfVersion = "0.44.12";
version = release.twbtRelease;
src = fetchurl {
url = "https://github.com/mifki/df-twbt/releases/download/v${version}/twbt-${version}-linux.zip";
sha256 = "10gfd6vv0vk4v1r5hjbz7vf1zqys06dsad695gysc7fbcik2dakh";
sha256 = release.sha256;
};
sourceRoot = ".";
@ -24,10 +69,9 @@ stdenvNoCC.mkDerivation rec {
cp -a *.png $art/data/art/
'';
meta = with stdenvNoCC.lib; {
description = "A plugin for Dwarf Fortress / DFHack that improves various aspects the game interface.";
maintainers = with maintainers; [ Baughn ];
maintainers = with maintainers; [ Baughn numinit ];
license = licenses.mit;
platforms = platforms.linux;
homepage = https://github.com/mifki/df-twbt;

View File

@ -1,18 +1,52 @@
{ stdenv, fetchFromGitHub, cmake
{ stdenv, lib, fetchFromGitHub, cmake
, libGL, libSM, SDL, SDL_image, SDL_ttf, glew, openalSoft
, ncurses, glib, gtk2, libsndfile, zlib
, dfVersion
}:
let dfVersion = "0.44.12"; in
with lib;
let
unfuck-releases = {
"0.43.05" = {
unfuckRelease = "0.43.05";
sha256 = "173dyrbxlzqvjf1j3n7vpns4gfjkpyvk9z16430xnmd5m6nda8p2";
};
"0.44.05" = {
unfuckRelease = "0.44.05";
sha256 = "00yj4l4gazxg4i6fj9rwri6vm17i6bviy2mpkx0z5c0mvsr7s14b";
};
"0.44.09" = {
unfuckRelease = "0.44.09";
sha256 = "138p0v8z2x47f0fk9k6g75ikw5wb3vxldwv5ggbkf4hhvlw6lvzm";
};
"0.44.10" = {
unfuckRelease = "0.44.10";
sha256 = "0vb19qx2ibc79j4bgbk9lskb883qfb0815zw1dfz9k7rqwal8mzj";
};
"0.44.11" = {
unfuckRelease = "0.44.11.1";
sha256 = "1kszkb1d1vll8p04ja41nangsaxb5lv4p3xh2jhmsmipfixw7nvz";
};
"0.44.12" = {
unfuckRelease = "0.44.12";
sha256 = "1kszkb1d1vll8p04ja41nangsaxb5lv4p3xh2jhmsmipfixw7nvz";
};
};
release = if hasAttr dfVersion unfuck-releases
then getAttr dfVersion unfuck-releases
else throw "[unfuck] Unknown Dwarf Fortress version: ${dfVersion}";
in
stdenv.mkDerivation {
name = "dwarf_fortress_unfuck-${dfVersion}";
name = "dwarf_fortress_unfuck-${release.unfuckRelease}";
src = fetchFromGitHub {
owner = "svenstaro";
repo = "dwarf_fortress_unfuck";
rev = dfVersion;
sha256 = "1kszkb1d1vll8p04ja41nangsaxb5lv4p3xh2jhmsmipfixw7nvz";
rev = release.unfuckRelease;
sha256 = release.sha256;
};
cmakeFlags = [
@ -20,23 +54,12 @@ stdenv.mkDerivation {
"-DGTK2_GDKCONFIG_INCLUDE_DIR=${gtk2.out}/lib/gtk-2.0/include"
];
makeFlags = [
''CFLAGS="-fkeep-inline-functions"''
''CXXFLAGS="-fkeep-inline-functions"''
];
nativeBuildInputs = [ cmake ];
buildInputs = [
libSM SDL SDL_image SDL_ttf glew openalSoft
ncurses gtk2 libsndfile zlib libGL
];
postPatch = ''
substituteInPlace CMakeLists.txt --replace \
'set(CMAKE_BUILD_TYPE Release)' \
'set(CMAKE_BUILD_TYPE Debug)'
'';
# Don't strip unused symbols; dfhack hooks into some of them.
dontStrip = true;
@ -56,6 +79,6 @@ stdenv.mkDerivation {
homepage = https://github.com/svenstaro/dwarf_fortress_unfuck;
license = licenses.free;
platforms = platforms.linux;
maintainers = with maintainers; [ abbradar ];
maintainers = with maintainers; [ abbradar numinit ];
};
}

View File

@ -1,4 +1,6 @@
{ stdenv, lib, buildEnv, dwarf-fortress, substituteAll
{ stdenv, lib, buildEnv, substituteAll
, dwarf-fortress, dwarf-fortress-unfuck
, dwarf-therapist
, enableDFHack ? false, dfhack
, enableSoundSense ? false, soundSense, jdk
, enableStoneSense ? false
@ -36,18 +38,29 @@ let
paths = themePkg ++ pkgs;
pathsToLink = [ "/" "/hack" "/hack/scripts" ];
ignoreCollisions = true;
postBuild = ''
# De-symlink init.txt
cp $out/data/init/init.txt init.txt
rm $out/data/init/init.txt
rm -f $out/data/init/init.txt
mv init.txt $out/data/init/init.txt
'' + lib.optionalString enableDFHack ''
# De-symlink symbols.xml
rm $out/hack/symbols.xml
substitute ${dfhack_}/hack/symbols.xml $out/hack/symbols.xml \
--replace $(cat ${dwarf-fortress}/hash.md5.orig) \
$(cat ${dwarf-fortress}/hash.md5)
# Patch the MD5
orig_md5=$(cat "${dwarf-fortress}/hash.md5.orig")
patched_md5=$(cat "${dwarf-fortress}/hash.md5")
input_file="${dfhack_}/hack/symbols.xml"
output_file="$out/hack/symbols.xml"
echo "[DFHack Wrapper] Fixing Dwarf Fortress MD5:"
echo " Input: $input_file"
echo " Search: $orig_md5"
echo " Output: $output_file"
echo " Replace: $patched_md5"
substitute "$input_file" "$output_file" --replace "$orig_md5" "$patched_md5"
'' + lib.optionalString enableTWBT ''
substituteInPlace $out/data/init/init.txt \
--replace '[PRINT_MODE:2D]' '[PRINT_MODE:TWBT]'
@ -57,14 +70,14 @@ let
--replace '[TRUETYPE:YES]' '[TRUETYPE:${unBool enableTruetype}]' \
--replace '[FPS:NO]' '[FPS:${unBool enableFPS}]'
'';
ignoreCollisions = true;
};
in
stdenv.mkDerivation rec {
name = "dwarf-fortress-${dwarf-fortress.dfVersion}";
compatible = lib.all (x: assert (x.dfVersion == dwarf-fortress.dfVersion); true) pkgs;
dfInit = substituteAll {
name = "dwarf-fortress-init";
src = ./dwarf-fortress-init.in;
@ -77,7 +90,7 @@ stdenv.mkDerivation rec {
runDFHack = ./dfhack.in;
runSoundSense = ./soundSense.in;
passthru = { inherit dwarf-fortress; };
passthru = { inherit dwarf-fortress dwarf-therapist; };
buildCommand = ''
mkdir -p $out/bin