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