about summary refs log tree commit diff
path: root/pkgs/applications/emulators
diff options
context:
space:
mode:
author7c6f434c <7c6f434c@mail.ru>2022-02-20 10:36:35 +0000
committerGitHub <noreply@github.com>2022-02-20 10:36:35 +0000
commitbb4b1bcc7037c61b2041c72d33fedc77d87a8e3f (patch)
tree21ce22896adde319adb302f77b078ee432a67572 /pkgs/applications/emulators
parent98de8579cdf57c490d06460dc3d2ce29b7dadec9 (diff)
parentff2aca9f4ae39834b0609158f1a5a55528026ebb (diff)
downloadnixlib-bb4b1bcc7037c61b2041c72d33fedc77d87a8e3f.tar
nixlib-bb4b1bcc7037c61b2041c72d33fedc77d87a8e3f.tar.gz
nixlib-bb4b1bcc7037c61b2041c72d33fedc77d87a8e3f.tar.bz2
nixlib-bb4b1bcc7037c61b2041c72d33fedc77d87a8e3f.tar.lz
nixlib-bb4b1bcc7037c61b2041c72d33fedc77d87a8e3f.tar.xz
nixlib-bb4b1bcc7037c61b2041c72d33fedc77d87a8e3f.tar.zst
nixlib-bb4b1bcc7037c61b2041c72d33fedc77d87a8e3f.zip
Merge pull request #160256 from reckenrode/wine64-darwin
wine64: improve Darwin support
Diffstat (limited to 'pkgs/applications/emulators')
-rw-r--r--pkgs/applications/emulators/wine/base.nix44
-rw-r--r--pkgs/applications/emulators/wine/darwin-metal-compat.patch31
-rw-r--r--pkgs/applications/emulators/wine/default.nix12
-rw-r--r--pkgs/applications/emulators/wine/packages.nix12
-rw-r--r--pkgs/applications/emulators/wine/setup-hook-darwin.sh37
-rw-r--r--pkgs/applications/emulators/wine/vkd3d.nix8
6 files changed, 124 insertions, 20 deletions
diff --git a/pkgs/applications/emulators/wine/base.nix b/pkgs/applications/emulators/wine/base.nix
index 480fc009504e..f13e224627a9 100644
--- a/pkgs/applications/emulators/wine/base.nix
+++ b/pkgs/applications/emulators/wine/base.nix
@@ -1,10 +1,11 @@
-{ stdenv, lib, pkgArches, callPackage,
+{ stdenv, lib, pkgArches, callPackage, makeSetupHook,
   name, version, src, mingwGccs, monos, geckos, platforms,
   bison, flex, fontforge, makeWrapper, pkg-config,
   autoconf, hexdump, perl, nixosTests,
   supportFlags,
   patches,
   vkd3dArches,
+  moltenvk,
   buildScript ? null, configureFlags ? []
 }:
 
@@ -15,9 +16,31 @@ let
   prevName = name;
   prevPlatforms = platforms;
   prevConfigFlags = configureFlags;
+  setupHookDarwin = makeSetupHook {
+    name = "darwin-mingw-hook";
+    substitutions = {
+      darwinSuffixSalt = stdenv.cc.suffixSalt;
+      mingwGccsSuffixSalts = map (gcc: gcc.suffixSalt) mingwGccs;
+    };
+  } ./setup-hook-darwin.sh;
 in
 stdenv.mkDerivation ((lib.optionalAttrs (buildScript != null) {
   builder = buildScript;
+}) // (lib.optionalAttrs stdenv.isDarwin {
+  postConfigure = ''
+    # dynamic fallback, so this shouldn’t cause problems for older versions of macOS and will
+    # provide additional functionality on newer ones. This can be removed once the x86_64-darwin
+    # SDK is updated.
+    sed 's|/\* #undef HAVE_MTLDEVICE_REGISTRYID \*/|#define HAVE_MTLDEVICE_REGISTRYID 1|' \
+      -i include/config.h
+  '';
+  postBuild = ''
+    # The Wine preloader must _not_ be linked to any system libraries, but `NIX_LDFLAGS` will link
+    # to libintl, libiconv, and CoreFoundation no matter what. Delete the one that was built and
+    # rebuild it with empty NIX_LDFLAGS.
+    rm loader/wine64-preloader
+    make loader/wine64-preloader NIX_LDFLAGS="" NIX_LDFLAGS_${stdenv.cc.suffixSalt}=""
+  '';
 }) // rec {
   inherit src;
 
