]> git.xonotic.org Git - xonotic/xonotic.git/blob - derivation.nix
slist: extend parsing
[xonotic/xonotic.git] / derivation.nix
1 # nix-shell -A shell
2 # ./nix-build.sh -A xonotic
3 # --argstr cc clang
4 # for it in $(./nix-build.sh -A dockerImage --no-out-link); do docker load -i $it; done
5 {
6     pkgs, lib,
7     cc ? null,
8     cmake ? pkgs.cmake_2_8,
9 }:
10 let
11     VERSION = "0.8.2";
12
13     x = {
14         # https://gitlab.com/xonotic/xonotic
15         srcs."xonotic" = localFilesMain ./.;
16         vers."xonotic" = "${VERSION}";
17
18         srcs."data/font-dejavu" = localFiles ./data/font-dejavu.pk3dir;
19         vers."data/font-dejavu" = "xonotic-${VERSION}";
20
21         srcs."data/font-nimbussansl" = localFiles ./data/font-nimbussansl.pk3dir;
22         vers."data/font-nimbussansl" = "xonotic-${VERSION}";
23
24         srcs."data/font-unifont" = localFiles ./data/font-unifont.pk3dir;
25         vers."data/font-unifont" = "xonotic-${VERSION}";
26
27         srcs."data/font-xolonium" = localFiles ./data/font-xolonium.pk3dir;
28         vers."data/font-xolonium" = "xonotic-${VERSION}";
29
30
31         # https://gitlab.com/xonotic/d0_blind_id
32         srcs."d0_blind_id" = localFiles ./d0_blind_id;
33         vers."d0_blind_id" = "xonotic-${VERSION}";
34
35
36         # https://gitlab.com/xonotic/darkplaces
37         srcs."darkplaces" = localFiles ./darkplaces;
38         vers."darkplaces" = "xonotic-${VERSION}";
39
40
41         # https://gitlab.com/xonotic/gmqcc
42         srcs."gmqcc" = localFiles ./gmqcc;
43         vers."gmqcc" = "xonotic-${VERSION}";
44
45
46         # https://gitlab.com/xonotic/netradiant
47         srcs."netradiant" = localFiles ./netradiant;
48         vers."netradiant" = "xonotic-${VERSION}";
49
50
51         # https://gitlab.com/xonotic/xonotic-data.pk3dir
52         srcs."data/xonotic-data" = localFilesCustom ./data/xonotic-data.pk3dir (name: type: type == "directory" || !(isCode name));
53         vers."data/xonotic-data" = builtins.getEnv "VERSION_data_xonotic_data_pk3dir";
54
55         srcs."data/xonotic-data/qcsrc" = localFilesCustom ./data/xonotic-data.pk3dir (name: type: type == "directory" || (isCode name));
56         vers."data/xonotic-data/qcsrc" = vers."data/xonotic-data";
57
58
59         # https://gitlab.com/xonotic/xonotic-maps.pk3dir
60         srcs."data/xonotic-maps" = localFiles ./data/xonotic-maps.pk3dir;
61         vers."data/xonotic-maps" = "${VERSION}";
62
63         # https://gitlab.com/xonotic/xonotic-music.pk3dir
64         srcs."data/xonotic-music" = localFiles ./data/xonotic-music.pk3dir;
65         vers."data/xonotic-music" = "${VERSION}";
66
67         # https://gitlab.com/xonotic/xonotic-nexcompat.pk3dir
68         srcs."data/xonotic-nexcompat" = localFiles ./data/xonotic-nexcompat.pk3dir;
69         vers."data/xonotic-nexcompat" = "${VERSION}";
70     };
71     inherit (x) srcs vers;
72
73     localFilesMain = src: let
74         project = toString ./.;
75         cleanSourceFilterMain = name: type: let
76             baseName = baseNameOf (toString name);
77             result = (cleanSourceFilter name type)
78                 && !(name == "${project}/release")
79                 && !(name == "${project}/d0_blind_id")
80                 && !(name == "${project}/daemon")
81                 && !(name == "${project}/darkplaces")
82                 && !(name == "${project}/data")
83                 && !(name == "${project}/gmqcc")
84                 && !(name == "${project}/netradiant")
85                 && !(name == "${project}/wiki" || name == "${project}/wiki.yes")
86                 && !(name == "${project}/xonstat" || name == "${project}/xonstat.yes")
87             ;
88         in result;
89     in builtins.filterSource cleanSourceFilterMain src;
90
91     isCode = name: let
92         baseName = baseNameOf (toString name);
93         result = !(false
94             || (lib.hasSuffix ".ase" baseName)
95             || (lib.hasSuffix ".dem" baseName)
96             || (lib.hasSuffix ".dpm" baseName)
97             || (lib.hasSuffix ".framegroups" baseName)
98             || (lib.hasSuffix ".iqm" baseName)
99             || (lib.hasSuffix ".jpg" baseName)
100             || (lib.hasSuffix ".lmp" baseName)
101             || (lib.hasSuffix ".md3" baseName)
102             || (lib.hasSuffix ".mdl" baseName)
103             || (lib.hasSuffix ".obj" baseName)
104             || (lib.hasSuffix ".ogg" baseName)
105             || (lib.hasSuffix ".png" baseName)
106             || (lib.hasSuffix ".shader" baseName)
107             || (lib.hasSuffix ".skin" baseName)
108             || (lib.hasSuffix ".sounds" baseName)
109             || (lib.hasSuffix ".sp2" baseName)
110             || (lib.hasSuffix ".spr" baseName)
111             || (lib.hasSuffix ".spr32" baseName)
112             || (lib.hasSuffix ".svg" baseName)
113             || (lib.hasSuffix ".tga" baseName)
114             || (lib.hasSuffix ".wav" baseName)
115             || (lib.hasSuffix ".width" baseName)
116             || (lib.hasSuffix ".zym" baseName)
117         );
118     in result;
119
120     pk3 = drv: mkDerivation {
121         name = "${drv.name}.pk3";
122         version = drv.version;
123
124         nativeBuildInputs = with pkgs; [
125             zip
126         ];
127
128         phases = [ "installPhase" ];
129         installPhase = ''
130             (cd ${drv} && zip -r ${drv.pk3args or ""} $out .)
131         '';
132     };
133
134     targets = rec {
135         font-dejavu = mkDerivation rec {
136             name = "font-dejavu-${version}";
137             version = vers."data/font-dejavu";
138
139             src = srcs."data/font-dejavu";
140
141             phases = [ "installPhase" ];
142             installPhase = ''
143                 cp -r $src $out
144             '';
145         };
146
147         font-nimbussansl = mkDerivation rec {
148             name = "font-nimbussansl-${version}";
149             version = vers."data/font-nimbussansl";
150
151             src = srcs."data/font-nimbussansl";
152
153             phases = [ "installPhase" ];
154             installPhase = ''
155                 cp -r $src $out
156             '';
157         };
158
159         font-unifont = mkDerivation rec {
160             name = "font-unifont-${version}";
161             version = vers."data/font-unifont";
162
163             src = srcs."data/font-unifont";
164
165             phases = [ "installPhase" ];
166             installPhase = ''
167                 cp -r $src $out
168             '';
169         };
170
171         font-xolonium = mkDerivation rec {
172             name = "font-xolonium-${version}";
173             version = vers."data/font-xolonium";
174
175             src = srcs."data/font-xolonium";
176
177             phases = [ "installPhase" ];
178             installPhase = ''
179                 cp -r $src $out
180             '';
181         };
182
183         d0_blind_id = mkDerivation rec {
184             name = "d0_blind_id-${version}";
185             version = vers."d0_blind_id";
186
187             src = srcs."d0_blind_id";
188
189             nativeBuildInputs = [
190                 cmake
191             ];
192
193             buildInputs = with pkgs; [
194                 openssl
195             ];
196
197             installPhase = ''
198                 mkdir -p $out/lib
199                 mkdir -p $out/include/d0_blind_id
200
201                 cp libd0_blind_id.so $out/lib
202                 (cd $src; cp d0.h d0_blind_id.h $out/include/d0_blind_id)
203
204                 cp libd0_rijndael.so $out/lib
205                 (cd $src; cp d0_rijndael.h $out/include/d0_blind_id)
206             '';
207         };
208
209         darkplaces = let
210             unwrapped = mkDerivation rec {
211                 name = "darkplaces-unwrapped-${version}";
212                 version = vers."darkplaces";
213
214                 src = srcs."darkplaces";
215
216                 nativeBuildInputs = [
217                     cmake
218                 ];
219
220                 buildInputs = with pkgs; [
221                     SDL2
222
223                     zlib
224                     libjpeg
225                 ];
226
227                 installPhase = ''
228                     mkdir -p $out/bin
229                     cp darkplaces-{dedicated,sdl} $out/bin
230                 '';
231             };
232             result = mkDerivation rec {
233                 name = "darkplaces-${version}";
234                 version = vers."darkplaces";
235
236                 buildInputs = unwrapped.buildInputs ++ runtimeInputs;
237                 runtimeInputs = with pkgs; [
238                     d0_blind_id
239
240                     freetype
241
242                     curl
243                     zlib
244
245                     libjpeg
246                     libpng
247
248                     libogg
249                     libtheora
250                     libvorbis
251                 ];
252
253                 phases = [ "installPhase" ];
254                 installPhase = ''
255                     mkdir -p $out/bin
256
257                     cp -r ${unwrapped}/bin .
258                     chmod +w bin/*
259                     cd bin
260
261                     for exe in dedicated sdl; do
262                         f=darkplaces-$exe
263                         rpath=$(patchelf --print-rpath $f)
264                         rpath=''${rpath:+$rpath:}${lib.makeLibraryPath runtimeInputs}
265                         patchelf --set-rpath $rpath $f
266                         cp $f $out/bin/xonotic-linux64-$exe
267                     done
268                 '';
269             };
270         in result;
271
272         gmqcc = mkDerivation rec {
273             name = "gmqcc-${version}";
274             version = vers."gmqcc";
275
276             src = srcs."gmqcc";
277
278             nativeBuildInputs = [
279                 cmake
280             ];
281
282             installPhase = ''
283                 mkdir -p $out/bin
284                 cp gmqcc $out/bin
285             '';
286         };
287
288         netradiant = mkDerivation rec {
289             name = "netradiant-${version}";
290             version = vers."netradiant";
291
292             src = srcs."netradiant";
293
294             nativeBuildInputs = with pkgs; [
295                 cmake
296                 git
297             ];
298
299             buildInputs = with pkgs; [
300                 pkgconfig
301                 glib
302                 pcre
303                 libxml2
304                 ncurses
305                 libjpeg
306                 libpng
307                 minizip
308
309                 mesa
310
311                 xorg.libXt
312                 xorg.libXmu
313                 xorg.libSM
314                 xorg.libICE
315                 xorg.libpthreadstubs
316                 xorg.libXdmcp
317
318                 gnome2.gtk
319                 gnome2.gtkglext
320                 gnome3.gtk
321             ];
322         };
323
324         xonotic-data = mkDerivation rec {
325             name = "xonotic-data-${version}";
326             version = vers."data/xonotic-data";
327
328             src = srcs."data/xonotic-data";
329
330             phases = [ "installPhase" ];
331             installPhase = ''
332                 mkdir $out
333                 cp -r $src/. $out
334                 chmod -R +w $out
335                 find $out -depth -type d -empty -exec rmdir {} \;
336             '';
337         };
338
339         xonotic-data-code = mkDerivation rec {
340             name = "xonotic-data-code-${version}";
341             version = vers."data/xonotic-data/qcsrc";
342
343             src = srcs."data/xonotic-data/qcsrc";
344
345             env = {
346                 QCC = "${gmqcc}/bin/gmqcc";
347                 VERSION = version;
348             };
349
350             nativeBuildInputs = with pkgs; [
351                 cmake
352                 git
353             ];
354
355             installPhase = ''
356                 mkdir $out
357                 cp -r $src/. $out
358                 chmod -R +w $out
359                 cp {menu,progs,csprogs}.{dat,lno} $out
360                 cp csprogs-${version}.{dat,lno,txt} $out/.tmp
361                 find $out -depth -type d -empty -exec rmdir {} \;
362             '';
363
364             passthru.csprogs = pkgs.runCommand "xonotic-data-csprogs-${version}" { inherit version; pk3name = "csprogs-${version}"; } ''
365                 mkdir $out
366                 cp ${xonotic-data-code}/.tmp/csprogs-${version}.{dat,lno,txt} $out
367             '';
368         };
369
370         # todo: build
371         xonotic-maps = mkDerivation rec {
372             name = "xonotic-maps-${version}";
373             version = vers."data/xonotic-maps";
374
375             src = srcs."data/xonotic-maps";
376
377             phases = [ "installPhase" ];
378             installPhase = ''
379                 mkdir $out
380                 cp -r $src/. $out
381             '';
382
383             passthru.dance = mkDerivation rec {
384                 name = "dance";
385                 version = vers."data/xonotic-maps";
386
387                 src = pkgs.fetchurl {
388                     url = http://beta.xonotic.org/autobuild-bsp/dance-full-88c416b8c11bdcecfdb889af2a2b97b4c0e2b8de-319ee7234504199da56f07ce25185f6d6cb889cd.pk3;
389                     sha256 = "1jgdg4mz56kbxcy3mwn4h5qlf3ahm1cmarp9l70fz9nfn6cnaknq";
390                 };
391
392                 phases = [ "installPhase" ];
393
394                 installPhase = ''
395                     mkdir -p $out
396                     cd $out
397                     ${pkgs.unzip}/bin/unzip $src
398                 '';
399             };
400         };
401
402         xonotic-music = mkDerivation rec {
403             name = "xonotic-music-${version}";
404             version = vers."data/xonotic-music";
405
406             src = srcs."data/xonotic-music";
407
408             phases = [ "installPhase" ];
409             installPhase = ''
410                 mkdir $out
411                 cp -r $src/. $out
412             '';
413
414             passthru.pk3args = "-0";
415         };
416
417         xonotic-nexcompat = mkDerivation rec {
418             name = "xonotic-nexcompat-${version}";
419             version = vers."data/xonotic-nexcompat";
420
421             src = srcs."data/xonotic-nexcompat";
422
423             phases = [ "installPhase" ];
424             installPhase = ''
425                 mkdir $out
426                 cp -r $src/. $out
427             '';
428         };
429
430         xonotic-keys = mkDerivation rec {
431             name = "xonotic-keys-${version}";
432             version = vers."xonotic";
433
434             src = srcs."xonotic";
435
436             phases = [ "installPhase" ];
437
438             installPhase = ''
439                 mkdir $out
440                 cp $src/*.d0pk $out
441             '';
442         };
443
444         slist = mkDerivation rec {
445             name = "slist-${version}";
446             version = "xonotic-${VERSION}";
447
448             src = "${srcs."xonotic"}/misc/infrastructure/python/slist";
449
450             buildInputs = with pkgs; [
451                 python3
452                 python3Packages.attrs
453                 (python3Packages.buildPythonApplication rec {
454                     pname = "mypy";
455                     version = "0.600";
456                     doCheck = false;
457                     src = python3Packages.fetchPypi {
458                         inherit pname version;
459                         sha256 = "1pd3kkz435wlvi9fwqbi3xag5zs59jcjqi6c9gzdjdn23friq9dw";
460                     };
461                     propagatedBuildInputs = with python3Packages; [ lxml typed-ast psutil ];
462                 })
463             ];
464             phases = [ "installPhase" ];
465             installPhase = ''
466                 mkdir $out
467                 cp -r $src/. $out
468             '';
469         };
470
471         xonotic = mkDerivation rec {
472             name = "xonotic-${version}";
473             version = vers."xonotic";
474
475             src = srcs."xonotic";
476
477             env = {
478                 XON_NO_DAEMON = "1";
479             };
480
481             passthru.paks = {
482                 inherit
483                     font-dejavu
484                     font-nimbussansl
485                     font-unifont
486                     font-xolonium
487                     xonotic-data
488                     xonotic-data-code
489                     xonotic-maps
490                     xonotic-music
491                     xonotic-nexcompat
492                 ;
493                 xonotic-data-csprogs = xonotic-data-code.passthru.csprogs;
494                 inherit (xonotic-maps)
495                     dance
496                 ;
497             };
498
499             phases = [ "installPhase" ];
500
501             installPhase = ''
502                 mkdir $out
503                 cp -r $src/. $out
504                 cp ${darkplaces}/bin/* $out
505
506                 mkdir -p $out/data
507                 ${lib.concatStringsSep "\n" (lib.mapAttrsToList (k: v:
508                     # "cp ${pk3 v} $out/data/${k}.pk3"
509                     "ln -s ${v} $out/data/${k}.pk3dir"
510                 ) passthru.paks)}
511
512                 mkdir -p $out/mapping
513                 ln -s ${netradiant} $out/mapping/${netradiant.name}
514             '';
515         };
516
517         dockerImage = let
518             main = pkgs.dockerTools.buildImage {
519                 name = "xonotic";
520                 tag = VERSION;
521                 contents = mkDerivation {
522                     name = "xonotic-init";
523                     phases = [ "installPhase" ];
524                     installPhase = ''
525                         mkdir -p $out
526                         cat > $out/init <<EOF
527                         #!${stdenv.shell}
528                         ${pkgs.coreutils}/bin/ln -s ${xonotic-keys}/* /
529
530                         ${pkgs.coreutils}/bin/ls -l /
531                         ${pkgs.coreutils}/bin/ls -l /data
532
533                         exec ${darkplaces}/bin/xonotic-linux64-dedicated "\''${@}"
534                         EOF
535                         chmod +x $out/init
536                     '';
537                 };
538                 config.Entrypoint = "/init";
539             };
540             unpackImage = { name, from, to }: pkgs.dockerTools.buildImage {
541                 name = "xonotic_${name}";
542                 tag = VERSION;
543                 contents = mkDerivation {
544                     name = "xonotic-${name}-init";
545                     phases = [ "installPhase" ];
546                     installPhase = ''
547                         mkdir -p $out
548                         cat > $out/init <<EOF
549                         #!${stdenv.shell}
550                         ${pkgs.coreutils}/bin/cp -r ${from} /data/${to}
551                         EOF
552                         chmod +x $out/init
553                     '';
554                 };
555                 config.Entrypoint = "/init";
556                 fromImage = pkgs.dockerTools.buildImage {
557                     name = "xonotic_deps";
558                     contents = mkDerivation {
559                         name = "xonotic_deps";
560                         phases = [ "installPhase" ];
561                         installPhase = ''
562                             mkdir -p $out
563                             cat > $out/init <<EOF
564                             ${stdenv.shell}
565                             ${pkgs.coreutils}
566                             EOF
567                         '';
568                     };
569                 };
570             };
571         in { main = main; }
572             // (lib.mapAttrs (k: v: unpackImage { name = k; from = pk3 v; to = "${v.pk3name or k}.pk3"; }) xonotic.paks)
573         ;
574     };
575
576     cleanSourceFilter = name: type: let
577         baseName = baseNameOf (toString name);
578         result = (lib.cleanSourceFilter name type)
579             && !(lib.hasSuffix ".nix" baseName)
580             && !(type == "directory" && baseName == ".git")
581             && !(type == "directory" && baseName == ".idea")
582             && !(type == "directory" && (lib.hasPrefix "cmake-build-" baseName))
583         ;
584     in result;
585
586     localFilesCustom = src: filter:
587         builtins.filterSource (name: type: (cleanSourceFilter name type) && (filter name type)) src
588     ;
589
590     localFiles = src: localFilesCustom src (name: type: true);
591
592     stdenv = if (cc == null) then pkgs.stdenv
593             else pkgs.overrideCC pkgs.stdenv pkgs."${cc}";
594
595     mkDerivation = {env ? {}, shellHook ? "", runtimeInputs ? [], ...}@args: stdenv.mkDerivation ({}
596         // { enableParallelBuilding = true; }
597         // (removeAttrs args ["env" "shellHook" "runtimeInputs"])
598         // env
599         // {
600             shellHook = ''
601                 ${shellHook}
602                 ${lib.concatStringsSep "\n" (lib.mapAttrsToList (n: v: "export ${n}=${v}") env)}
603                 export LD_LIBRARY_PATH=''${LD_LIBRARY_PATH:+$LD_LIBRARY_PATH:}${lib.makeLibraryPath runtimeInputs}
604             '';
605         }
606     );
607
608     shell = let inputs = (lib.mapAttrsToList (k: v: v) targets); in stdenv.mkDerivation (rec {
609         name = "xonotic-shell";
610         nativeBuildInputs = lib.unique (builtins.map (it: it.nativeBuildInputs) (builtins.filter (it: it?nativeBuildInputs) inputs));
611         buildInputs = lib.unique (builtins.map (it: it.buildInputs) (builtins.filter (it: it?buildInputs) inputs));
612         shellHook = builtins.map (it: it.shellHook) (builtins.filter (it: it?shellHook) inputs);
613     });
614 in { inherit shell; } // targets