about summary refs log tree commit diff
path: root/pkgs/applications/virtualization/qemu/default.nix
blob: 5b23e36af83a37b03220edc6e16cccbdc5c0bea7 (plain) (blame)
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
{ stdenv, fetchurl, pkgconfig, libtool, python, perl, texinfo, flex, bison
, gettext, makeWrapper, glib, zlib, pixman

# Optional Arguments
, SDL2 ? null, gtk ? null, gnutls ? null, cyrus_sasl ? null, libjpeg ? null
, libpng ? null, ncurses ? null, curl ? null, libcap ? null, attr ? null
, bluez ? null, libibverbs ? null, librdmacm ? null, libuuid ? null, vde2 ? null
, libaio ? null, libcap_ng ? null, spice ? null, spice_protocol ? null
, libceph ? null, libxfs ? null, nss ? null, nspr ? null, libusb ? null
, usbredir ? null, mesa ? null, lzo ? null, snappy ? null, bzip2 ? null
, libseccomp ? null, glusterfs ? null, libssh2 ? null, numactl ? null

# Audio libraries
, libpulseaudio ? null, alsaLib ? null

#, pixman ? null
#, python, zlib, glib, ncurses, perl
#, attr, libcap, vde2, alsaLib, texinfo, libuuid, flex, bison, lzo, snappy
#, libseccomp, libaio, libcap_ng, gnutls
#, makeWrapper
#, pulseSupport ? true, pulseaudio
#, sdlSupport ? true, SDL
#, vncSupport ? true, libjpeg, libpng
#, spiceSupport ? true, spice, spice_protocol, usbredir

# Extra options
, type ? ""
}:

with stdenv.lib;
let
  n = "qemu-2.3.0";

  mkFlag = trueStr: falseStr: cond: name: val:
    if cond == null then null else
      "--${if cond != false then trueStr else falseStr}${name}${if val != null && cond != false then "=${val}" else ""}";
  mkEnable = mkFlag "enable-" "disable-";
  mkWith = mkFlag "with-" "without-";
  mkOther = mkFlag "" "" true;

  shouldUsePkg = pkg: if pkg != null && stdenv.lib.any (x: x == stdenv.system) pkg.meta.platforms then pkg else null;

  optSDL2 = if type == "nix" then null else shouldUsePkg SDL2;
  optGtk = if type == "nix" then null else shouldUsePkg gtk;
  optLibcap = if type == "nix" then null else shouldUsePkg libcap;
  optAttr = if type == "nix" then null else shouldUsePkg attr;
  optGnutls = if type == "nix" then null else shouldUsePkg gnutls;
  optCyrus_sasl = if type == "nix" then null else shouldUsePkg cyrus_sasl;
  optLibjpeg = if type == "nix" then null else shouldUsePkg libjpeg;
  optLibpng = if type == "nix" then null else shouldUsePkg libpng;
  optNcurses = if type == "nix" then null else shouldUsePkg ncurses;
  optCurl = if type == "nix" then null else shouldUsePkg curl;
  optBluez = if type == "nix" then null else shouldUsePkg bluez;
  optLibibverbs = if type == "nix" then null else shouldUsePkg libibverbs;
  optLibrdmacm = if type == "nix" then null else shouldUsePkg librdmacm;
  optLibuuid = if type == "nix" then null else shouldUsePkg libuuid;
  optVde2 = if type == "nix" then null else shouldUsePkg vde2;
  optLibaio = shouldUsePkg libaio;
  optLibcap_ng = shouldUsePkg libcap_ng;
  optSpice = if type == "nix" then null else shouldUsePkg spice;
  optSpice_protocol = if type == "nix" then null else shouldUsePkg spice_protocol;
  optLibceph = if type == "nix" then null else shouldUsePkg libceph;
  optLibxfs = if type == "nix" then null else shouldUsePkg libxfs;
  optNss = if type == "nix" then null else shouldUsePkg nss;
  optNspr = if type == "nix" then null else shouldUsePkg nspr;
  optLibusb = if type == "nix" then null else shouldUsePkg libusb;
  optUsbredir = if type == "nix" then null else shouldUsePkg usbredir;
  optMesa = if type == "nix" then null else shouldUsePkg mesa;
  optLzo = if type == "nix" then null else shouldUsePkg lzo;
  optSnappy = if type == "nix" then null else shouldUsePkg snappy;
  optBzip2 = if type == "nix" then null else shouldUsePkg bzip2;
  optLibseccomp = if type == "nix" then null else shouldUsePkg libseccomp;
  optGlusterfs = if type == "nix" then null else shouldUsePkg glusterfs;
  optLibssh2 = if type == "nix" then null else shouldUsePkg libssh2;
  optNumactl = if type == "nix" then null else shouldUsePkg numactl;

  hasSDLAbi = if optSDL2 != null then true else null;

  hasVirtfs = stdenv.isLinux && optLibcap != null && optAttr != null;

  hasVnc = type != "nix";
  hasVncTls = hasVnc && optGnutls != null;
  hasVncSasl = hasVnc && optCyrus_sasl != null;
  hasVncJpeg = hasVnc && optLibjpeg != null;
  hasVncPng = hasVnc && optLibpng != null;
  hasVncWs = hasVnc && optGnutls != null;

  hasFdt = type != "nix";

  hasRdma = optLibibverbs != null && optLibrdmacm != null;

  hasLinuxAio = stdenv.isLinux && optLibaio != null;

  hasSpice = optSpice != null && optSpice_protocol != null;

  hasNss = optNss != null && optNspr != null;

  optLibpulseaudio = if type == "nix" then null else shouldUsePkg libpulseaudio;
  optAlsaLib = if type == "nix" then null else shouldUsePkg alsaLib;
  audio = concatStringsSep "," (
       optional (optSDL2 != null) "sdl"
    ++ optional (optLibpulseaudio != null) "pa"
    ++ optional (optAlsaLib != null) "alsa"
  );

  systemBinary = if stdenv.system == "x86_64-linux" then "x86_64"
    else if stdenv.system == "i686-linux" then "i386"
    else null;

  targetList = if stdenv.system == "x86_64-linux" then "x86_64-softmmu,i386-softmmu"
    else if stdenv.system == "i686-linux" then "i386-softmmu"
    else null;