@@ -38,11 +61,13 @@ stdenv.mkDerivation ((lib.optionalAttrs (buildScript != null) {
     hexdump
     perl
   ]
-  ++ lib.optionals supportFlags.mingwSupport mingwGccs;
+  ++ lib.optionals supportFlags.mingwSupport (mingwGccs
+    ++ lib.optional stdenv.isDarwin setupHookDarwin);
 
   buildInputs = toBuildInputs pkgArches (with supportFlags; (pkgs:
-  [ pkgs.freetype pkgs.perl ]
+  [ pkgs.freetype pkgs.perl pkgs.libunwind ]
   ++ lib.optional stdenv.isLinux         pkgs.libcap
+  ++ lib.optional stdenv.isDarwin        pkgs.libinotify-kqueue
   ++ lib.optional cupsSupport            pkgs.cups
   ++ lib.optional gettextSupport         pkgs.gettext
   ++ lib.optional dbusSupport            pkgs.dbus
@@ -56,14 +81,16 @@ stdenv.mkDerivation ((lib.optionalAttrs (buildScript != null) {
   ++ lib.optional v4lSupport             pkgs.libv4l
   ++ lib.optional saneSupport            pkgs.sane-backends
   ++ lib.optional gphoto2Support         pkgs.libgphoto2
+  ++ lib.optional krb5Support            pkgs.libkrb5
   ++ lib.optional ldapSupport            pkgs.openldap
   ++ lib.optional fontconfigSupport      pkgs.fontconfig
   ++ lib.optional alsaSupport            pkgs.alsa-lib
   ++ lib.optional pulseaudioSupport      pkgs.libpulseaudio
   ++ lib.optional (xineramaSupport && !waylandSupport) pkgs.xorg.libXinerama
   ++ lib.optional udevSupport            pkgs.udev
-  ++ lib.optional vulkanSupport          pkgs.vulkan-loader
+  ++ lib.optional vulkanSupport          (if stdenv.isDarwin then moltenvk else pkgs.vulkan-loader)
   ++ lib.optional sdlSupport             pkgs.SDL2
+  ++ lib.optional usbSupport             pkgs.libusb1
   ++ vkd3dArches
   ++ lib.optionals gstreamerSupport      (with pkgs.gst_all_1;
     [ gstreamer gst-plugins-base gst-plugins-good gst-plugins-ugly gst-libav
@@ -83,12 +110,17 @@ stdenv.mkDerivation ((lib.optionalAttrs (buildScript != null) {
      wayland libxkbcommon wayland-protocols wayland.dev libxkbcommon.dev
   ])));
 
-  patches = [ ] ++ patches';
+  patches = [ ]
+    # Wine requires `MTLDevice.registryID` for `winemac.drv`, but that property is not available
+    # in the 10.12 SDK (current SDK on x86_64-darwin). Work around that by using selector syntax.
+    ++ lib.optional stdenv.isDarwin ./darwin-metal-compat.patch
+    ++ patches';
 
   configureFlags = prevConfigFlags
     ++ lib.optionals supportFlags.waylandSupport [ "--with-wayland" ]
     ++ lib.optionals supportFlags.vulkanSupport [ "--with-vulkan" ]
-    ++ lib.optionals supportFlags.vkd3dSupport [ "--with-vkd3d" ];
+    ++ lib.optionals supportFlags.vkd3dSupport [ "--with-vkd3d" ]
+    ++ lib.optionals (stdenv.isDarwin && !supportFlags.xineramaSupport) [ "--without-x" ];
 
   # Wine locates a lot of libraries dynamically through dlopen().  Add
   # them to the RPATH so that the user doesn't have to set them in
diff --git a/pkgs/applications/emulators/wine/darwin-metal-compat.patch b/pkgs/applications/emulators/wine/darwin-metal-compat.patch
new file mode 100644
index 000000000000..aeee7533bbd4
--- /dev/null
+++ b/pkgs/applications/emulators/wine/darwin-metal-compat.patch
@@ -0,0 +1,31 @@
+diff --git a/dlls/winemac.drv/cocoa_display.m b/dlls/winemac.drv/cocoa_display.m
+index f64a6c0f6ad..6da0391e3fa 100644
+--- a/dlls/winemac.drv/cocoa_display.m
++++ b/dlls/winemac.drv/cocoa_display.m
+@@ -289,7 +289,7 @@ static int macdrv_get_gpus_from_metal(struct macdrv_gpu** new_gpus, int* count)
+      * the primary GPU because we need to hide the integrated GPU for an automatic graphic switching pair to avoid apps
+      * using the integrated GPU. This is the behavior of Windows on a Mac. */
+     primary_device = [MTLCreateSystemDefaultDevice() autorelease];
+-    if (macdrv_get_gpu_info_from_registry_id(&primary_gpu, primary_device.registryID))
++    if (macdrv_get_gpu_info_from_registry_id(&primary_gpu, (uint64_t)[primary_device registryID]))
+         goto done;
+ 
+     /* Hide the integrated GPU if the system default device is a dedicated GPU */
+@@ -301,7 +301,7 @@ static int macdrv_get_gpus_from_metal(struct macdrv_gpu** new_gpus, int* count)
+ 
+     for (i = 0; i < devices.count; i++)
+     {
+-        if (macdrv_get_gpu_info_from_registry_id(&gpus[gpu_count], devices[i].registryID))
++        if (macdrv_get_gpu_info_from_registry_id(&gpus[gpu_count], (uint64_t)[devices[i] registryID]))
+             goto done;
+ 
+         if (hide_integrated && devices[i].isLowPower)
+@@ -354,7 +354,7 @@ static int macdrv_get_gpu_info_from_display_id_using_metal(struct macdrv_gpu* gp
+ 
+     device = [CGDirectDisplayCopyCurrentMetalDevice(display_id) autorelease];
+     if (device && [device respondsToSelector:@selector(registryID)])
+-        ret = macdrv_get_gpu_info_from_registry_id(gpu, device.registryID);
++        ret = macdrv_get_gpu_info_from_registry_id(gpu, (uint64_t)[device registryID]);
+ 
+ done:
+     [pool release];
diff --git a/pkgs/applications/emulators/wine/default.nix b/pkgs/applications/emulators/wine/default.nix
index 191fd4b29800..37953f73c5dc 100644
--- a/pkgs/applications/emulators/wine/default.nix
+++ b/pkgs/applications/emulators/wine/default.nix
@@ -6,7 +6,7 @@
 # };
 # Make additional configurations on demand:
 # wine.override { wineBuild = "wine32"; wineRelease = "staging"; };
-{ lib, stdenv, callPackage,
+{ lib, stdenv, callPackage, darwin,
   wineRelease ? "stable",
   wineBuild ? if stdenv.hostPlatform.system == "x86_64-linux" then "wineWow" else "wine32",
   gettextSupport ? false,
@@ -29,6 +29,7 @@
   v4lSupport ? false,
   saneSupport ? false,
   gphoto2Support ? false,
+  krb5Support ? false,
   ldapSupport ? false,
   pulseaudioSupport ? false,
   udevSupport ? false,
@@ -36,9 +37,11 @@
   vulkanSupport ? false,
   sdlSupport ? false,
   vkd3dSupport ? false,
+  usbSupport ? false,
   mingwSupport ? wineRelease != "stable",
   waylandSupport ? wineRelease == "wayland",
-  embedInstallers ? false # The Mono and Gecko MSI installers
+  embedInstallers ? false, # The Mono and Gecko MSI installers
+  moltenvk ? darwin.moltenvk # Allow users to override MoltenVK easily
 }:
 
 let wine-build = build: release:
@@ -48,11 +51,12 @@ let wine-build = build: release:
           inherit
             cupsSupport gettextSupport dbusSupport openalSupport cairoSupport
             odbcSupport netapiSupport cursesSupport vaSupport pcapSupport
-            v4lSupport saneSupport gphoto2Support ldapSupport fontconfigSupport
+            v4lSupport saneSupport gphoto2Support krb5Support ldapSupport fontconfigSupport
             alsaSupport pulseaudioSupport xineramaSupport gtkSupport openclSupport
             tlsSupport openglSupport gstreamerSupport udevSupport vulkanSupport
-            sdlSupport vkd3dSupport mingwSupport waylandSupport embedInstallers;
+            sdlSupport usbSupport vkd3dSupport mingwSupport waylandSupport embedInstallers;
         };
+        inherit moltenvk;
       });
 
 in if wineRelease == "staging" then
diff --git a/pkgs/applications/emulators/wine/packages.nix b/pkgs/applications/emulators/wine/packages.nix
index cb857daef0a6..bf3f57aff0ff 100644
--- a/pkgs/applications/emulators/wine/packages.nix
+++ b/pkgs/applications/emulators/wine/packages.nix
@@ -1,16 +1,16 @@
-{ stdenv_32bit, lib, pkgs, pkgsi686Linux, pkgsCross, callPackage,
+{ stdenv_32bit, lib, pkgs, pkgsi686Linux, pkgsCross, callPackage, moltenvk,
   wineRelease ? "stable",
   supportFlags
 }:
 
 let
   src = lib.getAttr wineRelease (callPackage ./sources.nix {});
-  vkd3d = pkgs.callPackage ./vkd3d.nix {};
-  vkd3d_i686 = pkgsi686Linux.callPackage ./vkd3d.nix {};
+  vkd3d = pkgs.callPackage ./vkd3d.nix { inherit moltenvk; };
+  vkd3d_i686 = pkgsi686Linux.callPackage ./vkd3d.nix { inherit moltenvk; };
 in with src; {
   wine32 = pkgsi686Linux.callPackage ./base.nix {
     name = "wine-${version}";
-    inherit src version supportFlags patches;
+    inherit src version supportFlags patches moltenvk;
     pkgArches = [ pkgsi686Linux ];
     vkd3dArches = lib.optionals supportFlags.vkd3dSupport [ vkd3d_i686 ];
     geckos = [ gecko32 ];
@@ -20,7 +20,7 @@ in with src; {
   };
   wine64 = callPackage ./base.nix {
     name = "wine64-${version}";
-    inherit src version supportFlags patches;
+    inherit src version supportFlags patches moltenvk;
     pkgArches = [ pkgs ];
     vkd3dArches = lib.optionals supportFlags.vkd3dSupport [ vkd3d ];
     mingwGccs = with pkgsCross; [ mingwW64.buildPackages.gcc ];
@@ -31,7 +31,7 @@ in with src; {
   };
   wineWow = callPackage ./base.nix {
     name = "wine-wow-${version}";
-    inherit src version supportFlags patches;
+    inherit src version supportFlags patches moltenvk;
     stdenv = stdenv_32bit;
     pkgArches = [ pkgs pkgsi686Linux ];
     vkd3dArches = lib.optionals supportFlags.vkd3dSupport [ vkd3d vkd3d_i686 ];
diff --git a/pkgs/applications/emulators/wine/setup-hook-darwin.sh b/pkgs/applications/emulators/wine/setup-hook-darwin.sh
new file mode 100644
index 000000000000..39eee193ded6
--- /dev/null
+++ b/pkgs/applications/emulators/wine/setup-hook-darwin.sh
@@ -0,0 +1,37 @@
+
+fixupCFlagsForDarwin() {
+    # Because it’s getting called from a Darwin stdenv, MinGW will pick up on Darwin-specific
+    # flags, and the ./configure tests will fail to consider it a working cross-compiler.
+    # Strip them out, so Wine can use MinGW to build its DLLs instead of trying to use Clang.
+    # Ideally, it would be possible to build the DLLs on Windows (i.e., as part of `pkgsCross``),
+    # but that is not the case currently with Wine’s build system.
+    cflagsFilter='s|-F[^ ]*||g;s|-iframework [^ ]*||g;s|-isystem [^ ]*||g;s|  *| |g'
+
+    # libiconv and libintl aren’t needed by Wine, and having them causes linking to fail.
+    # The `CoreFoundation` reference is added by `linkSystemCoreFoundationFramework` in the
+    # Apple SDK’s setup hook. Remove that because MingW will fail due to file not found.
+    ldFlagsFilter='s|-lintl||g;s|-liconv||g;s|/nix/store/[^-]*-apple-framework-CoreFoundation[^ ]*||g'
+
+    # `cc-wrapper.sh`` supports getting flags from a system-specific salt. While it is currently a
+    # tuple, that’s not considered a stable interface, so the Wine derivation will provide them:
+    # - for Darwin: The source is `stdenv.cc.suffixSalt`; and
+    # - for MinGW: The source is the `suffixSalt`` attribute of each of the `mingwGccs`.
+    export NIX_CFLAGS_COMPILE_@darwinSuffixSalt@=${NIX_CFLAGS_COMPILE-}
+    export NIX_LDFLAGS_@darwinSuffixSalt@=${NIX_LDFLAGS-}
+    for mingwSalt in @mingwGccsSuffixSalts@; do
+        echo removing @darwinSuffixSalt@-specific flags from NIX_CFLAGS_COMPILE for $mingwSalt
+        export NIX_CFLAGS_COMPILE_$mingwSalt+="$(sed "$cflagsFilter" <<< "$NIX_CFLAGS_COMPILE")"
+        echo removing @darwinSuffixSalt@-specific flags from NIX_LDFLAGS for $mingwSalt
+        export NIX_LDFLAGS_$mingwSalt+="$(sed "$ldFlagsFilter;$cflagsFilter" <<< "$NIX_LDFLAGS")"
+    done
+
+    # Make sure the global flags aren’t accidentally influencing the platform-specific flags.
+    export NIX_CFLAGS_COMPILE=""
+    export NIX_LDFLAGS=""
+}
+
+# This is pretty hacky, but this hook _must_ run after `linkSystemCoreFoundationFramework`.
+function runFixupCFlagsForDarwinLast() {
+    preConfigureHooks+=(fixupCFlagsForDarwin)
+}
+postUnpackHooks+=(runFixupCFlagsForDarwinLast)
diff --git a/pkgs/applications/emulators/wine/vkd3d.nix b/pkgs/applications/emulators/wine/vkd3d.nix
index 303d33df217d..ac7c399cd97b 100644
--- a/pkgs/applications/emulators/wine/vkd3d.nix
+++ b/pkgs/applications/emulators/wine/vkd3d.nix
@@ -1,6 +1,5 @@
-{ lib, stdenv, fetchurl, vulkan-headers, spirv-headers, vulkan-loader }:
+{ lib, stdenv, fetchurl, moltenvk, vulkan-headers, spirv-headers, vulkan-loader }:
 
-#TODO: MoltenVK
 #TODO: unstable
 
 stdenv.mkDerivation rec {
@@ -12,7 +11,8 @@ stdenv.mkDerivation rec {
     sha256 = "0szr1lw3xbgi9qjm13d1q4gyzzwv8i5wfxiwjg6dmwphrc7h6jxh";
   };
 
-  buildInputs = [ vulkan-headers spirv-headers vulkan-loader ];
+  buildInputs = [ vulkan-headers spirv-headers ]
+    ++ [ (if stdenv.isDarwin then moltenvk else vulkan-loader) ];
 
   enableParallelBuilding = true;
 
@@ -20,7 +20,7 @@ stdenv.mkDerivation rec {
     description = "A 3d library build on top on Vulkan with a similar api to DirectX 12";
     homepage = "https://source.winehq.org/git/vkd3d.git";
     license = licenses.lgpl21;
-    platforms = platforms.linux;
+    platforms = platforms.unix;
     maintainers = [ maintainers.marius851000 ];
   };
 }