biome: 1.9.2 -> 1.9.3
[NixPkgs.git] / pkgs / applications / virtualization / virtualbox / default.nix
blob437ceba29ce07f198635eab7a895c03afc6ae297
1 { config, stdenv, fetchurl, fetchpatch, callPackage, lib, acpica-tools, dev86, pam, libxslt, libxml2, wrapQtAppsHook
2 , libX11, xorgproto, libXext, libXcursor, libXmu, libIDL, SDL2, libcap, libGL, libGLU
3 , libpng, glib, lvm2, libXrandr, libXinerama, libopus, libtpms, qtbase, qtx11extras
4 , qttools, qtsvg, qtwayland, pkg-config, which, docbook_xsl, docbook_xml_dtd_43
5 , alsa-lib, curl, libvpx, nettools, dbus, substituteAll, gsoap, zlib, xz
6 , yasm, glslang
7 , nixosTests
8 # If open-watcom-bin is not passed, VirtualBox will fall back to use
9 # the shipped alternative sources (assembly).
10 , open-watcom-bin
11 , makeself, perl
12 , vulkan-loader
13 , javaBindings ? true, jdk # Almost doesn't affect closure size
14 , pythonBindings ? false, python3
15 , extensionPack ? null, fakeroot
16 , pulseSupport ? config.pulseaudio or stdenv.hostPlatform.isLinux, libpulseaudio
17 , enableHardening ? false
18 , headless ? false
19 , enable32bitGuests ? true
20 , enableWebService ? false
21 , enableKvm ? false
22 , extraConfigureFlags ? ""
25 # The web services use Java infrastructure.
26 assert enableWebService -> javaBindings;
28 let
29   buildType = "release";
30   # Use maintainers/scripts/update.nix to update the version and all related hashes or
31   # change the hashes in extpack.nix and guest-additions/default.nix as well manually.
32   virtualboxVersion = "7.0.20";
33   virtualboxSha256 = "5cf5979bef66ebab3fcd495796b215a940e8a07c469d4bc56d064de44222dd02";
35   kvmPatchVersion = "20240828";
36   kvmPatchHash = "sha256-g0esJbB1IGyLGZMLFJIY8ZYdHWuiM5IZtLMHZvCY6bs=";
38   # The KVM build is not compatible to VirtualBox's kernel modules. So don't export
39   # modsrc at all.
40   withModsrc = !enableKvm;
42   virtualboxGuestAdditionsIso = callPackage guest-additions-iso/default.nix { };
44   inherit (lib) optional optionals optionalString getDev getLib;
45 in stdenv.mkDerivation (finalAttrs: {
46   pname = "virtualbox";
47   version = finalAttrs.virtualboxVersion;
49   inherit buildType virtualboxVersion virtualboxSha256 kvmPatchVersion kvmPatchHash virtualboxGuestAdditionsIso;
51   src = fetchurl {
52     url = "https://download.virtualbox.org/virtualbox/${finalAttrs.virtualboxVersion}/VirtualBox-${finalAttrs.virtualboxVersion}.tar.bz2";
53     sha256 = finalAttrs.virtualboxSha256;
54   };
56   outputs = [ "out" ] ++ optional withModsrc "modsrc";
58   nativeBuildInputs = [ pkg-config which docbook_xsl docbook_xml_dtd_43 yasm glslang ]
59     ++ optional (!headless) wrapQtAppsHook;
61   # Wrap manually because we wrap just a small number of executables.
62   dontWrapQtApps = true;
64   buildInputs = [
65     acpica-tools dev86 libxslt libxml2 xorgproto libX11 libXext libXcursor libIDL
66     libcap glib lvm2 alsa-lib curl libvpx pam makeself perl
67     libXmu libXrandr libpng libopus libtpms python3 xz ]
68     ++ optional javaBindings jdk
69     ++ optional pythonBindings python3 # Python is needed even when not building bindings
70     ++ optional pulseSupport libpulseaudio
71     ++ optionals headless [ libGL ]
72     ++ optionals (!headless) [ qtbase qtx11extras libXinerama SDL2 libGLU ]
73     ++ optionals enableWebService [ gsoap zlib ];
75   hardeningDisable = [ "format" "fortify" "pic" "stackprotector" ];
77   prePatch = ''
78     set -x
79     sed -e 's@MKISOFS --version@MKISOFS -version@' \
80         -e 's@PYTHONDIR=.*@PYTHONDIR=${optionalString pythonBindings python3}@' \
81         -e 's@CXX_FLAGS="\(.*\)"@CXX_FLAGS="-std=c++11 \1"@' \
82         ${optionalString (!headless) ''
83         -e 's@TOOLQT5BIN=.*@TOOLQT5BIN="${getDev qtbase}/bin"@' \
84         ''} -i configure
85     ls kBuild/bin/linux.x86/k* tools/linux.x86/bin/* | xargs -n 1 patchelf --set-interpreter ${stdenv.cc.libc}/lib/ld-linux.so.2
86     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
88     grep 'libpulse\.so\.0'      src include -rI --files-with-match | xargs sed -i -e '
89       ${optionalString pulseSupport
90         ''s@"libpulse\.so\.0"@"${libpulseaudio.out}/lib/libpulse.so.0"@g''}'
92     grep 'libdbus-1\.so\.3'     src include -rI --files-with-match | xargs sed -i -e '
93       s@"libdbus-1\.so\.3"@"${dbus.lib}/lib/libdbus-1.so.3"@g'
95     grep 'libasound\.so\.2'     src include -rI --files-with-match | xargs sed -i -e '
96       s@"libasound\.so\.2"@"${alsa-lib.out}/lib/libasound.so.2"@g'
98     export USER=nix
99     set +x
100   '';
102   patches =
103      optional enableHardening ./hardened.patch
104      # Since VirtualBox 7.0.8, VBoxSDL requires SDL2, but the build framework uses SDL1
105   ++ optionals (!headless) [ ./fix-sdl.patch
106      # No update patch disables check for update function
107      # https://bugs.launchpad.net/ubuntu/+source/virtualbox-ose/+bug/272212
108      (fetchpatch {
109        url = "https://salsa.debian.org/pkg-virtualbox-team/virtualbox/-/raw/debian/7.0.14-dfsg-1/debian/patches/16-no-update.patch";
110        hash = "sha256-UJHpuB6QB/BbxJorlqZXUF12lgq8gbLMRHRMsbyqRpY=";
111      })]
112   ++ [ ./extra_symbols.patch ]
113      # When hardening is enabled, we cannot use wrapQtApp to ensure that VirtualBoxVM sees
114      # the correct environment variables needed for Qt to work, specifically QT_PLUGIN_PATH.
115      # This is because VirtualBoxVM would detect that it is wrapped that and refuse to run,
116      # and also because it would unset QT_PLUGIN_PATH for security reasons. We work around
117      # these issues by patching the code to set QT_PLUGIN_PATH to the necessary paths,
118      # after the code that unsets it. Note that qtsvg is included so that SVG icons from
119      # the user's icon theme can be loaded.
120   ++ optional (!headless && enableHardening) (substituteAll {
121       src = ./qt-env-vars.patch;
122       qtPluginPath = "${qtbase.bin}/${qtbase.qtPluginPrefix}:${qtsvg.bin}/${qtbase.qtPluginPrefix}:${qtwayland.bin}/${qtbase.qtPluginPrefix}";
123   })
124      # While the KVM patch should not break any other behavior if --with-kvm is not specified,
125      # we don't take any chances and only apply it if people actually want to use KVM support.
126   ++ optional enableKvm (fetchpatch {
127       name = "virtualbox-${finalAttrs.virtualboxVersion}-kvm-dev-${finalAttrs.kvmPatchVersion}.patch";
128       url = "https://github.com/cyberus-technology/virtualbox-kvm/releases/download/dev-${finalAttrs.kvmPatchVersion}/kvm-backend-${finalAttrs.virtualboxVersion}-dev-${finalAttrs.kvmPatchVersion}.patch";
129       hash = finalAttrs.kvmPatchHash;
130     })
131   ++ [
132     ./qt-dependency-paths.patch
133     # https://github.com/NixOS/nixpkgs/issues/123851
134     ./fix-audio-driver-loading.patch
135   ];
137   postPatch = ''
138     sed -i -e 's|/sbin/ifconfig|${nettools}/bin/ifconfig|' \
139       src/VBox/HostDrivers/adpctl/VBoxNetAdpCtl.cpp
140   '';
142   # first line: ugly hack, and it isn't yet clear why it's a problem
143   configurePhase = ''
144     NIX_CFLAGS_COMPILE=$(echo "$NIX_CFLAGS_COMPILE" | sed 's,\-isystem ${lib.getDev stdenv.cc.libc}/include,,g')
146     cat >> LocalConfig.kmk <<LOCAL_CONFIG
147     VBOX_WITH_TESTCASES            :=
148     VBOX_WITH_TESTSUITE            :=
149     VBOX_WITH_VALIDATIONKIT        :=
150     VBOX_WITH_DOCS                 :=
151     VBOX_WITH_WARNINGS_AS_ERRORS   :=
153     VBOX_WITH_ORIGIN               :=
154     VBOX_PATH_APP_PRIVATE_ARCH_TOP := $out/share/virtualbox
155     VBOX_PATH_APP_PRIVATE_ARCH     := $out/libexec/virtualbox
156     VBOX_PATH_SHARED_LIBS          := $out/libexec/virtualbox
157     VBOX_WITH_RUNPATH              := $out/libexec/virtualbox
158     VBOX_PATH_APP_PRIVATE          := $out/share/virtualbox
159     VBOX_PATH_APP_DOCS             := $out/doc
161     VBOX_WITH_UPDATE_AGENT :=
163     ${optionalString javaBindings ''
164     VBOX_JAVA_HOME                 := ${jdk}
165     ''}
166     ${optionalString (!headless) ''
167     VBOX_WITH_VBOXSDL              := 1
168     PATH_QT5_X11_EXTRAS_LIB        := ${getLib qtx11extras}/lib
169     PATH_QT5_X11_EXTRAS_INC        := ${getDev qtx11extras}/include
170     PATH_QT5_TOOLS_LIB             := ${getLib qttools}/lib
171     PATH_QT5_TOOLS_INC             := ${getDev qttools}/include
172     ''}
173     ${optionalString enableWebService ''
174     # fix gsoap missing zlib include and produce errors with --as-needed
175     VBOX_GSOAP_CXX_LIBS := gsoapssl++ z
176     ''}
177     TOOL_QT5_LRC                   := ${getDev qttools}/bin/lrelease
178     LOCAL_CONFIG
180     ./configure \
181       ${optionalString headless "--build-headless"} \
182       ${optionalString (!javaBindings) "--disable-java"} \
183       ${optionalString (!pythonBindings) "--disable-python"} \
184       ${optionalString (!pulseSupport) "--disable-pulse"} \
185       ${optionalString (!enableHardening) "--disable-hardening"} \
186       ${optionalString (!enable32bitGuests) "--disable-vmmraw"} \
187       ${optionalString enableWebService "--enable-webservice"} \
188       ${optionalString (open-watcom-bin != null) "--with-ow-dir=${open-watcom-bin}"} \
189       ${optionalString (enableKvm) "--with-kvm"} \
190       ${extraConfigureFlags} \
191       --disable-kmods
192     sed -e 's@PKG_CONFIG_PATH=.*@PKG_CONFIG_PATH=${libIDL}/lib/pkgconfig:${glib.dev}/lib/pkgconfig ${libIDL}/bin/libIDL-config-2@' \
193         -i AutoConfig.kmk
194     sed -e 's@arch/x86/@@' \
195         -i Config.kmk
196     substituteInPlace Config.kmk --replace-fail "VBOX_WITH_TESTCASES = 1" "#"
197   '';
199   enableParallelBuilding = true;
201   buildPhase = ''
202     source env.sh
203     kmk -j $NIX_BUILD_CORES BUILD_TYPE="${finalAttrs.buildType}"
204   '';
206   installPhase = ''
207     libexec="$out/libexec/virtualbox"
208     share="${if enableHardening then "$out/share/virtualbox" else "$libexec"}"
210     # Install VirtualBox files
211     mkdir -p "$libexec"
212     find out/linux.*/${finalAttrs.buildType}/bin -mindepth 1 -maxdepth 1 \
213       -name src -o -exec cp -avt "$libexec" {} +
215     mkdir -p $out/bin
216     for file in ${optionalString (!headless) "VirtualBox VBoxSDL"} ${optionalString enableWebService "vboxwebsrv"} VBoxManage VBoxBalloonCtrl VBoxHeadless; do
217         echo "Linking $file to /bin"
218         test -x "$libexec/$file"
219         ln -s "$libexec/$file" $out/bin/$file
220     done
222     ${optionalString (extensionPack != null) ''
223       mkdir -p "$share"
224       "${fakeroot}/bin/fakeroot" "${stdenv.shell}" <<EOF
225       "$libexec/VBoxExtPackHelperApp" install \
226         --base-dir "$share/ExtensionPacks" \
227         --cert-dir "$share/ExtPackCertificates" \
228         --name "Oracle VM VirtualBox Extension Pack" \
229         --tarball "${extensionPack}" \
230         --sha-256 "${extensionPack.outputHash}"
231       EOF
232     ''}
234     ${optionalString (!headless) ''
235       # Create and fix desktop item
236       mkdir -p $out/share/applications
237       sed -i -e "s|Icon=VBox|Icon=$libexec/VBox.png|" $libexec/virtualbox.desktop
238       ln -sfv $libexec/virtualbox.desktop $out/share/applications
239       # Icons
240       mkdir -p $out/share/icons/hicolor
241       for size in `ls -1 $libexec/icons`; do
242         mkdir -p $out/share/icons/hicolor/$size/apps
243         ln -s $libexec/icons/$size/*.png $out/share/icons/hicolor/$size/apps
244       done
245       # Translation
246       ln -sv $libexec/nls "$out/share/virtualbox"
247     ''}
249     ${optionalString withModsrc ''
250       cp -rv out/linux.*/${finalAttrs.buildType}/bin/src "$modsrc"
251     ''}
253     mkdir -p "$out/share/virtualbox"
254     cp -rv src/VBox/Main/UnattendedTemplates "$out/share/virtualbox"
255     ln -s "${finalAttrs.virtualboxGuestAdditionsIso}" "$out/share/virtualbox/VBoxGuestAdditions.iso"
256   '';
258   preFixup = optionalString (!headless) ''
259     wrapQtApp $out/bin/VirtualBox
260   ''
261   # If hardening is disabled, wrap the VirtualBoxVM binary instead of patching
262   # the source code (see postPatch).
263   + optionalString (!headless && !enableHardening) ''
264     wrapQtApp $out/libexec/virtualbox/VirtualBoxVM \
265        --prefix LD_LIBRARY_PATH : "${lib.makeLibraryPath [ vulkan-loader ]}"
266   '';
268   passthru = {
269     inherit extensionPack; # for inclusion in profile to prevent gc
270     tests = nixosTests.virtualbox;
271     updateScript = ./update.sh;
272   };
274   meta = {
275     description = "PC emulator";
276     longDescription = ''
277       VirtualBox is an x86 and AMD64/Intel64 virtualization product for enterprise and home use.
279       To install on NixOS, please use the option `virtualisation.virtualbox.host.enable = true`.
280       Please also check other options under `virtualisation.virtualbox`.
281     '';
282     sourceProvenance = with lib.sourceTypes; [
283       fromSource
284       binaryNativeCode
285     ];
286     license = lib.licenses.gpl2;
287     homepage = "https://www.virtualbox.org/";
288     maintainers = with lib.maintainers; [ sander friedrichaltheide blitz ];
289     platforms = [ "x86_64-linux" ];
290     mainProgram = "VirtualBox";
291   };