1{
2 stdenv,
3 lib,
4 fetchurl,
5 coreutils,
6 ncurses,
7 gzip,
8 flex,
9 bison,
10 less,
11 buildPackages,
12 x11Mode ? false,
13 qtMode ? false,
14 libXaw,
15 libXext,
16 libXpm,
17 bdftopcf,
18 mkfontdir,
19 pkg-config,
20 qt5,
21 copyDesktopItems,
22 makeDesktopItem,
23}:
24
25let
26 platform =
27 if stdenv.hostPlatform.isUnix then
28 "unix"
29 else
30 throw "Unknown platform for NetHack: ${stdenv.hostPlatform.system}";
31 unixHint =
32 if x11Mode then
33 "linux-x11"
34 else if qtMode then
35 "linux-qt4"
36 else if stdenv.hostPlatform.isLinux then
37 "linux"
38 else if stdenv.hostPlatform.isDarwin then
39 "macosx10.14"
40 # We probably want something different for Darwin
41 else
42 "unix";
43 userDir = "~/.config/nethack";
44 binPath = lib.makeBinPath [
45 coreutils
46 less
47 ];
48
49in
50stdenv.mkDerivation rec {
51 version = "3.6.7";
52 pname =
53 if x11Mode then
54 "nethack-x11"
55 else if qtMode then
56 "nethack-qt"
57 else
58 "nethack";
59
60 src = fetchurl {
61 url = "https://nethack.org/download/${version}/nethack-${
62 lib.replaceStrings [ "." ] [ "" ] version
63 }-src.tgz";
64 sha256 = "sha256-mM9n323r+WaKYXRaqEwJvKs2Ll0z9blE7FFV1E0qrLI=";
65 };
66
67 buildInputs = [
68 ncurses
69 ]
70 ++ lib.optionals x11Mode [
71 libXaw
72 libXext
73 libXpm
74 ]
75 ++ lib.optionals qtMode [
76 gzip
77 qt5.qtbase.bin
78 qt5.qtmultimedia.bin
79 ];
80
81 nativeBuildInputs = [
82 flex
83 bison
84 copyDesktopItems
85 ]
86 ++ lib.optionals x11Mode [
87 mkfontdir
88 bdftopcf
89 ]
90 ++ lib.optionals qtMode [
91 pkg-config
92 mkfontdir
93 qt5.qtbase.dev
94 qt5.qtmultimedia.dev
95 qt5.wrapQtAppsHook
96 bdftopcf
97 ];
98
99 makeFlags = [ "PREFIX=$(out)" ];
100
101 postPatch = ''
102 sed -e '/^ *cd /d' -i sys/unix/nethack.sh
103 sed \
104 -e 's/^YACC *=.*/YACC = bison -y/' \
105 -e 's/^LEX *=.*/LEX = flex/' \
106 -i sys/unix/Makefile.utl
107 sed \
108 -e 's,^WINQT4LIB =.*,WINQT4LIB = `pkg-config Qt5Gui --libs` \\\
109 `pkg-config Qt5Widgets --libs` \\\
110 `pkg-config Qt5Multimedia --libs`,' \
111 -i sys/unix/Makefile.src
112 sed \
113 -e 's,^CFLAGS=-g,CFLAGS=,' \
114 -e 's,/bin/gzip,${gzip}/bin/gzip,g' \
115 -e 's,^WINTTYLIB=.*,WINTTYLIB=-lncurses,' \
116 -i sys/unix/hints/linux
117 sed \
118 -e 's,^#WANT_WIN_CURSES=1$,WANT_WIN_CURSES=1,' \
119 -e 's,^CC=.*$,CC=${stdenv.cc.targetPrefix}cc,' \
120 -e 's,^HACKDIR=.*$,HACKDIR=\$(PREFIX)/games/lib/\$(GAME)dir,' \
121 -e 's,^SHELLDIR=.*$,SHELLDIR=\$(PREFIX)/games,' \
122 -e 's,^CFLAGS=-g,CFLAGS=,' \
123 -i sys/unix/hints/macosx10.14
124 sed -e '/define CHDIR/d' -i include/config.h
125 ${lib.optionalString qtMode ''
126 sed \
127 -e 's,^QTDIR *=.*,QTDIR=${qt5.qtbase.dev},' \
128 -e 's,CFLAGS.*QtGui.*,CFLAGS += `pkg-config Qt5Gui --cflags`,' \
129 -e 's,CFLAGS+=-DCOMPRESS.*,CFLAGS+=-DCOMPRESS=\\"${gzip}/bin/gzip\\" \\\
130 -DCOMPRESS_EXTENSION=\\".gz\\",' \
131 -e 's,moc-qt4,moc,' \
132 -i sys/unix/hints/linux-qt4
133 ''}
134 ${lib.optionalString (stdenv.buildPlatform != stdenv.hostPlatform)
135 # If we're cross-compiling, replace the paths to the data generation tools
136 # with the ones from the build platform's nethack package, since we can't
137 # run the ones we've built here.
138 ''
139 ${buildPackages.perl}/bin/perl -p \
140 -e 's,[a-z./]+/(makedefs|dgn_comp|lev_comp|dlb)(?!\.),${buildPackages.nethack}/libexec/nethack/\1,g' \
141 -i sys/unix/Makefile.*
142 ''
143 }
144 sed -i -e '/rm -f $(MAKEDEFS)/d' sys/unix/Makefile.src
145 # Fix building on darwin where otherwise __has_attribute fails with an empty parameter
146 sed -e 's/define __warn_unused_result__ .*/define __warn_unused_result__ __unused__/' -i include/tradstdc.h
147 sed -e 's/define warn_unused_result .*/define warn_unused_result __unused__/' -i include/tradstdc.h
148 '';
149
150 configurePhase = ''
151 pushd sys/${platform}
152 ${lib.optionalString (platform == "unix") ''
153 sh setup.sh hints/${unixHint}
154 ''}
155 popd
156 '';
157
158 # https://github.com/NixOS/nixpkgs/issues/294751
159 enableParallelBuilding = false;
160
161 preFixup = lib.optionalString qtMode ''
162 wrapQtApp "$out/games/nethack"
163 '';
164
165 postInstall = ''
166 mkdir -p $out/games/lib/nethackuserdir
167 for i in xlogfile logfile perm record save; do
168 mv $out/games/lib/nethackdir/$i $out/games/lib/nethackuserdir
169 done
170
171 mkdir -p $out/bin
172 cat <<EOF >$out/bin/nethack
173 #! ${stdenv.shell} -e
174 PATH=${binPath}:\$PATH
175
176 if [ ! -d ${userDir} ]; then
177 mkdir -p ${userDir}
178 cp -r $out/games/lib/nethackuserdir/* ${userDir}
179 chmod -R +w ${userDir}
180 fi
181
182 RUNDIR=\$(mktemp -d)
183
184 cleanup() {
185 rm -rf \$RUNDIR
186 }
187 trap cleanup EXIT
188
189 cd \$RUNDIR
190 for i in ${userDir}/*; do
191 ln -s \$i \$(basename \$i)
192 done
193 for i in $out/games/lib/nethackdir/*; do
194 ln -s \$i \$(basename \$i)
195 done
196 $out/games/nethack
197 EOF
198 chmod +x $out/bin/nethack
199 ${lib.optionalString x11Mode "mv $out/bin/nethack $out/bin/nethack-x11"}
200 ${lib.optionalString qtMode "mv $out/bin/nethack $out/bin/nethack-qt"}
201 install -Dm 555 util/{makedefs,dgn_comp,lev_comp} -t $out/libexec/nethack/
202 ${lib.optionalString (!(x11Mode || qtMode)) "install -Dm 555 util/dlb -t $out/libexec/nethack/"}
203 '';
204
205 desktopItems = [
206 (makeDesktopItem {
207 name = "NetHack";
208 exec =
209 if x11Mode then
210 "nethack-x11"
211 else if qtMode then
212 "nethack-qt"
213 else
214 "nethack";
215 icon = "nethack";
216 desktopName = "NetHack";
217 comment = "NetHack is a single player dungeon exploration game";
218 categories = [
219 "Game"
220 "ActionGame"
221 ];
222 })
223 ];
224
225 meta = with lib; {
226 description = "Rogue-like game";
227 homepage = "http://nethack.org/";
228 license = "nethack";
229 platforms = if x11Mode then platforms.linux else platforms.unix;
230 maintainers = with maintainers; [ abbradar ];
231 mainProgram = "nethack";
232 };
233}