nix: create a composed shell derivation
[xonotic/xonotic.git] / default.nix
1 # nix-shell -A shell
2 # --argstr cc clang
3 {
4     nixpkgs ? <nixpkgs>,
5     pkgs ? (import nixpkgs) {},
6     cc ? null
7 }:
8 with pkgs;
9 let
10     VERSION = "0.8.2";
11     targets = rec {
12         xonotic = mkDerivation { pki = true; dp = true; data = true; } rec {
13             name = "xonotic-${version}";
14             version = VERSION;
15
16             src = lib.sourceFilesBySuffices ./. [
17                 ".txt" ".cmake" ".in"
18                 ".c" ".cpp" ".h"
19                 ".inc" ".def"
20                 ".qc" ".qh"
21                 ".sh"
22             ];
23
24             env = {
25                 QCC = "${gmqcc}/gmqcc";
26             };
27
28             nativeBuildInputs = [
29                 cmake   # for building
30                 git     # for versioning
31                 # unzip # for downloading maps
32             ];
33
34             cmakeFlags = [
35                 "-DDOWNLOAD_MAPS=0"
36             ];
37
38             buildInputs = [
39                 openssl # for d0_blind_id
40                 SDL2    # for darkplaces
41             ];
42
43             runtimeInputs = [
44                 zlib
45                 curl
46
47                 libjpeg
48                 libpng
49
50                 freetype
51
52                 libogg
53                 libtheora
54                 libvorbis
55             ];
56
57             installPhase = ''
58                 mkdir $out
59
60                 exe=darkplaces/darkplaces
61                 rpath=$(patchelf --print-rpath $exe)
62                 rpath_firstparty=$out/d0_blind_id
63                 rpath_thirdparty=${lib.makeLibraryPath runtimeInputs}
64                 rpath=''${rpath:+$rpath:}$rpath_firstparty:$rpath_thirdparty
65                 patchelf --set-rpath $rpath $exe
66
67                 cp -r . $out
68             '';
69
70             dontPatchELF = true;
71         };
72
73         gmqcc = mkDerivation { qcc = true; } rec {
74             name = "gmqcc-${version}";
75             version = "xonotic-${VERSION}";
76
77             src = ./gmqcc;
78
79             installPhase = ''
80                 mkdir $out
81                 cp -r . $out
82             '';
83         };
84
85         netradiant = mkDerivation { radiant = true; } rec {
86             name = "netradiant-${version}";
87             version = VERSION;
88
89             src = ./netradiant;
90
91             nativeBuildInputs = [
92                 cmake   # for building
93                 git     # for versioning
94             ];
95
96             cmakeFlags = [
97                 "-DDOWNLOAD_MAPS=0"
98             ];
99
100             buildInputs = [
101                 pkgconfig
102                 glib
103                 pcre
104                 libxml2
105                 ncurses
106                 libjpeg
107                 libpng
108                 minizip
109
110                 mesa
111
112                 xorg.libXt
113                 xorg.libXmu
114                 xorg.libSM
115                 xorg.libICE
116                 xorg.libpthreadstubs
117                 xorg.libXdmcp
118
119                 gnome3.gtk
120                 gnome2.gtk
121                 gnome2.gtkglext
122             ];
123         };
124     };
125     stdenv = if (cc != null) then overrideCC pkgs.stdenv pkgs."${cc}" else pkgs.stdenv;
126     mkEnableTargets = args: {
127         XON_NO_PKI = !args?pki;
128         XON_NO_DP = !args?dp;
129         XON_NO_DATA = !args?data;
130         XON_NO_QCC = !args?qcc;
131         XON_NO_RADIANT = !args?radiant;
132     };
133     mkDerivation = targets: {env ? {}, shellHook ? "", runtimeInputs ? [], ...}@args:
134         stdenv.mkDerivation (
135             (mkEnableTargets targets)
136             // { enableParallelBuilding = true; }
137             // (removeAttrs args ["env" "shellHook" "runtimeInputs"])  # passthru
138             // env
139             // {
140                 shellHook = ''
141                     ${shellHook}
142                     ${lib.concatStringsSep "\n" (lib.mapAttrsToList (n: v: "export ${n}=${v}") env)}
143                     export LD_LIBRARY_PATH=''${LD_LIBRARY_PATH:+$LD_LIBRARY_PATH:}${lib.makeLibraryPath runtimeInputs}
144                 '';
145             }
146         );
147     shell = let inputs = (lib.mapAttrsToList (n: v: v) targets); in stdenv.mkDerivation (rec {
148         name = "xon-shell";
149         XON_NO_DAEMON = true;
150         nativeBuildInputs = builtins.map (it: it.nativeBuildInputs) inputs;
151         buildInputs = builtins.map (it: it.buildInputs) inputs;
152         shellHook = builtins.map (it: it.shellHook) (builtins.filter (it: it?shellHook) inputs);
153     });
154 in { inherit shell; } // targets