in

stdenv.mkDerivation rec {
  name = "${n}${optionalString (type != null && type != "") "-${type}"}";

  src = fetchurl {
    url = "http://wiki.qemu.org/download/${n}.tar.bz2";
    sha256 = "120m53c3p28qxmfzllicjzr8syjv6v4d9rsyrgkp7gnmcgvvgfmn";
  };

  nativeBuildInputs = [ pkgconfig libtool perl texinfo flex bison gettext makeWrapper ];

  buildInputs = [
    python glib zlib pixman optSDL2 optGtk optNcurses optCurl optBluez optVde2
    optLibcap_ng optAttr optLibuuid optLibceph optLibxfs optLibusb optUsbredir
    optMesa optLzo optSnappy optBzip2 optLibseccomp optGlusterfs optLibssh2
    optNumactl optLibpulseaudio optAlsaLib
  ] ++ optionals (hasVncTls || hasVncWs) [
    optGnutls
  ] ++ optionals hasVncSasl [
    optCyrus_sasl
  ] ++ optionals hasVncJpeg [
    optLibjpeg
  ] ++ optionals hasVncPng [
    optLibpng
  ] ++ optionals hasVirtfs [
    optLibcap
  ] ++ optionals hasRdma [
    optLibibverbs optLibrdmacm
  ] ++ optionals hasLinuxAio [
    optLibaio
  ] ++ optionals hasSpice [
    optSpice optSpice_protocol
  ] ++ optionals hasNss [
    optNss optNspr
  ];

  enableParallelBuilding = true;

  configureFlags = [
    (mkOther                          "smbd"                "smbd")
    (mkOther                          "sysconfdir"          "/etc")
    (mkOther                          "localstatedir"       "/var")
    (mkEnable true                    "modules"             null)
    (mkEnable false                   "debug-tcg"           null)
    (mkEnable false                   "debug-info"          null)
    (mkEnable false                   "sparse"              null)
    (mkEnable false                   "werror"              null)
    (mkEnable (optSDL2 != null)       "sdl"                 null)
    (mkWith   hasSDLAbi               "sdlabi"              "2.0")
    (mkEnable (optGtk != null)        "gtk"                 null)
    (mkEnable hasVirtfs               "virtfs"              null)
    (mkEnable hasVnc                  "vnc"                 null)
    (mkEnable stdenv.isDarwin         "cocoa"               null)
    (mkOther                          "audio-drv-list"      audio)
    (mkEnable false                   "xen"                 null)
    (mkEnable false                   "xen-pci-passthrough" null)
    (mkEnable false                   "brlapi"              null)
    (mkEnable hasVncTls               "vnc-tls"             null)
    (mkEnable hasVncSasl              "vnc-sasl"            null)
    (mkEnable hasVncJpeg              "vnc-jpeg"            null)
    (mkEnable hasVncPng               "vnc-png"             null)
    (mkEnable hasVncWs                "vnc-ws"              null)
    (mkEnable (optNcurses != null)    "curses"              null)
    (mkEnable (optCurl != null)       "curl"                null)
    (mkEnable hasFdt                  "fdt"                 null)
    (mkEnable (optBluez != null)      "bluez"               null)
    (mkEnable stdenv.isLinux          "kvm"                 null)
    (mkEnable hasRdma                 "rdma"                null)
    (mkEnable (type != "nix")         "system"              null)
    (mkEnable (type != "kvm-only")    "user"                null)
    (mkEnable (type != "kvm-only")    "guest-base"          null)
    (mkEnable true                    "pie"                 null)
    (mkEnable (optLibuuid != null)    "uuid"                null)
    (mkEnable (optVde2 != null)       "vde"                 null)
    (mkEnable false                   "netmap"              null)  # TODO(wkennington): Add Support
    (mkEnable hasLinuxAio             "linux-aio"           null)
    (mkEnable (optLibcap_ng != null)  "cap-ng"              null)
    (mkEnable (optAttr != null)       "attr"                null)
    (mkEnable (type != "nix")         "docs"                null)
    (mkEnable stdenv.isLinux          "vhost-net"           null)
    (mkEnable hasSpice                "spice"               null)
    (mkEnable (optLibceph != null)    "rbd"                 null)
    (mkEnable false                   "libiscsi"            null)  # TODO(wkennington): Add support
    (mkEnable false                   "libnfs"              null)  # TODO(wkennington): Add support
    (mkEnable (optLibxfs != null)     "xfsctl"              null)
    (mkEnable hasNss                  "smartcard-nss"       null)
    (mkEnable (optLibusb != null)     "libusb"              null)
    (mkEnable (optUsbredir != null)   "usb-redir"           null)
    (mkEnable (optMesa != null)       "opengl"              null)
    (mkEnable (optLzo != null)        "lzo"                 null)
    (mkEnable (optSnappy != null)     "snappy"              null)
    (mkEnable (optBzip2 != null)      "bzip2"               null)
    (mkEnable true                    "guest-agent"         null)
    (mkEnable (optLibseccomp != null) "seccomp"             null)
    (mkEnable (optGlusterfs != null)  "glusterfs"           null)
    (mkEnable false                   "archipelago"         null)
    (mkEnable true                    "tpm"                 null)
    (mkEnable (optLibssh2 != null)    "libssh2"             null)
    (mkEnable (optLibuuid != null)    "vhdx"                null)
    (mkEnable (optGnutls != null)     "quorum"              null)
    (mkEnable (optNumactl != null)    "numa"                null)
  ] ++ optionals (type == "kvm-only") [
    (mkOther                          "target-list"         targetList)
  ];

  installFlags = [
    "sysconfdir=\${out}/etc"
    "qemu_confdir=\${out}/etc/qemu"
    "qemu_localstatedir=\${TMPDIR}"
  ];

  postInstall = optionalString (systemBinary != null) ''
    # Add a ‘qemu-kvm’ wrapper for compatibility/convenience.
    p="$out/bin/qemu-system-${systemBinary}"
    if [ -e "$p" ]; then
      makeWrapper "$p" $out/bin/qemu-kvm --add-flags "\$([ -e /dev/kvm ] && echo -enable-kvm)"
    fi
  '';

  meta = with stdenv.lib; {
    homepage = http://www.qemu.org/;
    description = "A generic and open source machine emulator and virtualizer";
    license = licenses.gpl2Plus;
    maintainers = with maintainers; [ viric shlevy eelco wkennington ];
    platforms = if type == "kvm-only" then platforms.linux else platforms.all;
  };
}