nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1{ lib, stdenv, fetchurl
2, makeWrapper
3, makeDesktopItem
4, copyDesktopItems
5, fetchFromGitHub
6, gradle
7, jdk
8, perl
9
10# for arc
11, SDL2
12, pkg-config
13, stb
14, ant
15, alsa-lib
16, alsa-plugins
17, glew
18, glew-egl
19
20# for soloud
21, libpulseaudio ? null
22, libjack2 ? null
23
24, nixosTests
25
26
27# Make the build version easily overridable.
28# Server and client build versions must match, and an empty build version means
29# any build is allowed, so this parameter acts as a simple whitelist.
30# Takes the package version and returns the build version.
31, makeBuildVersion ? (v: v)
32, enableClient ? true
33, enableServer ? true
34
35, enableWayland ? false
36}:
37
38let
39 pname = "mindustry";
40 version = "144.3";
41 buildVersion = makeBuildVersion version;
42
43 selectedGlew = if enableWayland then glew-egl else glew;
44
45 Mindustry = fetchFromGitHub {
46 owner = "Anuken";
47 repo = "Mindustry";
48 rev = "v${version}";
49 hash = "sha256-IXwrBaj0gweaaHefO/LyqEW4a3fBLfySSYPHBhRMVo8=";
50 };
51 Arc = fetchFromGitHub {
52 owner = "Anuken";
53 repo = "Arc";
54 rev = "v${version}";
55 hash = "sha256-nH/sHRWMdX6ieh2EWfD0wAn87E2ZkqZX+9zt2vKYPcE=";
56 };
57 soloud = fetchFromGitHub {
58 owner = "Anuken";
59 repo = "soloud";
60 # This is pinned in Arc's arc-core/build.gradle
61 rev = "v0.9";
62 hash = "sha256-6KlqOtA19MxeqZttNyNrMU7pKqzlNiA4rBZKp9ekanc=";
63 };
64 freetypeSource = fetchurl {
65 # This is pinned in Arc's extensions/freetype/build.gradle
66 url = "https://download.savannah.gnu.org/releases/freetype/freetype-2.10.4.tar.gz";
67 hash = "sha256-Xqt5XrsjrHcAHPtot9TVC11sdGkkewsBsslTJp9ljaw=";
68 };
69 glewSource = fetchurl {
70 # This is pinned in Arc's backends/backend-sdl/build.gradle
71 url = "https://github.com/nigels-com/glew/releases/download/glew-2.2.0/glew-2.2.0.zip";
72 hash = "sha256-qQRqkTd0OVoJXtzAsKwtgcOqzKYXh7OYOblB6b4U4NQ=";
73 };
74 SDLmingwSource = fetchurl {
75 # This is pinned in Arc's backends/backend-sdl/build.gradle
76 url = "https://www.libsdl.org/release/SDL2-devel-2.0.20-mingw.tar.gz";
77 hash = "sha256-OAlNgqhX1sYjUuXFzex0lIxbTSXFnL0pjW0jNWiXa9E=";
78 };
79
80 patches = [
81 ./0001-fix-include-path-for-SDL2-on-linux.patch
82 ];
83
84 unpackPhase = ''
85 cp -r ${Mindustry} Mindustry
86 cp -r ${Arc} Arc
87 chmod -R u+w -- Mindustry Arc
88 cp ${stb.src}/stb_image.h Arc/arc-core/csrc/
89 cp -r ${soloud} Arc/arc-core/csrc/soloud
90 chmod -R u+w -- Arc
91 '';
92
93 desktopItem = makeDesktopItem {
94 name = "Mindustry";
95 desktopName = "Mindustry";
96 exec = "mindustry";
97 icon = "mindustry";
98 };
99
100 cleanupMindustrySrc = ''
101 # Ensure the prebuilt shared objects don't accidentally get shipped
102 rm -r Arc/natives/natives-*/libs/*
103 rm -r Arc/backends/backend-*/libs/*
104
105 # Remove unbuildable iOS stuff
106 sed -i '/^project(":ios"){/,/^}/d' Mindustry/build.gradle
107 sed -i '/robo(vm|VM)/d' Mindustry/build.gradle
108 rm Mindustry/ios/build.gradle
109 '';
110
111 # fake build to pre-download deps into fixed-output derivation
112 deps = stdenv.mkDerivation {
113 pname = "${pname}-deps";
114 inherit version unpackPhase patches;
115 postPatch = cleanupMindustrySrc;
116
117 nativeBuildInputs = [ gradle perl ];
118 # Here we download dependencies for both the server and the client so
119 # we only have to specify one hash for 'deps'. Deps can be garbage
120 # collected after the build, so this is not really an issue.
121 buildPhase = ''
122 pushd Mindustry
123 export GRADLE_USER_HOME=$(mktemp -d)
124 gradle --no-daemon resolveDependencies
125 popd
126 '';
127 # perl code mavenizes pathes (com.squareup.okio/okio/1.13.0/a9283170b7305c8d92d25aff02a6ab7e45d06cbe/okio-1.13.0.jar -> com/squareup/okio/okio/1.13.0/okio-1.13.0.jar)
128 installPhase = ''
129 find $GRADLE_USER_HOME/caches/modules-2 -type f -regex '.*\.\(jar\|pom\)' \
130 | perl -pe 's#(.*/([^/]+)/([^/]+)/([^/]+)/[0-9a-f]{30,40}/([^/\s]+))$# ($x = $2) =~ tr|\.|/|; "install -Dm444 $1 \$out/$x/$3/$4/$5" #e' \
131 | sh
132 '';
133 outputHashMode = "recursive";
134 outputHash = "sha256-vZc8T7Hk1DLHYgqj8zxKUP2NPXumRxuheMk21Sh2TZY=";
135 };
136
137in
138assert lib.assertMsg (enableClient || enableServer)
139 "mindustry: at least one of 'enableClient' and 'enableServer' must be true";
140stdenv.mkDerivation rec {
141 inherit pname version unpackPhase patches;
142
143 postPatch = cleanupMindustrySrc;
144
145 buildInputs = lib.optionals enableClient [
146 SDL2
147 selectedGlew
148 alsa-lib
149 ];
150 nativeBuildInputs = [
151 pkg-config
152 gradle
153 makeWrapper
154 jdk
155 ] ++ lib.optionals enableClient [
156 ant
157 copyDesktopItems
158 ];
159
160 desktopItems = lib.optional enableClient desktopItem;
161
162 buildPhase = with lib; ''
163 export GRADLE_USER_HOME=$(mktemp -d)
164
165 # point to offline repo
166 sed -ie "1ipluginManagement { repositories { maven { url '${deps}' } } }; " Mindustry/settings.gradle
167 sed -ie "s#mavenLocal()#mavenLocal(); maven { url '${deps}' }#g" Mindustry/build.gradle
168 sed -ie "s#mavenCentral()#mavenCentral(); maven { url '${deps}' }#g" Arc/build.gradle
169 sed -ie "s#wget.*freetype.* -O #cp ${freetypeSource} #" Arc/extensions/freetype/build.gradle
170 sed -ie "/curl.*glew/{;s#curl -o #cp ${glewSource} #;s# -L http.*\.zip##;}" Arc/backends/backend-sdl/build.gradle
171 sed -ie "/curl.*sdlmingw/{;s#curl -o #cp ${SDLmingwSource} #;s# -L http.*\.tar.gz##;}" Arc/backends/backend-sdl/build.gradle
172
173 pushd Mindustry
174 '' + optionalString enableClient ''
175
176 pushd ../Arc
177 gradle --offline --no-daemon jnigenBuild -Pbuildversion=${buildVersion}
178 gradle --offline --no-daemon jnigenJarNativesDesktop -Pbuildversion=${buildVersion}
179 glewlib=${lib.getLib selectedGlew}/lib/libGLEW.so
180 sdllib=${lib.getLib SDL2}/lib/libSDL2.so
181 patchelf backends/backend-sdl/libs/linux64/libsdl-arc*.so \
182 --add-needed $glewlib \
183 --add-needed $sdllib
184 # Put the freshly-built libraries where the pre-built libraries used to be:
185 cp arc-core/libs/*/* natives/natives-desktop/libs/
186 cp extensions/freetype/libs/*/* natives/natives-freetype-desktop/libs/
187 popd
188
189 gradle --offline --no-daemon desktop:dist -Pbuildversion=${buildVersion}
190 '' + optionalString enableServer ''
191 gradle --offline --no-daemon server:dist -Pbuildversion=${buildVersion}
192 '';
193
194 installPhase = with lib; let
195 installClient = ''
196 install -Dm644 desktop/build/libs/Mindustry.jar $out/share/mindustry.jar
197 mkdir -p $out/bin
198 makeWrapper ${jdk}/bin/java $out/bin/mindustry \
199 --add-flags "-jar $out/share/mindustry.jar" \
200 --suffix LD_LIBRARY_PATH : ${lib.makeLibraryPath [libpulseaudio alsa-lib libjack2]} \
201 --set ALSA_PLUGIN_DIR ${alsa-plugins}/lib/alsa-lib/'' + optionalString enableWayland '' \
202 --set SDL_VIDEODRIVER wayland \
203 --set SDL_VIDEO_WAYLAND_WMCLASS Mindustry
204 '' + ''
205
206 # Retain runtime depends to prevent them from being cleaned up.
207 # Since a jar is a compressed archive, nix can't figure out that the dependency is actually in there,
208 # and will assume that it's not actually needed.
209 # This can cause issues.
210 # See https://github.com/NixOS/nixpkgs/issues/109798.
211 echo "# Retained runtime dependencies: " >> $out/bin/mindustry
212 for dep in ${SDL2.out} ${alsa-lib.out} ${selectedGlew.out}; do
213 echo "# $dep" >> $out/bin/mindustry
214 done
215
216 install -Dm644 core/assets/icons/icon_64.png $out/share/icons/hicolor/64x64/apps/mindustry.png
217 '';
218 installServer = ''
219 install -Dm644 server/build/libs/server-release.jar $out/share/mindustry-server.jar
220 mkdir -p $out/bin
221 makeWrapper ${jdk}/bin/java $out/bin/mindustry-server \
222 --add-flags "-jar $out/share/mindustry-server.jar"
223 '';
224 in ''
225 runHook preInstall
226 '' + optionalString enableClient installClient
227 + optionalString enableServer installServer
228 + ''
229 runHook postInstall
230 '';
231
232 passthru.tests = {
233 nixosTest = nixosTests.mindustry;
234 };
235
236 meta = with lib; {
237 homepage = "https://mindustrygame.github.io/";
238 downloadPage = "https://github.com/Anuken/Mindustry/releases";
239 description = "A sandbox tower defense game";
240 sourceProvenance = with sourceTypes; [
241 fromSource
242 binaryBytecode # deps
243 ];
244 license = licenses.gpl3Plus;
245 maintainers = with maintainers; [ chkno fgaz thekostins ];
246 platforms = platforms.x86_64;
247 # Hash mismatch on darwin:
248 # https://github.com/NixOS/nixpkgs/pull/105590#issuecomment-737120293
249 broken = stdenv.isDarwin;
250 };
251}