bottom: add gpu recognition, new apple sdk, refactor (#360568)
[NixPkgs.git] / pkgs / applications / virtualization / virtualbox / default.nix
blob8c2a9f7e6f2c546b2df48811b83e57ecfe0da7ac
2   config,
3   stdenv,
4   fetchurl,
5   fetchpatch,
6   callPackage,
7   lib,
8   acpica-tools,
9   dev86,
10   pam,
11   libxslt,
12   libxml2,
13   wrapQtAppsHook,
14   libX11,
15   xorgproto,
16   libXext,
17   libXcursor,
18   libXmu,
19   libIDL,
20   SDL2,
21   libcap,
22   libGL,
23   libGLU,
24   libpng,
25   glib,
26   lvm2,
27   libXrandr,
28   libXinerama,
29   libopus,
30   libtpms,
31   qtbase,
32   qtx11extras,
33   qttools,
34   qtsvg,
35   qtwayland,
36   pkg-config,
37   which,
38   docbook_xsl,
39   docbook_xml_dtd_43,
40   alsa-lib,
41   curl,
42   libvpx,
43   nettools,
44   dbus,
45   substituteAll,
46   gsoap,
47   zlib,
48   xz,
49   yasm,
50   glslang,
51   nixosTests,
52   # If open-watcom-bin is not passed, VirtualBox will fall back to use
53   # the shipped alternative sources (assembly).
54   open-watcom-bin,
55   makeself,
56   perl,
57   vulkan-loader,
58   javaBindings ? true,
59   jdk, # Almost doesn't affect closure size
60   pythonBindings ? false,
61   python3,
62   extensionPack ? null,
63   fakeroot,
64   pulseSupport ? config.pulseaudio or stdenv.hostPlatform.isLinux,
65   libpulseaudio,
66   enableHardening ? false,
67   headless ? false,
68   enable32bitGuests ? true,
69   enableWebService ? false,
70   enableKvm ? false,
71   extraConfigureFlags ? "",
74 # The web services use Java infrastructure.
75 assert enableWebService -> javaBindings;
77 let
78   buildType = "release";
79   # Use maintainers/scripts/update.nix to update the version and all related hashes or
80   # change the hashes in extpack.nix and guest-additions/default.nix as well manually.
81   virtualboxVersion = "7.0.22";
82   virtualboxSha256 = "cf3ddf633ca410f1b087b0722413e83247cda4f14d33323dc122a4a42ff61981";
84   kvmPatchVersion = "20240828";
85   kvmPatchHash = "sha256-g0esJbB1IGyLGZMLFJIY8ZYdHWuiM5IZtLMHZvCY6bs=";
87   # The KVM build is not compatible to VirtualBox's kernel modules. So don't export
88   # modsrc at all.
89   withModsrc = !enableKvm;
91   virtualboxGuestAdditionsIso = callPackage guest-additions-iso/default.nix { };
93   inherit (lib)
94     optional
95     optionals
96     optionalString
97     getDev
98     getLib
99     ;
101 stdenv.mkDerivation (finalAttrs: {
102   pname = "virtualbox";
103   version = finalAttrs.virtualboxVersion;
105   inherit
106     buildType
107     virtualboxVersion
108     virtualboxSha256
109     kvmPatchVersion
110     kvmPatchHash
111     virtualboxGuestAdditionsIso
112     ;
114   src = fetchurl {
115     url = "https://download.virtualbox.org/virtualbox/${finalAttrs.virtualboxVersion}/VirtualBox-${finalAttrs.virtualboxVersion}.tar.bz2";
116     sha256 = finalAttrs.virtualboxSha256;
117   };
119   outputs = [ "out" ] ++ optional withModsrc "modsrc";
121   nativeBuildInputs = [
122     pkg-config
123     which
124     docbook_xsl
125     docbook_xml_dtd_43
126     yasm
127     glslang
128   ] ++ optional (!headless) wrapQtAppsHook;
130   # Wrap manually because we wrap just a small number of executables.
131   dontWrapQtApps = true;
133   buildInputs =
134     [
135       acpica-tools
136       dev86
137       libxslt
138       libxml2
139       xorgproto
140       libX11
141       libXext
142       libXcursor
143       libIDL
144       libcap
145       glib
146       lvm2
147       alsa-lib
148       curl
149       libvpx
150       pam
151       makeself
152       perl
153       libXmu
154       libXrandr
155       libpng
156       libopus
157       libtpms
158       python3
159       xz
160     ]
161     ++ optional javaBindings jdk
162     ++ optional pythonBindings python3 # Python is needed even when not building bindings
163     ++ optional pulseSupport libpulseaudio
164     ++ optionals headless [ libGL ]
165     ++ optionals (!headless) [
166       qtbase
167       qtx11extras
168       libXinerama
169       SDL2
170       libGLU
171     ]
172     ++ optionals enableWebService [
173       gsoap
174       zlib
175     ];
177   hardeningDisable = [
178     "format"
179     "fortify"
180     "pic"
181     "stackprotector"
182   ];
184   prePatch = ''
185     set -x
186     sed -e 's@MKISOFS --version@MKISOFS -version@' \
187         -e 's@PYTHONDIR=.*@PYTHONDIR=${optionalString pythonBindings python3}@' \
188         -e 's@CXX_FLAGS="\(.*\)"@CXX_FLAGS="-std=c++11 \1"@' \
189         ${
190           optionalString (!headless) ''
191             -e 's@TOOLQT5BIN=.*@TOOLQT5BIN="${getDev qtbase}/bin"@' \
192           ''
193         } -i configure
194     ls kBuild/bin/linux.x86/k* tools/linux.x86/bin/* | xargs -n 1 patchelf --set-interpreter ${stdenv.cc.libc}/lib/ld-linux.so.2
195     ls kBuild/bin/linux.amd64/k* tools/linux.amd64/bin/* | xargs -n 1 patchelf --set-interpreter ${stdenv.cc.libc}/lib/ld-linux-x86-64.so.2
197     grep 'libpulse\.so\.0'      src include -rI --files-with-match | xargs sed -i -e '
198       ${optionalString pulseSupport ''s@"libpulse\.so\.0"@"${libpulseaudio.out}/lib/libpulse.so.0"@g''}'
200     grep 'libdbus-1\.so\.3'     src include -rI --files-with-match | xargs sed -i -e '
201       s@"libdbus-1\.so\.3"@"${dbus.lib}/lib/libdbus-1.so.3"@g'
203     grep 'libasound\.so\.2'     src include -rI --files-with-match | xargs sed -i -e '
204       s@"libasound\.so\.2"@"${alsa-lib.out}/lib/libasound.so.2"@g'
206     export USER=nix
207     set +x
208   '';
210   patches =
211     optional enableHardening ./hardened.patch
212     # Since VirtualBox 7.0.8, VBoxSDL requires SDL2, but the build framework uses SDL1
213     ++ optionals (!headless) [
214       ./fix-sdl.patch
215       # No update patch disables check for update function
216       # https://bugs.launchpad.net/ubuntu/+source/virtualbox-ose/+bug/272212
217       (fetchpatch {
218         url = "https://salsa.debian.org/pkg-virtualbox-team/virtualbox/-/raw/debian/7.0.14-dfsg-1/debian/patches/16-no-update.patch";
219         hash = "sha256-UJHpuB6QB/BbxJorlqZXUF12lgq8gbLMRHRMsbyqRpY=";
220       })
221     ]
222     ++ [ ./extra_symbols.patch ]
223     # When hardening is enabled, we cannot use wrapQtApp to ensure that VirtualBoxVM sees
224     # the correct environment variables needed for Qt to work, specifically QT_PLUGIN_PATH.
225     # This is because VirtualBoxVM would detect that it is wrapped that and refuse to run,
226     # and also because it would unset QT_PLUGIN_PATH for security reasons. We work around
227     # these issues by patching the code to set QT_PLUGIN_PATH to the necessary paths,
228     # after the code that unsets it. Note that qtsvg is included so that SVG icons from
229     # the user's icon theme can be loaded.
230     ++ optional (!headless && enableHardening) (substituteAll {
231       src = ./qt-env-vars.patch;
232       qtPluginPath = "${qtbase.bin}/${qtbase.qtPluginPrefix}:${qtsvg.bin}/${qtbase.qtPluginPrefix}:${qtwayland.bin}/${qtbase.qtPluginPrefix}";
233     })
234     # While the KVM patch should not break any other behavior if --with-kvm is not specified,
235     # we don't take any chances and only apply it if people actually want to use KVM support.
236     ++ optional enableKvm (
237       let
238         patchVboxVersion =
239           # There is no updated patch for 7.0.22 yet, but the older one still applies.
240           if finalAttrs.virtualboxVersion == "7.0.22" then "7.0.20" else finalAttrs.virtualboxVersion;
241       in
242       fetchpatch {
243         name = "virtualbox-${finalAttrs.virtualboxVersion}-kvm-dev-${finalAttrs.kvmPatchVersion}.patch";
244         url = "https://github.com/cyberus-technology/virtualbox-kvm/releases/download/dev-${finalAttrs.kvmPatchVersion}/kvm-backend-${patchVboxVersion}-dev-${finalAttrs.kvmPatchVersion}.patch";
245         hash = finalAttrs.kvmPatchHash;
246       }
247     )
248     ++ [
249       ./qt-dependency-paths.patch
250       # https://github.com/NixOS/nixpkgs/issues/123851
251       ./fix-audio-driver-loading.patch
252     ];
254   postPatch = ''
255     sed -i -e 's|/sbin/ifconfig|${nettools}/bin/ifconfig|' \
256       src/VBox/HostDrivers/adpctl/VBoxNetAdpCtl.cpp
257   '';
259   # first line: ugly hack, and it isn't yet clear why it's a problem
260   configurePhase = ''
261     NIX_CFLAGS_COMPILE=$(echo "$NIX_CFLAGS_COMPILE" | sed 's,\-isystem ${lib.getDev stdenv.cc.libc}/include,,g')
263     cat >> LocalConfig.kmk <<LOCAL_CONFIG
264     VBOX_WITH_TESTCASES            :=
265     VBOX_WITH_TESTSUITE            :=
266     VBOX_WITH_VALIDATIONKIT        :=
267     VBOX_WITH_DOCS                 :=
268     VBOX_WITH_WARNINGS_AS_ERRORS   :=
270     VBOX_WITH_ORIGIN               :=
271     VBOX_PATH_APP_PRIVATE_ARCH_TOP := $out/share/virtualbox
272     VBOX_PATH_APP_PRIVATE_ARCH     := $out/libexec/virtualbox
273     VBOX_PATH_SHARED_LIBS          := $out/libexec/virtualbox
274     VBOX_WITH_RUNPATH              := $out/libexec/virtualbox
275     VBOX_PATH_APP_PRIVATE          := $out/share/virtualbox
276     VBOX_PATH_APP_DOCS             := $out/doc
278     VBOX_WITH_UPDATE_AGENT :=
280     ${optionalString javaBindings ''
281       VBOX_JAVA_HOME                 := ${jdk}
282     ''}
283     ${optionalString (!headless) ''
284       VBOX_WITH_VBOXSDL              := 1
285       PATH_QT5_X11_EXTRAS_LIB        := ${getLib qtx11extras}/lib
286       PATH_QT5_X11_EXTRAS_INC        := ${getDev qtx11extras}/include
287       PATH_QT5_TOOLS_LIB             := ${getLib qttools}/lib
288       PATH_QT5_TOOLS_INC             := ${getDev qttools}/include
289     ''}
290     ${optionalString enableWebService ''
291       # fix gsoap missing zlib include and produce errors with --as-needed
292       VBOX_GSOAP_CXX_LIBS := gsoapssl++ z
293     ''}
294     TOOL_QT5_LRC                   := ${getDev qttools}/bin/lrelease
295     LOCAL_CONFIG
297     ./configure \
298       ${optionalString headless "--build-headless"} \
299       ${optionalString (!javaBindings) "--disable-java"} \
300       ${optionalString (!pythonBindings) "--disable-python"} \
301       ${optionalString (!pulseSupport) "--disable-pulse"} \
302       ${optionalString (!enableHardening) "--disable-hardening"} \
303       ${optionalString (!enable32bitGuests) "--disable-vmmraw"} \
304       ${optionalString enableWebService "--enable-webservice"} \
305       ${optionalString (open-watcom-bin != null) "--with-ow-dir=${open-watcom-bin}"} \
306       ${optionalString (enableKvm) "--with-kvm"} \
307       ${extraConfigureFlags} \
308       --disable-kmods
309     sed -e 's@PKG_CONFIG_PATH=.*@PKG_CONFIG_PATH=${libIDL}/lib/pkgconfig:${glib.dev}/lib/pkgconfig ${libIDL}/bin/libIDL-config-2@' \
310         -i AutoConfig.kmk
311     sed -e 's@arch/x86/@@' \
312         -i Config.kmk
313     substituteInPlace Config.kmk --replace-fail "VBOX_WITH_TESTCASES = 1" "#"
314   '';
316   enableParallelBuilding = true;
318   buildPhase = ''
319     source env.sh
320     kmk -j $NIX_BUILD_CORES BUILD_TYPE="${finalAttrs.buildType}"
321   '';
323   installPhase = ''
324     libexec="$out/libexec/virtualbox"
325     share="${if enableHardening then "$out/share/virtualbox" else "$libexec"}"
327     # Install VirtualBox files
328     mkdir -p "$libexec"
329     find out/linux.*/${finalAttrs.buildType}/bin -mindepth 1 -maxdepth 1 \
330       -name src -o -exec cp -avt "$libexec" {} +
332     mkdir -p $out/bin
333     for file in ${
334       optionalString (!headless) "VirtualBox VBoxSDL"
335     } ${optionalString enableWebService "vboxwebsrv"} VBoxManage VBoxBalloonCtrl VBoxHeadless; do
336         echo "Linking $file to /bin"
337         test -x "$libexec/$file"
338         ln -s "$libexec/$file" $out/bin/$file
339     done
341     ${optionalString (extensionPack != null) ''
342       mkdir -p "$share"
343       "${fakeroot}/bin/fakeroot" "${stdenv.shell}" <<EOF
344       "$libexec/VBoxExtPackHelperApp" install \
345         --base-dir "$share/ExtensionPacks" \
346         --cert-dir "$share/ExtPackCertificates" \
347         --name "Oracle VM VirtualBox Extension Pack" \
348         --tarball "${extensionPack}" \
349         --sha-256 "${extensionPack.outputHash}"
350       EOF
351     ''}
353     ${optionalString (!headless) ''
354       # Create and fix desktop item
355       mkdir -p $out/share/applications
356       sed -i -e "s|Icon=VBox|Icon=$libexec/VBox.png|" $libexec/virtualbox.desktop
357       ln -sfv $libexec/virtualbox.desktop $out/share/applications
358       # Icons
359       mkdir -p $out/share/icons/hicolor
360       for size in `ls -1 $libexec/icons`; do
361         mkdir -p $out/share/icons/hicolor/$size/apps
362         ln -s $libexec/icons/$size/*.png $out/share/icons/hicolor/$size/apps
363       done
364       # Translation
365       mkdir -p "$out/share/virtualbox"
366       ln -sv $libexec/nls "$out/share/virtualbox/nls"
367     ''}
369     ${optionalString withModsrc ''
370       cp -rv out/linux.*/${finalAttrs.buildType}/bin/src "$modsrc"
371     ''}
373     mkdir -p "$out/share/virtualbox"
374     cp -rv src/VBox/Main/UnattendedTemplates "$out/share/virtualbox"
375     ln -s "${finalAttrs.virtualboxGuestAdditionsIso}" "$out/share/virtualbox/VBoxGuestAdditions.iso"
376   '';
378   preFixup =
379     optionalString (!headless) ''
380       wrapQtApp $out/bin/VirtualBox
381     ''
382     # If hardening is disabled, wrap the VirtualBoxVM binary instead of patching
383     # the source code (see postPatch).
384     + optionalString (!headless && !enableHardening) ''
385       wrapQtApp $out/libexec/virtualbox/VirtualBoxVM \
386          --prefix LD_LIBRARY_PATH : "${lib.makeLibraryPath [ vulkan-loader ]}"
387     '';
389   passthru = {
390     inherit extensionPack; # for inclusion in profile to prevent gc
391     tests = nixosTests.virtualbox;
392     updateScript = ./update.sh;
393   };
395   meta = {
396     description = "PC emulator";
397     longDescription = ''
398       VirtualBox is an x86 and AMD64/Intel64 virtualization product for enterprise and home use.
400       To install on NixOS, please use the option `virtualisation.virtualbox.host.enable = true`.
401       Please also check other options under `virtualisation.virtualbox`.
402     '';
403     sourceProvenance = with lib.sourceTypes; [
404       fromSource
405       binaryNativeCode
406     ];
407     license = lib.licenses.gpl2;
408     homepage = "https://www.virtualbox.org/";
409     maintainers = with lib.maintainers; [
410       sander
411       friedrichaltheide
412       blitz
413     ];
414     platforms = [ "x86_64-linux" ];
415     mainProgram = "VirtualBox";
416   };