at master 464 lines 15 kB view raw
1{ 2 lib, 3 stdenv, 4 fetchurl, 5 fetchpatch, 6 python3Packages, 7 zlib, 8 pkg-config, 9 glib, 10 buildPackages, 11 pixman, 12 vde2, 13 alsa-lib, 14 flex, 15 bison, 16 lzo, 17 snappy, 18 libaio, 19 libtasn1, 20 gnutls, 21 curl, 22 dtc, 23 ninja, 24 meson, 25 perl, 26 sigtool, 27 makeWrapper, 28 removeReferencesTo, 29 attr, 30 libcap, 31 libcap_ng, 32 socat, 33 libslirp, 34 libcbor, 35 apple-sdk_13, 36 darwinMinVersionHook, 37 guestAgentSupport ? 38 (with stdenv.hostPlatform; isLinux || isNetBSD || isOpenBSD || isSunOS || isWindows) && !minimal, 39 numaSupport ? stdenv.hostPlatform.isLinux && !stdenv.hostPlatform.isAarch32 && !minimal, 40 numactl, 41 seccompSupport ? stdenv.hostPlatform.isLinux && !minimal, 42 libseccomp, 43 alsaSupport ? lib.hasSuffix "linux" stdenv.hostPlatform.system && !nixosTestRunner && !minimal, 44 pulseSupport ? !stdenv.hostPlatform.isDarwin && !nixosTestRunner && !minimal, 45 libpulseaudio, 46 pipewireSupport ? !stdenv.hostPlatform.isDarwin && !nixosTestRunner && !minimal, 47 pipewire, 48 sdlSupport ? !stdenv.hostPlatform.isDarwin && !nixosTestRunner && !minimal, 49 SDL2, 50 SDL2_image, 51 jackSupport ? !stdenv.hostPlatform.isDarwin && !nixosTestRunner && !minimal, 52 libjack2, 53 gtkSupport ? !stdenv.hostPlatform.isDarwin && !xenSupport && !nixosTestRunner && !minimal, 54 gtk3, 55 gettext, 56 vte, 57 wrapGAppsHook3, 58 vncSupport ? !nixosTestRunner && !minimal, 59 libjpeg, 60 libpng, 61 smartcardSupport ? !nixosTestRunner && !minimal, 62 libcacard, 63 spiceSupport ? true && !nixosTestRunner && !minimal, 64 spice, 65 spice-protocol, 66 ncursesSupport ? !nixosTestRunner && !minimal, 67 ncurses, 68 usbredirSupport ? spiceSupport, 69 usbredir, 70 xenSupport ? false, 71 xen, 72 cephSupport ? false, 73 ceph, 74 glusterfsSupport ? false, 75 glusterfs, 76 libuuid, 77 openGLSupport ? sdlSupport, 78 libgbm, 79 libepoxy, 80 libdrm, 81 rutabagaSupport ? 82 openGLSupport && !minimal && lib.meta.availableOn stdenv.hostPlatform rutabaga_gfx, 83 rutabaga_gfx, 84 virglSupport ? openGLSupport, 85 virglrenderer, 86 libiscsiSupport ? !minimal, 87 libiscsi, 88 smbdSupport ? false, 89 samba, 90 tpmSupport ? !minimal, 91 uringSupport ? stdenv.hostPlatform.isLinux && !userOnly, 92 liburing, 93 canokeySupport ? !minimal, 94 canokey-qemu, 95 capstoneSupport ? !minimal, 96 capstone, 97 valgrindSupport ? false, 98 valgrind-light, 99 pluginsSupport ? !stdenv.hostPlatform.isStatic, 100 enableDocs ? !minimal || toolsOnly, 101 enableTools ? !minimal || toolsOnly, 102 enableBlobs ? !minimal || toolsOnly, 103 hostCpuOnly ? false, 104 hostCpuTargets ? ( 105 if toolsOnly then 106 [ ] 107 else if xenSupport then 108 [ "i386-softmmu" ] 109 else if hostCpuOnly then 110 ( 111 lib.optional stdenv.hostPlatform.isx86_64 "i386-softmmu" 112 ++ [ "${stdenv.hostPlatform.qemuArch}-softmmu" ] 113 ) 114 else 115 null 116 ), 117 nixosTestRunner ? false, 118 toolsOnly ? false, 119 userOnly ? false, 120 minimal ? toolsOnly || userOnly, 121 gitUpdater, 122 qemu-utils, # for tests attribute 123}: 124 125assert lib.assertMsg ( 126 xenSupport -> hostCpuTargets == [ "i386-softmmu" ] 127) "Xen should not use any other QEMU architecture other than i386."; 128 129let 130 hexagonSupport = hostCpuTargets == null || lib.elem "hexagon" hostCpuTargets; 131 132 # needed in buildInputs and depsBuildBuild 133 # check log for warnings eg: `warning: 'hv_vm_config_get_max_ipa_size' is only available on macOS 13.0` 134 # to indicate if min version needs to get bumped. 135 darwinSDK = [ 136 apple-sdk_13 137 (darwinMinVersionHook "13") 138 ]; 139in 140 141stdenv.mkDerivation (finalAttrs: { 142 pname = 143 "qemu" 144 + lib.optionalString xenSupport "-xen" 145 + lib.optionalString hostCpuOnly "-host-cpu-only" 146 + lib.optionalString nixosTestRunner "-for-vm-tests" 147 + lib.optionalString toolsOnly "-utils" 148 + lib.optionalString userOnly "-user"; 149 version = "10.1.0"; 150 151 src = fetchurl { 152 url = "https://download.qemu.org/qemu-${finalAttrs.version}.tar.xz"; 153 hash = "sha256-4FFzSbUMpz6+wvqFsGBQ1cRjymXHOIM72PwfFfGAvlE="; 154 }; 155 156 depsBuildBuild = [ 157 buildPackages.stdenv.cc 158 ] 159 ++ lib.optionals stdenv.buildPlatform.isDarwin darwinSDK 160 ++ lib.optionals hexagonSupport [ pkg-config ]; 161 162 nativeBuildInputs = [ 163 makeWrapper 164 removeReferencesTo 165 pkg-config 166 flex 167 bison 168 meson 169 ninja 170 perl 171 172 # For python changes other than simple package additions, ping @dramforever for review. 173 # Don't change `python3Packages` to `python3.pkgs.*`, breaks cross-compilation. 174 python3Packages.distlib 175 # Hooks from the python package are needed to add `$pythonPath` so 176 # `python/scripts/mkvenv.py` can detect `meson` otherwise the vendored meson without patches will be used. 177 python3Packages.python 178 ] 179 ++ lib.optionals gtkSupport [ wrapGAppsHook3 ] 180 ++ lib.optionals enableDocs [ 181 python3Packages.sphinx 182 python3Packages.sphinx-rtd-theme 183 ] 184 ++ lib.optionals hexagonSupport [ glib ] 185 ++ lib.optionals stdenv.hostPlatform.isDarwin [ 186 sigtool 187 ] 188 ++ lib.optionals (!userOnly) [ dtc ]; 189 190 # gnutls is required for crypto support (luks) in qemu-img 191 buildInputs = [ 192 glib 193 gnutls 194 zlib 195 ] 196 ++ lib.optionals (!minimal) [ 197 dtc 198 pixman 199 vde2 200 lzo 201 snappy 202 libtasn1 203 libslirp 204 libcbor 205 ] 206 ++ lib.optionals (!userOnly) [ curl ] 207 ++ lib.optionals ncursesSupport [ ncurses ] 208 ++ lib.optionals stdenv.hostPlatform.isDarwin darwinSDK 209 ++ lib.optionals seccompSupport [ libseccomp ] 210 ++ lib.optionals numaSupport [ numactl ] 211 ++ lib.optionals alsaSupport [ alsa-lib ] 212 ++ lib.optionals pulseSupport [ libpulseaudio ] 213 ++ lib.optionals pipewireSupport [ pipewire ] 214 ++ lib.optionals sdlSupport [ 215 SDL2 216 SDL2_image 217 ] 218 ++ lib.optionals jackSupport [ libjack2 ] 219 ++ lib.optionals gtkSupport [ 220 gtk3 221 gettext 222 vte 223 ] 224 ++ lib.optionals vncSupport [ 225 libjpeg 226 libpng 227 ] 228 ++ lib.optionals smartcardSupport [ libcacard ] 229 ++ lib.optionals spiceSupport [ 230 spice-protocol 231 spice 232 ] 233 ++ lib.optionals usbredirSupport [ usbredir ] 234 ++ lib.optionals (stdenv.hostPlatform.isLinux && !userOnly) [ 235 libcap_ng 236 libcap 237 attr 238 libaio 239 ] 240 ++ lib.optionals xenSupport [ xen ] 241 ++ lib.optionals cephSupport [ ceph ] 242 ++ lib.optionals glusterfsSupport [ 243 glusterfs 244 libuuid 245 ] 246 ++ lib.optionals openGLSupport [ 247 libgbm 248 libepoxy 249 libdrm 250 ] 251 ++ lib.optionals rutabagaSupport [ rutabaga_gfx ] 252 ++ lib.optionals virglSupport [ virglrenderer ] 253 ++ lib.optionals libiscsiSupport [ libiscsi ] 254 ++ lib.optionals smbdSupport [ samba ] 255 ++ lib.optionals uringSupport [ liburing ] 256 ++ lib.optionals canokeySupport [ canokey-qemu ] 257 ++ lib.optionals capstoneSupport [ capstone ] 258 ++ lib.optionals valgrindSupport [ valgrind-light ]; 259 260 dontUseMesonConfigure = true; # meson's configurePhase isn't compatible with qemu build 261 dontAddStaticConfigureFlags = true; 262 263 outputs = [ "out" ] ++ lib.optional enableDocs "doc" ++ lib.optional guestAgentSupport "ga"; 264 # On aarch64-linux we would shoot over the Hydra's 2G output limit. 265 separateDebugInfo = !(stdenv.hostPlatform.isAarch64 && stdenv.hostPlatform.isLinux); 266 267 patches = [ 268 ./fix-qemu-ga.patch 269 270 # On macOS, QEMU uses `Rez(1)` and `SetFile(1)` to attach its icon 271 # to the binary. Unfortunately, those commands are proprietary, 272 # deprecated since Xcode 6, and operate on resource forks, which 273 # these days are stored in extended attributes, which aren’t 274 # supported in the Nix store. So we patch out the calls. 275 ./skip-macos-icon.patch 276 277 # Workaround for upstream issue with nested virtualisation: https://gitlab.com/qemu-project/qemu/-/issues/1008 278 (fetchpatch { 279 url = "https://gitlab.com/qemu-project/qemu/-/commit/3e4546d5bd38a1e98d4bd2de48631abf0398a3a2.diff"; 280 sha256 = "sha256-oC+bRjEHixv1QEFO9XAm4HHOwoiT+NkhknKGPydnZ5E="; 281 revert = true; 282 }) 283 ] 284 ++ lib.optional nixosTestRunner ./force-uid0-on-9p.patch; 285 286 postPatch = '' 287 # Otherwise tries to ensure /var/run exists. 288 sed -i "/install_emptydir(get_option('localstatedir') \/ 'run')/d" \ 289 qga/meson.build 290 ''; 291 292 preConfigure = '' 293 unset CPP # intereferes with dependency calculation 294 # this script isn't marked as executable b/c it's indirectly used by meson. Needed to patch its shebang 295 chmod +x ./scripts/shaderinclude.py 296 patchShebangs . 297 # avoid conflicts with libc++ include for <version> 298 mv VERSION QEMU_VERSION 299 substituteInPlace configure \ 300 --replace-fail '$source_path/VERSION' '$source_path/QEMU_VERSION' 301 substituteInPlace meson.build \ 302 --replace-fail "'VERSION'" "'QEMU_VERSION'" 303 substituteInPlace docs/conf.py \ 304 --replace-fail "'../VERSION'" "'../QEMU_VERSION'" 305 substituteInPlace python/qemu/machine/machine.py \ 306 --replace-fail /var/tmp "$TMPDIR" 307 ''; 308 309 configureFlags = [ 310 "--disable-strip" # We'll strip ourselves after separating debug info. 311 "--enable-gnutls" # auto detection only works when building with --enable-system 312 (lib.enableFeature enableDocs "docs") 313 (lib.enableFeature enableTools "tools") 314 "--localstatedir=/var" 315 "--sysconfdir=/etc" 316 "--cross-prefix=${stdenv.cc.targetPrefix}" 317 (lib.enableFeature guestAgentSupport "guest-agent") 318 ] 319 ++ lib.optional numaSupport "--enable-numa" 320 ++ lib.optional seccompSupport "--enable-seccomp" 321 ++ lib.optional smartcardSupport "--enable-smartcard" 322 ++ lib.optional spiceSupport "--enable-spice" 323 ++ lib.optional usbredirSupport "--enable-usb-redir" 324 ++ lib.optional (hostCpuTargets != null) "--target-list=${lib.concatStringsSep "," hostCpuTargets}" 325 ++ lib.optionals stdenv.hostPlatform.isDarwin [ 326 "--enable-cocoa" 327 "--enable-hvf" 328 ] 329 ++ lib.optional (stdenv.hostPlatform.isLinux && !userOnly) "--enable-linux-aio" 330 ++ lib.optional gtkSupport "--enable-gtk" 331 ++ lib.optional xenSupport "--enable-xen" 332 ++ lib.optional cephSupport "--enable-rbd" 333 ++ lib.optional glusterfsSupport "--enable-glusterfs" 334 ++ lib.optional openGLSupport "--enable-opengl" 335 ++ lib.optional virglSupport "--enable-virglrenderer" 336 ++ lib.optional tpmSupport "--enable-tpm" 337 ++ lib.optional libiscsiSupport "--enable-libiscsi" 338 ++ lib.optional smbdSupport "--smbd=${samba}/bin/smbd" 339 ++ lib.optional uringSupport "--enable-linux-io-uring" 340 ++ lib.optional canokeySupport "--enable-canokey" 341 ++ lib.optional capstoneSupport "--enable-capstone" 342 ++ lib.optional (!pluginsSupport) "--disable-plugins" 343 ++ lib.optional (!enableBlobs) "--disable-install-blobs" 344 ++ lib.optional userOnly "--disable-system" 345 ++ lib.optional stdenv.hostPlatform.isStatic "--static"; 346 347 dontWrapGApps = true; 348 349 # QEMU attaches entitlements with codesign and strip removes those, 350 # voiding the entitlements and making it non-operational. 351 # The alternative is to re-sign with entitlements after stripping: 352 # * https://github.com/qemu/qemu/blob/v6.1.0/scripts/entitlement.sh#L25 353 dontStrip = stdenv.hostPlatform.isDarwin; 354 355 postFixup = '' 356 # the .desktop is both invalid and pointless 357 rm -f $out/share/applications/qemu.desktop 358 '' 359 + lib.optionalString guestAgentSupport '' 360 # move qemu-ga (guest agent) to separate output 361 mkdir -p $ga/bin 362 mv $out/bin/qemu-ga $ga/bin/ 363 ln -s $ga/bin/qemu-ga $out/bin 364 remove-references-to -t $out $ga/bin/qemu-ga 365 '' 366 + lib.optionalString gtkSupport '' 367 # wrap GTK Binaries 368 for f in $out/bin/qemu-system-*; do 369 wrapGApp $f 370 done 371 '' 372 + lib.optionalString stdenv.hostPlatform.isStatic '' 373 # HACK: Otherwise the result will have the entire buildInputs closure 374 # injected by the pkgsStatic stdenv 375 # <https://github.com/NixOS/nixpkgs/issues/83667> 376 rm -f $out/nix-support/propagated-build-inputs 377 ''; 378 preBuild = "cd build"; 379 380 # tests can still timeout on slower systems 381 doCheck = false; 382 nativeCheckInputs = [ socat ]; 383 preCheck = '' 384 # time limits are a little meagre for a build machine that's 385 # potentially under load. 386 substituteInPlace ../tests/unit/meson.build \ 387 --replace 'timeout: slow_tests' 'timeout: 50 * slow_tests' 388 substituteInPlace ../tests/qtest/meson.build \ 389 --replace 'timeout: slow_qtests' 'timeout: 50 * slow_qtests' 390 substituteInPlace ../tests/fp/meson.build \ 391 --replace 'timeout: 90)' 'timeout: 300)' 392 393 # point tests towards correct binaries 394 substituteInPlace ../tests/unit/test-qga.c \ 395 --replace '/bin/bash' "$(type -P bash)" \ 396 --replace '/bin/echo' "$(type -P echo)" 397 substituteInPlace ../tests/unit/test-io-channel-command.c \ 398 --replace '/bin/socat' "$(type -P socat)" 399 400 # combined with a long package name, some temp socket paths 401 # can end up exceeding max socket name len 402 substituteInPlace ../tests/qtest/bios-tables-test.c \ 403 --replace 'qemu-test_acpi_%s_tcg_%s' '%s_%s' 404 405 # get-fsinfo attempts to access block devices, disallowed by sandbox 406 sed -i -e '/\/qga\/get-fsinfo/d' -e '/\/qga\/blacklist/d' \ 407 ../tests/unit/test-qga.c 408 409 # xattrs are not allowed in the sandbox 410 substituteInPlace ../tests/qtest/virtio-9p-test.c \ 411 --replace-fail mapped-xattr mapped-file 412 '' 413 + lib.optionalString stdenv.hostPlatform.isDarwin '' 414 # skip test that stalls on darwin, perhaps due to subtle differences 415 # in fifo behaviour 416 substituteInPlace ../tests/unit/meson.build \ 417 --replace "'test-io-channel-command'" "#'test-io-channel-command'" 418 ''; 419 420 # Add a ‘qemu-kvm’ wrapper for compatibility/convenience. 421 postInstall = lib.optionalString (!minimal && !xenSupport) '' 422 ln -s $out/bin/qemu-system-${stdenv.hostPlatform.qemuArch} $out/bin/qemu-kvm 423 ''; 424 425 passthru = { 426 qemu-system-i386 = "bin/qemu-system-i386"; 427 tests = lib.optionalAttrs (!toolsOnly) { 428 qemu-tests = finalAttrs.finalPackage.overrideAttrs (_: { 429 doCheck = true; 430 }); 431 qemu-utils-builds = qemu-utils; 432 }; 433 updateScript = gitUpdater { 434 # No nicer place to find latest release. 435 url = "https://gitlab.com/qemu-project/qemu.git"; 436 rev-prefix = "v"; 437 ignoredVersions = "(alpha|beta|rc).*"; 438 }; 439 }; 440 441 # Builds in ~3h with 2 cores, and ~20m with a big-parallel builder. 442 requiredSystemFeatures = [ "big-parallel" ]; 443 444 meta = 445 with lib; 446 { 447 homepage = "https://www.qemu.org/"; 448 description = "Generic and open source machine emulator and virtualizer"; 449 license = licenses.gpl2Plus; 450 maintainers = with maintainers; [ qyliss ]; 451 teams = lib.optionals xenSupport xen.meta.teams; 452 platforms = platforms.unix; 453 } 454 # toolsOnly: Does not have qemu-kvm and there's no main support tool 455 # userOnly: There's one qemu-<arch> for every architecture 456 // lib.optionalAttrs (!toolsOnly && !userOnly) { 457 mainProgram = "qemu-kvm"; 458 } 459 # userOnly: https://qemu.readthedocs.io/en/v9.0.2/user/main.html 460 // lib.optionalAttrs userOnly { 461 platforms = with platforms; (linux ++ freebsd ++ openbsd ++ netbsd); 462 description = "QEMU User space emulator - launch executables compiled for one CPU on another CPU"; 463 }; 464})