1{
2 lib,
3 stdenv,
4 fetchFromGitLab,
5 autoconf,
6 automake,
7 gnum4,
8 pkg-config,
9 bison,
10 python3,
11 which,
12 boost,
13 ftgl,
14 freetype,
15 glew,
16 SDL,
17 SDL_image,
18 SDL_mixer,
19 SDL2,
20 SDL2_image,
21 SDL2_mixer,
22 libGL,
23 libGLU,
24 libpng,
25 libX11,
26 libxml2,
27 protobuf,
28 xvfb-run,
29 gnugrep,
30 nixosTests,
31 dedicatedServer ? false,
32}:
33
34let
35 latestVersionMajor = "0.2.9";
36 unstableVersionMajor = "0.4";
37
38 srcs =
39 let
40 fetchArmagetron =
41 rev: hash:
42 fetchFromGitLab {
43 owner = "armagetronad";
44 repo = "armagetronad";
45 inherit rev hash;
46 };
47 in
48 {
49 # https://gitlab.com/armagetronad/armagetronad/-/tags
50 ${latestVersionMajor} =
51 let
52 version = "${latestVersionMajor}.2.3";
53 rev = "v${version}";
54 hash = "sha256-lfYJ3luGK9hB0aiiBiJIqq5ddANqGaVtKXckbo4fl2g=";
55 in
56 dedicatedServer: {
57 inherit version;
58 src = fetchArmagetron rev hash;
59 extraBuildInputs = lib.optionals (!dedicatedServer) [
60 libGL
61 libGLU
62 libX11
63 libpng
64 SDL
65 SDL_image
66 SDL_mixer
67 ];
68 };
69
70 # https://gitlab.com/armagetronad/armagetronad/-/commits/trunk/?ref_type=heads
71 ${unstableVersionMajor} =
72 let
73 rev = "813b684ab0de8ee9737c9fc1f9b90ba0543dd418";
74 hash = "sha256-01jWE9rSBJn+JS8p8LTFqIGquOY1avXsAZnfYfo5pPk=";
75 in
76 dedicatedServer: {
77 version = "${unstableVersionMajor}-${builtins.substring 0 8 rev}";
78 src = fetchArmagetron rev hash;
79 extraBuildInputs = [
80 protobuf
81 boost
82 ]
83 ++ lib.optionals (!dedicatedServer) [
84 glew
85 ftgl
86 freetype
87 libGL
88 libGLU
89 libX11
90 SDL2
91 SDL2_image
92 SDL2_mixer
93 ];
94 extraNativeBuildInputs = [ bison ];
95 };
96
97 # https://gitlab.com/armagetronad/armagetronad/-/commits/hack-0.2.8-sty+ct+ap/?ref_type=heads
98 "${latestVersionMajor}-sty+ct+ap" =
99 let
100 rev = "5a17cc9fb6e1e27a358711afbd745ae54d4a8c60";
101 hash = "sha256-111C1j/hSaASGcvYy3//TyHs4Z+3fuiOvCmtcWLdFd4=";
102 in
103 dedicatedServer: {
104 version = "${latestVersionMajor}-sty+ct+ap-${builtins.substring 0 8 rev}";
105 src = fetchArmagetron rev hash;
106 extraBuildInputs = lib.optionals (!dedicatedServer) [
107 libGL
108 libGLU
109 libX11
110 libpng
111 SDL
112 SDL_image
113 SDL_mixer
114 ];
115 };
116 };
117
118 # Creates an Armagetron build. Takes a function returning build inputs for a particular value of dedicatedServer.
119 mkArmagetron =
120 fn: dedicatedServer:
121 let
122 # Compute the build params.
123 resolvedParams = fn dedicatedServer;
124
125 # Figure out the binary name depending on whether this is a dedicated server.
126 mainProgram = if dedicatedServer then "armagetronad-dedicated" else "armagetronad";
127
128 # Split the version into the major and minor parts
129 versionParts = lib.splitString "-" resolvedParams.version;
130 splitVersion = lib.splitVersion (builtins.elemAt versionParts 0);
131 majorVersion = builtins.concatStringsSep "." (lib.lists.take 2 splitVersion);
132
133 minorVersionPart =
134 parts: sep: expectedSize:
135 if builtins.length parts > expectedSize then
136 sep + (builtins.concatStringsSep sep (lib.lists.drop expectedSize parts))
137 else
138 "";
139
140 minorVersion =
141 (minorVersionPart splitVersion "." 2) + (minorVersionPart versionParts "-" 1) + "-nixpkgs";
142 in
143 stdenv.mkDerivation {
144 pname = mainProgram;
145 inherit (resolvedParams) version src;
146
147 # Build works fine; install has a race.
148 enableParallelBuilding = true;
149 enableParallelInstalling = false;
150
151 preConfigure = ''
152 patchShebangs .
153
154 # Create the version.
155 echo "${majorVersion}" > major_version
156 echo "${minorVersion}" > minor_version
157
158 echo "Bootstrapping version: $(<major_version)$(<minor_version)" >&2
159 ./bootstrap.sh
160 '';
161
162 configureFlags = [
163 "--enable-automakedefaults"
164 "--enable-authentication"
165 "--disable-memmanager"
166 "--disable-useradd"
167 "--disable-initscripts"
168 "--disable-etc"
169 "--disable-uninstall"
170 "--disable-sysinstall"
171 ]
172 ++ lib.optional dedicatedServer "--enable-dedicated"
173 ++ lib.optional (!dedicatedServer) "--enable-music";
174
175 buildInputs =
176 lib.singleton (libxml2.override { enableHttp = true; }) ++ (resolvedParams.extraBuildInputs or [ ]);
177
178 nativeBuildInputs = [
179 autoconf
180 automake
181 gnum4
182 pkg-config
183 which
184 python3
185 ]
186 ++ (resolvedParams.extraNativeBuildInputs or [ ]);
187
188 nativeInstallCheckInputs = [
189 gnugrep
190 ]
191 ++ lib.optional (!dedicatedServer) xvfb-run
192 ++ (resolvedParams.extraNativeInstallCheckInputs or [ ]);
193
194 postInstall = lib.optionalString (!dedicatedServer) ''
195 mkdir -p $out/share/{applications,icons/hicolor}
196 ln -s $out/share/games/armagetronad/desktop/armagetronad*.desktop $out/share/applications/
197 ln -s $out/share/games/armagetronad/desktop/icons $out/share/icons/hicolor
198 '';
199
200 doInstallCheck = true;
201
202 installCheckPhase = ''
203 export XDG_RUNTIME_DIR=/tmp
204 bin="$out/bin/${mainProgram}"
205 if command -v xvfb-run &>/dev/null; then
206 run="xvfb-run $bin"
207 else
208 run="$bin"
209 fi
210 echo "Checking game info:" >&2
211 version="$($run --version || true)"
212 echo " - Version: $version" >&2
213 prefix="$($run --prefix || true)"
214 echo " - Prefix: $prefix" >&2
215 rubber="$(($run --doc || true) | grep -m1 CYCLE_RUBBER)"
216 echo " - Docstring: $rubber" >&2
217
218 if [[ "$version" != *"${resolvedParams.version}"* ]] || \
219 [ "$prefix" != "$out" ] || \
220 [[ ! "$rubber" =~ ^CYCLE_RUBBER[[:space:]]+Niceness[[:space:]]factor ]]; then
221 echo "Something didn't match. :-(" >&2
222 exit 1
223 else
224 echo "Everything is ok." >&2
225 fi
226 '';
227
228 passthru =
229 if (dedicatedServer) then
230 {
231 # No passthru, end of the line.
232 # https://www.youtube.com/watch?v=NOMa56y_Was
233 }
234 else if (resolvedParams.version != (srcs.${latestVersionMajor} dedicatedServer).version) then
235 {
236 # Allow a "dedicated" passthru for versions other than the default.
237 dedicated = mkArmagetron fn true;
238 }
239 else
240 (lib.mapAttrs (name: value: mkArmagetron value dedicatedServer) (
241 lib.filterAttrs (
242 name: value: (value dedicatedServer).version != (srcs.${latestVersionMajor} dedicatedServer).version
243 ) srcs
244 ))
245 // {
246 # Allow both a "dedicated" passthru and a passthru for all the options other than the latest version, which this is.
247 dedicated = mkArmagetron fn true;
248 tests.armagetronad = nixosTests.armagetronad;
249 };
250
251 meta = with lib; {
252 inherit mainProgram;
253 homepage = "https://www.armagetronad.org";
254 description = "Multiplayer networked arcade racing game in 3D similar to Tron";
255 maintainers = with maintainers; [ numinit ];
256 license = licenses.gpl2Plus;
257 platforms = platforms.linux;
258 };
259 };
260in
261mkArmagetron srcs.${latestVersionMajor} dedicatedServer