lol
1config:
2{ lib, stdenv, cmake, pkg-config, which
3
4# Xen
5, bison, bzip2, checkpolicy, dev86, figlet, flex, gettext, glib
6, acpica-tools, libaio, libiconv, libuuid, ncurses, openssl, perl
7, python2Packages
8# python2Packages.python
9, xz, yajl, zlib
10
11# Xen Optional
12, ocamlPackages
13
14# Scripts
15, coreutils, gawk, gnused, gnugrep, diffutils, multipath-tools
16, iproute2, inetutils, iptables, bridge-utils, openvswitch, nbd, drbd
17, lvm2, util-linux, procps, systemd
18
19# Documentation
20# python2Packages.markdown
21, transfig, ghostscript, texinfo, pandoc
22
23, binutils-unwrapped
24
25, ...} @ args:
26
27with lib;
28
29let
30 #TODO: fix paths instead
31 scriptEnvPath = concatMapStringsSep ":" (x: "${x}/bin") [
32 which perl
33 coreutils gawk gnused gnugrep diffutils util-linux multipath-tools
34 iproute2 inetutils iptables bridge-utils openvswitch nbd drbd
35 ];
36
37 withXenfiles = f: concatStringsSep "\n" (mapAttrsToList f config.xenfiles);
38
39 withTools = a: f: withXenfiles (name: x: optionalString (hasAttr a x) ''
40 echo "processing ${name}"
41 __do() {
42 cd "tools/${name}"
43 ${f name x}
44 }
45 ( __do )
46 '');
47
48 # We don't want to use the wrapped version, because this version of ld is
49 # only used for linking the Xen EFI binary, and the build process really
50 # needs control over the LDFLAGS used
51 efiBinutils = binutils-unwrapped.overrideAttrs (oldAttrs: {
52 name = "efi-binutils";
53 configureFlags = oldAttrs.configureFlags ++ [
54 "--enable-targets=x86_64-pep"
55 ];
56 doInstallCheck = false; # We get a spurious failure otherwise, due to host/target mis-match
57 });
58in
59
60stdenv.mkDerivation (rec {
61 inherit (config) version;
62
63 name = "xen-${version}";
64
65 dontUseCmakeConfigure = true;
66
67 hardeningDisable = [ "stackprotector" "fortify" "pic" ];
68
69 nativeBuildInputs = [ pkg-config ];
70 buildInputs = [
71 cmake which
72
73 # Xen
74 bison bzip2 checkpolicy dev86 figlet flex gettext glib acpica-tools libaio
75 libiconv libuuid ncurses openssl perl python2Packages.python xz yajl zlib
76
77 # oxenstored
78 ocamlPackages.findlib ocamlPackages.ocaml systemd
79
80 # Python fixes
81 python2Packages.wrapPython
82
83 # Documentation
84 python2Packages.markdown transfig ghostscript texinfo pandoc
85
86 # Others
87 ] ++ (concatMap (x: x.buildInputs or []) (attrValues config.xenfiles))
88 ++ (config.buildInputs or []);
89
90 prePatch = ''
91 ### Generic fixes
92
93 # Xen's stubdoms, tools and firmwares need various sources that
94 # are usually fetched at build time using wget and git. We can't
95 # have that, so we prefetch them in nix-expression and setup
96 # fake wget and git for debugging purposes.
97
98 mkdir fake-bin
99
100 # Fake git: just print what it wants and die
101 cat > fake-bin/wget << EOF
102 #!${stdenv.shell} -e
103 echo ===== FAKE WGET: Not fetching \$*
104 [ -e \$3 ]
105 EOF
106
107 # Fake git: just print what it wants and die
108 cat > fake-bin/git << EOF
109 #!${stdenv.shell}
110 echo ===== FAKE GIT: Not cloning \$*
111 [ -e \$3 ]
112 EOF
113
114 chmod +x fake-bin/*
115 export PATH=$PATH:$PWD/fake-bin
116
117 # Remove in-tree qemu stuff in case we build from a tar-ball
118 rm -rf tools/qemu-xen tools/qemu-xen-traditional
119
120 # Fix shebangs, mainly for build-scipts
121 # We want to do this before getting prefetched stuff to speed things up
122 # (prefetched stuff has lots of files)
123 find . -type f | xargs sed -i 's@/usr/bin/\(python\|perl\)@/usr/bin/env \1@g'
124 find . -type f -not -path "./tools/hotplug/Linux/xendomains.in" \
125 | xargs sed -i 's@/bin/bash@${stdenv.shell}@g'
126
127 # Get prefetched stuff
128 ${withXenfiles (name: x: ''
129 echo "${x.src} -> tools/${name}"
130 cp -r ${x.src} tools/${name}
131 chmod -R +w tools/${name}
132 '')}
133 '';
134
135 patches = [
136 ./0000-fix-ipxe-src.patch
137 ./0000-fix-install-python.patch
138 ./0004-makefile-use-efi-ld.patch
139 ./0005-makefile-fix-efi-mountdir-use.patch
140 ] ++ (config.patches or []);
141
142 postPatch = ''
143 ### Hacks
144
145 # Work around a bug in our GCC wrapper: `gcc -MF foo -v' doesn't
146 # print the GCC version number properly.
147 substituteInPlace xen/Makefile \
148 --replace '$(CC) $(CFLAGS) -v' '$(CC) -v'
149
150 # Hack to get `gcc -m32' to work without having 32-bit Glibc headers.
151 mkdir -p tools/include/gnu
152 touch tools/include/gnu/stubs-32.h
153
154 ### Fixing everything else
155
156 substituteInPlace tools/libfsimage/common/fsimage_plugin.c \
157 --replace /usr $out
158
159 substituteInPlace tools/blktap2/lvm/lvm-util.c \
160 --replace /usr/sbin/vgs ${lvm2}/bin/vgs \
161 --replace /usr/sbin/lvs ${lvm2}/bin/lvs
162
163 substituteInPlace tools/misc/xenpvnetboot \
164 --replace /usr/sbin/mount ${util-linux}/bin/mount \
165 --replace /usr/sbin/umount ${util-linux}/bin/umount
166
167 substituteInPlace tools/xenmon/xenmon.py \
168 --replace /usr/bin/pkill ${procps}/bin/pkill
169
170 substituteInPlace tools/xenstat/Makefile \
171 --replace /usr/include/curses.h ${ncurses.dev}/include/curses.h
172
173 ${optionalString (builtins.compareVersions config.version "4.8" >= 0) ''
174 substituteInPlace tools/hotplug/Linux/launch-xenstore.in \
175 --replace /bin/mkdir mkdir
176 ''}
177
178 ${optionalString (builtins.compareVersions config.version "4.6" < 0) ''
179 # TODO: use this as a template and support our own if-up scripts instead?
180 substituteInPlace tools/hotplug/Linux/xen-backend.rules.in \
181 --replace "@XEN_SCRIPT_DIR@" $out/etc/xen/scripts
182
183 # blktap is not provided by xen, but by xapi
184 sed -i '/blktap/d' tools/hotplug/Linux/xen-backend.rules.in
185 ''}
186
187 ${withTools "patches" (name: x: ''
188 ${concatMapStringsSep "\n" (p: ''
189 echo "# Patching with ${p}"
190 patch -p1 < ${p}
191 '') x.patches}
192 '')}
193
194 ${withTools "postPatch" (name: x: x.postPatch)}
195
196 ${config.postPatch or ""}
197 '';
198
199 postConfigure = ''
200 substituteInPlace tools/hotplug/Linux/xendomains \
201 --replace /bin/ls ls
202 '';
203
204 EFI_LD = "${efiBinutils}/bin/ld";
205 EFI_VENDOR = "nixos";
206
207 # TODO: Flask needs more testing before enabling it by default.
208 #makeFlags = [ "XSM_ENABLE=y" "FLASK_ENABLE=y" "PREFIX=$(out)" "CONFIG_DIR=/etc" "XEN_EXTFILES_URL=\\$(XEN_ROOT)/xen_ext_files" ];
209 makeFlags = [ "PREFIX=$(out) CONFIG_DIR=/etc" "XEN_SCRIPT_DIR=/etc/xen/scripts" ]
210 ++ (config.makeFlags or []);
211
212 buildFlags = [ "xen" "tools" ];
213
214 postBuild = ''
215 make -C docs man-pages
216
217 ${withTools "buildPhase" (name: x: x.buildPhase)}
218 '';
219
220 installPhase = ''
221 mkdir -p $out $out/share $out/share/man
222 cp -prvd dist/install/nix/store/*/* $out/
223 cp -prvd dist/install/boot $out/boot
224 cp -prvd dist/install/etc $out
225 cp -dR docs/man1 docs/man5 $out/share/man/
226
227 ${withTools "installPhase" (name: x: x.installPhase)}
228
229 # Hack
230 substituteInPlace $out/etc/xen/scripts/hotplugpath.sh \
231 --replace SBINDIR=\"$out/sbin\" SBINDIR=\"$out/bin\"
232
233 wrapPythonPrograms
234 # We also need to wrap pygrub, which lies in lib
235 wrapPythonProgramsIn "$out/lib" "$out $pythonPath"
236
237 shopt -s extglob
238 for i in $out/etc/xen/scripts/!(*.sh); do
239 sed -i "2s@^@export PATH=$out/bin:${scriptEnvPath}\n@" $i
240 done
241 '';
242
243 enableParallelBuilding = true;
244
245 # TODO(@oxij): Stop referencing args here
246 meta = {
247 homepage = "http://www.xen.org/";
248 description = "Xen hypervisor and related components"
249 + optionalString (args ? meta && args.meta ? description)
250 " (${args.meta.description})";
251 longDescription = (args.meta.longDescription or "")
252 + "\nIncludes:\n"
253 + withXenfiles (name: x: "* ${name}: ${x.meta.description or "(No description)"}.");
254 platforms = [ "x86_64-linux" ];
255 maintainers = with lib.maintainers; [ eelco tstrobel oxij ];
256 license = lib.licenses.gpl2;
257 } // (config.meta or {});
258} // removeAttrs config [ "xenfiles" "buildInputs" "patches" "postPatch" "meta" ])