summary refs log tree commit diff
path: root/pkgs/applications/emulators/wine
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/applications/emulators/wine')
-rw-r--r--pkgs/applications/emulators/wine/base.nix199
-rw-r--r--pkgs/applications/emulators/wine/builder-wow.sh31
-rw-r--r--pkgs/applications/emulators/wine/cert-path.patch15
-rw-r--r--pkgs/applications/emulators/wine/darwin-metal-compat.patch31
-rw-r--r--pkgs/applications/emulators/wine/default.nix67
-rw-r--r--pkgs/applications/emulators/wine/fonts.nix22
-rw-r--r--pkgs/applications/emulators/wine/packages.nix44
-rw-r--r--pkgs/applications/emulators/wine/setup-hook-darwin.sh37
-rw-r--r--pkgs/applications/emulators/wine/sources.nix93
-rw-r--r--pkgs/applications/emulators/wine/staging.nix28
-rw-r--r--pkgs/applications/emulators/wine/util.nix9
-rw-r--r--pkgs/applications/emulators/wine/vkd3d.nix28
-rw-r--r--pkgs/applications/emulators/wine/winetricks.nix33
13 files changed, 637 insertions, 0 deletions
diff --git a/pkgs/applications/emulators/wine/base.nix b/pkgs/applications/emulators/wine/base.nix
new file mode 100644
index 00000000000..f13e224627a
--- /dev/null
+++ b/pkgs/applications/emulators/wine/base.nix
@@ -0,0 +1,199 @@
+{ 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 ? []
+}:
+
+with import ./util.nix { inherit lib; };
+
+let
+  patches' = patches;
+  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;
+
+  name = if supportFlags.waylandSupport then "${prevName}-wayland" else prevName;
+
+  # Fixes "Compiler cannot create executables" building wineWow with mingwSupport
+  strictDeps = true;
+
+  nativeBuildInputs = [
+    bison
+    flex
+    fontforge
+    makeWrapper
+    pkg-config
+
+    # Required by staging
+    autoconf
+    hexdump
+    perl
+  ]
+  ++ lib.optionals supportFlags.mingwSupport (mingwGccs
+    ++ lib.optional stdenv.isDarwin setupHookDarwin);
+
+  buildInputs = toBuildInputs pkgArches (with supportFlags; (pkgs:
+  [ 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
+  ++ lib.optional openalSupport          pkgs.openal
+  ++ lib.optional cairoSupport           pkgs.cairo
+  ++ lib.optional odbcSupport            pkgs.unixODBC
+  ++ lib.optional netapiSupport          pkgs.samba4
+  ++ lib.optional cursesSupport          pkgs.ncurses
+  ++ lib.optional vaSupport              pkgs.libva
+  ++ lib.optional pcapSupport            pkgs.libpcap
+  ++ 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          (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
+    (gst-plugins-bad.override { enableZbar = false; }) ])
+  ++ lib.optionals gtkSupport    [ pkgs.gtk3 pkgs.glib ]
+  ++ lib.optionals openclSupport [ pkgs.opencl-headers pkgs.ocl-icd ]
+  ++ lib.optionals tlsSupport    [ pkgs.openssl pkgs.gnutls ]
+  ++ lib.optionals (openglSupport && !stdenv.isDarwin) [ pkgs.libGLU pkgs.libGL pkgs.mesa.osmesa pkgs.libdrm ]
+  ++ lib.optionals stdenv.isDarwin (with pkgs.buildPackages.darwin.apple_sdk.frameworks; [
+     CoreServices Foundation ForceFeedback AppKit OpenGL IOKit DiskArbitration Security
+     ApplicationServices AudioToolbox CoreAudio AudioUnit CoreMIDI OpenAL OpenCL Cocoa Carbon
+  ])
+  ++ lib.optionals (stdenv.isLinux && !waylandSupport) (with pkgs.xorg; [
+     libX11 libXi libXcursor libXrandr libXrender libXxf86vm libXcomposite libXext
+  ])
+  ++ lib.optionals waylandSupport (with pkgs; [
+     wayland libxkbcommon wayland-protocols wayland.dev libxkbcommon.dev
+  ])));
+
+  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 (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
+  # LD_LIBRARY_PATH.
+  NIX_LDFLAGS = toString (map (path: "-rpath " + path) (
+      map (x: "${lib.getLib x}/lib") ([ stdenv.cc.cc ] ++ buildInputs)
+      # libpulsecommon.so is linked but not found otherwise
+      ++ lib.optionals supportFlags.pulseaudioSupport (map (x: "${lib.getLib x}/lib/pulseaudio")
+          (toBuildInputs pkgArches (pkgs: [ pkgs.libpulseaudio ])))
+      ++ lib.optionals supportFlags.waylandSupport (map (x: "${lib.getLib x}/share/wayland-protocols")
+          (toBuildInputs pkgArches (pkgs: [ pkgs.wayland-protocols ])))
+    ));
+
+  # Don't shrink the ELF RPATHs in order to keep the extra RPATH
+  # elements specified above.
+  dontPatchELF = true;
+
+  ## FIXME
+  # Add capability to ignore known failing tests
+  # and enable doCheck
+  doCheck = false;
+
+  postInstall = let
+    links = prefix: pkg: "ln -s ${pkg} $out/${prefix}/${pkg.name}";
+  in lib.optionalString supportFlags.embedInstallers ''
+    mkdir -p $out/share/wine/gecko $out/share/wine/mono/
+    ${lib.strings.concatStringsSep "\n"
+          ((map (links "share/wine/gecko") geckos)
+        ++ (map (links "share/wine/mono")  monos))}
+  '' + lib.optionalString supportFlags.gstreamerSupport ''
+    # Wrapping Wine is tricky.
+    # https://github.com/NixOS/nixpkgs/issues/63170
+    # https://github.com/NixOS/nixpkgs/issues/28486
+    # The main problem is that wine-preloader opens and loads the wine(64) binary, and
+    # breakage occurs if it finds a shell script instead of the real binary. We solve this
+    # by setting WINELOADER to point to the original binary. Additionally, the locations
+    # of the 32-bit and 64-bit binaries must differ only by the presence of "64" at the
+    # end, due to the logic Wine uses to find the other binary (see get_alternate_loader
+    # in dlls/kernel32/process.c). Therefore we do not use wrapProgram which would move
+    # the binaries to ".wine-wrapped" and ".wine64-wrapped", but use makeWrapper directly,
+    # and move the binaries to ".wine" and ".wine64".
+    for i in wine wine64 ; do
+      prog="$out/bin/$i"
+      if [ -e "$prog" ]; then
+        hidden="$(dirname "$prog")/.$(basename "$prog")"
+        mv "$prog" "$hidden"
+        makeWrapper "$hidden" "$prog" \
+          --argv0 "" \
+          --set WINELOADER "$hidden" \
+          --prefix GST_PLUGIN_SYSTEM_PATH_1_0 ":" "$GST_PLUGIN_SYSTEM_PATH_1_0"
+      fi
+    done
+  '';
+
+  enableParallelBuilding = true;
+
+  # https://bugs.winehq.org/show_bug.cgi?id=43530
+  # https://github.com/NixOS/nixpkgs/issues/31989
+  hardeningDisable = [ "bindnow" ]
+    ++ lib.optional (stdenv.hostPlatform.isDarwin) "fortify"
+    ++ lib.optional (supportFlags.mingwSupport) "format";
+
+  passthru = {
+    inherit pkgArches;
+    tests = { inherit (nixosTests) wine; };
+  };
+  meta = {
+    inherit version;
+    homepage = "https://www.winehq.org/";
+    license = with lib.licenses; [ lgpl21Plus ];
+    description = if supportFlags.waylandSupport then "An Open Source implementation of the Windows API on top of OpenGL and Unix (with experimental Wayland support)" else "An Open Source implementation of the Windows API on top of X, OpenGL, and Unix";
+    platforms = if supportFlags.waylandSupport then (lib.remove "x86_64-darwin" prevPlatforms) else prevPlatforms;
+    maintainers = with lib.maintainers; [ avnik raskin bendlas jmc-figueira ];
+    mainProgram = "wine";
+  };
+})
diff --git a/pkgs/applications/emulators/wine/builder-wow.sh b/pkgs/applications/emulators/wine/builder-wow.sh
new file mode 100644
index 00000000000..0dd3194dc53
--- /dev/null
+++ b/pkgs/applications/emulators/wine/builder-wow.sh
@@ -0,0 +1,31 @@
+## build described at http://wiki.winehq.org/Wine64
+
+source $stdenv/setup
+preFlags="${configureFlags}"
+
+unpackPhase
+cd $TMP/$sourceRoot
+patchPhase
+
+configureScript=$TMP/$sourceRoot/configure
+mkdir -p $TMP/wine-wow $TMP/wine64
+
+cd $TMP/wine64
+sourceRoot=`pwd`
+configureFlags="${preFlags} --enable-win64"
+configurePhase
+buildPhase
+# checkPhase
+
+cd $TMP/wine-wow
+sourceRoot=`pwd`
+configureFlags="${preFlags} --with-wine64=../wine64"
+configurePhase
+buildPhase
+# checkPhase
+
+eval "$preInstall"
+cd $TMP/wine-wow && make install
+cd $TMP/wine64 && make install
+eval "$postInstall"
+fixupPhase
diff --git a/pkgs/applications/emulators/wine/cert-path.patch b/pkgs/applications/emulators/wine/cert-path.patch
new file mode 100644
index 00000000000..f0727f422f8
--- /dev/null
+++ b/pkgs/applications/emulators/wine/cert-path.patch
@@ -0,0 +1,15 @@
+diff --git a/dlls/crypt32/unixlib.c b/dlls/crypt32/unixlib.c
+index 7cb521eb98b..5804b88be84 100644
+--- a/dlls/crypt32/unixlib.c
++++ b/dlls/crypt32/unixlib.c
+@@ -654,6 +654,10 @@ static void load_root_certs(void)
+ 
+     for (i = 0; i < ARRAY_SIZE(CRYPT_knownLocations) && list_empty(&root_cert_list); i++)
+         import_certs_from_path( CRYPT_knownLocations[i], TRUE );
++
++    char *nix_cert_file = getenv("NIX_SSL_CERT_FILE");
++    if (nix_cert_file != NULL)
++        import_certs_from_path(nix_cert_file, TRUE);
+ }
+ 
+ static NTSTATUS enum_root_certs( void *args )
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 00000000000..aeee7533bbd
--- /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
new file mode 100644
index 00000000000..37953f73c5d
--- /dev/null
+++ b/pkgs/applications/emulators/wine/default.nix
@@ -0,0 +1,67 @@
+## Configuration:
+# Control you default wine config in nixpkgs-config:
+# wine = {
+#   release = "stable"; # "stable", "unstable", "staging", "wayland"
+#   build = "wineWow"; # "wine32", "wine64", "wineWow"
+# };
+# Make additional configurations on demand:
+# wine.override { wineBuild = "wine32"; wineRelease = "staging"; };
+{ lib, stdenv, callPackage, darwin,
+  wineRelease ? "stable",
+  wineBuild ? if stdenv.hostPlatform.system == "x86_64-linux" then "wineWow" else "wine32",
+  gettextSupport ? false,
+  fontconfigSupport ? false,
+  alsaSupport ? false,
+  gtkSupport ? false,
+  openglSupport ? false,
+  tlsSupport ? false,
+  gstreamerSupport ? false,
+  cupsSupport ? false,
+  dbusSupport ? false,
+  openalSupport ? false,
+  openclSupport ? false,
+  cairoSupport ? false,
+  odbcSupport ? false,
+  netapiSupport ? false,
+  cursesSupport ? false,
+  vaSupport ? false,
+  pcapSupport ? false,
+  v4lSupport ? false,
+  saneSupport ? false,
+  gphoto2Support ? false,
+  krb5Support ? false,
+  ldapSupport ? false,
+  pulseaudioSupport ? false,
+  udevSupport ? false,
+  xineramaSupport ? false,
+  vulkanSupport ? false,
+  sdlSupport ? false,
+  vkd3dSupport ? false,
+  usbSupport ? false,
+  mingwSupport ? wineRelease != "stable",
+  waylandSupport ? wineRelease == "wayland",
+  embedInstallers ? false, # The Mono and Gecko MSI installers
+  moltenvk ? darwin.moltenvk # Allow users to override MoltenVK easily
+}:
+
+let wine-build = build: release:
+      lib.getAttr build (callPackage ./packages.nix {
+        wineRelease = release;
+        supportFlags = {
+          inherit
+            cupsSupport gettextSupport dbusSupport openalSupport cairoSupport
+            odbcSupport netapiSupport cursesSupport vaSupport pcapSupport
+            v4lSupport saneSupport gphoto2Support krb5Support ldapSupport fontconfigSupport
+            alsaSupport pulseaudioSupport xineramaSupport gtkSupport openclSupport
+            tlsSupport openglSupport gstreamerSupport udevSupport vulkanSupport
+            sdlSupport usbSupport vkd3dSupport mingwSupport waylandSupport embedInstallers;
+        };
+        inherit moltenvk;
+      });
+
+in if wineRelease == "staging" then
+  callPackage ./staging.nix {
+    wineUnstable = wine-build wineBuild "unstable";
+  }
+else
+  wine-build wineBuild wineRelease
diff --git a/pkgs/applications/emulators/wine/fonts.nix b/pkgs/applications/emulators/wine/fonts.nix
new file mode 100644
index 00000000000..0ee1b3973d8
--- /dev/null
+++ b/pkgs/applications/emulators/wine/fonts.nix
@@ -0,0 +1,22 @@
+{ stdenv, lib, callPackage }:
+let src = (callPackage ./sources.nix {}).stable;
+in
+stdenv.mkDerivation {
+  pname = "wine-fonts";
+  inherit (src) version;
+
+  sourceRoot = "wine-${src.version}/fonts";
+  inherit src;
+
+  installPhase = ''
+    install *.ttf -Dt $out/share/fonts/wine
+  '';
+
+  meta = {
+    description = "Microsoft replacement fonts by the Wine project";
+    homepage = "https://wiki.winehq.org/Create_Fonts";
+    license = with lib.licenses; [ lgpl21Plus ];
+    platforms = lib.platforms.all;
+    maintainers = with lib.maintainers; [ avnik raskin bendlas johnazoidberg ];
+  };
+}
diff --git a/pkgs/applications/emulators/wine/packages.nix b/pkgs/applications/emulators/wine/packages.nix
new file mode 100644
index 00000000000..bf3f57aff0f
--- /dev/null
+++ b/pkgs/applications/emulators/wine/packages.nix
@@ -0,0 +1,44 @@
+{ stdenv_32bit, lib, pkgs, pkgsi686Linux, pkgsCross, callPackage, moltenvk,
+  wineRelease ? "stable",
+  supportFlags
+}:
+
+let
+  src = lib.getAttr wineRelease (callPackage ./sources.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 moltenvk;
+    pkgArches = [ pkgsi686Linux ];
+    vkd3dArches = lib.optionals supportFlags.vkd3dSupport [ vkd3d_i686 ];
+    geckos = [ gecko32 ];
+    mingwGccs = with pkgsCross; [ mingw32.buildPackages.gcc ];
+    monos =  [ mono ];
+    platforms = [ "i686-linux" "x86_64-linux" ];
+  };
+  wine64 = callPackage ./base.nix {
+    name = "wine64-${version}";
+    inherit src version supportFlags patches moltenvk;
+    pkgArches = [ pkgs ];
+    vkd3dArches = lib.optionals supportFlags.vkd3dSupport [ vkd3d ];
+    mingwGccs = with pkgsCross; [ mingwW64.buildPackages.gcc ];
+    geckos = [ gecko64 ];
+    monos =  [ mono ];
+    configureFlags = [ "--enable-win64" ];
+    platforms = [ "x86_64-linux" "x86_64-darwin" ];
+  };
+  wineWow = callPackage ./base.nix {
+    name = "wine-wow-${version}";
+    inherit src version supportFlags patches moltenvk;
+    stdenv = stdenv_32bit;
+    pkgArches = [ pkgs pkgsi686Linux ];
+    vkd3dArches = lib.optionals supportFlags.vkd3dSupport [ vkd3d vkd3d_i686 ];
+    geckos = [ gecko32 gecko64 ];
+    mingwGccs = with pkgsCross; [ mingw32.buildPackages.gcc mingwW64.buildPackages.gcc ];
+    monos =  [ mono ];
+    buildScript = ./builder-wow.sh;
+    platforms = [ "x86_64-linux" ];
+  };
+}
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 00000000000..39eee193ded
--- /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/sources.nix b/pkgs/applications/emulators/wine/sources.nix
new file mode 100644
index 00000000000..23538a237e4
--- /dev/null
+++ b/pkgs/applications/emulators/wine/sources.nix
@@ -0,0 +1,93 @@
+{ pkgs ? import <nixpkgs> {} }:
+## we default to importing <nixpkgs> here, so that you can use
+## a simple shell command to insert new sha256's into this file
+## e.g. with emacs C-u M-x shell-command
+##
+##     nix-prefetch-url sources.nix -A {stable{,.mono,.gecko64,.gecko32}, unstable, staging, winetricks}
+
+# here we wrap fetchurl and fetchFromGitHub, in order to be able to pass additional args around it
+let fetchurl = args@{url, sha256, ...}:
+  pkgs.fetchurl { inherit url sha256; } // args;
+    fetchFromGitHub = args@{owner, repo, rev, sha256, ...}:
+  pkgs.fetchFromGitHub { inherit owner repo rev sha256; } // args;
+    fetchFromGitLab = args@{domain, owner, repo, rev, sha256, ...}:
+  pkgs.fetchFromGitLab { inherit domain owner repo rev sha256; } // args;
+in rec {
+
+  stable = fetchurl rec {
+    version = "7.0";
+    url = "https://dl.winehq.org/wine/source/7.0/wine-${version}.tar.xz";
+    sha256 = "sha256-W0PifVwIXLGPlzlORhgDENXu98HZHGiVQyo4ibLeCGs=";
+
+    ## see http://wiki.winehq.org/Gecko
+    gecko32 = fetchurl rec {
+      version = "2.47.2";
+      url = "https://dl.winehq.org/wine/wine-gecko/${version}/wine-gecko-${version}-x86.msi";
+      sha256 = "07d6nrk2g0614kvwdjym1wq21d2bwy3pscwikk80qhnd6rrww875";
+    };
+    gecko64 = fetchurl rec {
+      version = "2.47.2";
+      url = "https://dl.winehq.org/wine/wine-gecko/${version}/wine-gecko-${version}-x86_64.msi";
+      sha256 = "0iffhvdawc499nbn4k99k33cr7g8sdfcvq8k3z1g6gw24h87d5h5";
+    };
+
+    ## see http://wiki.winehq.org/Mono
+    mono = fetchurl rec {
+      version = "7.0.0";
+      url = "https://dl.winehq.org/wine/wine-mono/${version}/wine-mono-${version}-x86.msi";
+      sha256 = "sha256-s35vyeWQ5YIkPcJdcqX8wzDDp5cN/cmKeoHSOEW6iQA=";
+    };
+
+    patches = [
+      # Also look for root certificates at $NIX_SSL_CERT_FILE
+      ./cert-path.patch
+    ];
+  };
+
+  unstable = fetchurl rec {
+    # NOTE: Don't forget to change the SHA256 for staging as well.
+    version = "7.4";
+    url = "https://dl.winehq.org/wine/source/7.x/wine-${version}.tar.xz";
+    sha256 = "sha256-co6GbW5JzpKioMUUMz6f8Ivb9shvXvTmGAFDuNK31BY=";
+    inherit (stable) gecko32 gecko64 patches;
+
+    mono = fetchurl rec {
+      version = "7.1.1";
+      url = "https://dl.winehq.org/wine/wine-mono/${version}/wine-mono-${version}-x86.msi";
+      sha256 = "sha256-ncjlYDt7xkNU65SuTqD2ghQkdno/9E/w0Z40akkMEeo=";
+    };
+  };
+
+  staging = fetchFromGitHub rec {
+    # https://github.com/wine-staging/wine-staging/releases
+    inherit (unstable) version;
+    sha256 = "0vlj3b8bnidyhlgkjrnlbah3878zjy3s557vbp16qka42zjaa51q";
+    owner = "wine-staging";
+    repo = "wine-staging";
+    rev = "v${version}";
+
+    disabledPatchsets = [ ];
+  };
+
+  wayland = fetchFromGitLab rec {
+    version = "7.0-rc2";
+    sha256 = "sha256-FU9L8cyIIfFQ+8f/AUg7IT+RxTpyNTuSfL0zBnur0SA=";
+    domain = "gitlab.collabora.com";
+    owner = "alf";
+    repo = "wine";
+    rev = "95f0154c96a4b7d81e783ee5ba2f5d9cc7cda351";
+
+    inherit (unstable) gecko32 gecko64;
+
+    inherit (unstable) mono;
+  };
+
+  winetricks = fetchFromGitHub rec {
+    # https://github.com/Winetricks/winetricks/releases
+    version = "20210825";
+    sha256 = "sha256-exMhj3dS8uXCEgOaWbftaq94mBOmtZIXsXb9xNX5ha8=";
+    owner = "Winetricks";
+    repo = "winetricks";
+    rev = version;
+  };
+}
diff --git a/pkgs/applications/emulators/wine/staging.nix b/pkgs/applications/emulators/wine/staging.nix
new file mode 100644
index 00000000000..c6bdb401245
--- /dev/null
+++ b/pkgs/applications/emulators/wine/staging.nix
@@ -0,0 +1,28 @@
+{ lib, callPackage, wineUnstable }:
+
+with callPackage ./util.nix {};
+
+let patch = (callPackage ./sources.nix {}).staging;
+    build-inputs = pkgNames: extra:
+      (mkBuildInputs wineUnstable.pkgArches pkgNames) ++ extra;
+in assert lib.getVersion wineUnstable == patch.version;
+
+(lib.overrideDerivation wineUnstable (self: {
+  buildInputs = build-inputs [ "perl" "util-linux" "autoconf" "gitMinimal" ] self.buildInputs;
+
+  name = "${self.name}-staging";
+
+  prePatch = self.prePatch or "" + ''
+    patchShebangs tools
+    cp -r ${patch}/patches .
+    chmod +w patches
+    cd patches
+    patchShebangs gitapply.sh
+    ./patchinstall.sh DESTDIR="$PWD/.." --all ${lib.concatMapStringsSep " " (ps: "-W ${ps}") patch.disabledPatchsets}
+    cd ..
+  '';
+})) // {
+  meta = wineUnstable.meta // {
+    description = wineUnstable.meta.description + " (with staging patches)";
+  };
+}
diff --git a/pkgs/applications/emulators/wine/util.nix b/pkgs/applications/emulators/wine/util.nix
new file mode 100644
index 00000000000..cd5bd03130b
--- /dev/null
+++ b/pkgs/applications/emulators/wine/util.nix
@@ -0,0 +1,9 @@
+{ lib }:
+rec {
+  toPackages = pkgNames: pkgs:
+    map (pn: lib.getAttr pn pkgs) pkgNames;
+  toBuildInputs = pkgArches: archPkgs:
+    lib.concatLists (map archPkgs pkgArches);
+  mkBuildInputs = pkgArches: pkgNames:
+    toBuildInputs pkgArches (toPackages pkgNames);
+}
diff --git a/pkgs/applications/emulators/wine/vkd3d.nix b/pkgs/applications/emulators/wine/vkd3d.nix
new file mode 100644
index 00000000000..4f06b886e23
--- /dev/null
+++ b/pkgs/applications/emulators/wine/vkd3d.nix
@@ -0,0 +1,28 @@
+{ lib, stdenv, fetchurl, moltenvk, vulkan-headers, spirv-headers, vulkan-loader, flex, bison }:
+
+#TODO: unstable
+
+stdenv.mkDerivation rec {
+  pname = "vkd3d";
+  version = "1.3";
+
+  src = fetchurl {
+    url = "https://dl.winehq.org/vkd3d/source/vkd3d-${version}.tar.xz";
+    sha256 = "134b347806d34a4d2b39ea29ff1c2b38443793803a3adc50800855bb929fb8b2";
+  };
+
+  nativeBuildInputs = [ flex bison ];
+
+  buildInputs = [ vulkan-headers spirv-headers ]
+    ++ [ (if stdenv.isDarwin then moltenvk else vulkan-loader) ];
+
+  enableParallelBuilding = true;
+
+  meta = with lib; {
+    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.unix;
+    maintainers = [ maintainers.marius851000 ];
+  };
+}
diff --git a/pkgs/applications/emulators/wine/winetricks.nix b/pkgs/applications/emulators/wine/winetricks.nix
new file mode 100644
index 00000000000..61ca6515c44
--- /dev/null
+++ b/pkgs/applications/emulators/wine/winetricks.nix
@@ -0,0 +1,33 @@
+{ lib, stdenv, callPackage, perl, which, coreutils, zenity, curl
+, cabextract, unzip, p7zip, gnused, gnugrep, bash } :
+
+stdenv.mkDerivation rec {
+  pname = "winetricks";
+  version = src.version;
+
+  src = (callPackage ./sources.nix {}).winetricks;
+
+  buildInputs = [ perl which ];
+
+  # coreutils is for sha1sum
+  pathAdd = lib.makeBinPath [
+    perl which coreutils zenity curl cabextract unzip p7zip gnused gnugrep bash
+  ];
+
+  makeFlags = [ "PREFIX=$(out)" ];
+
+  doCheck = false; # requires "bashate"
+
+  postInstall = ''
+    sed -i \
+      -e '2i PATH="${pathAdd}:$PATH"' \
+      "$out/bin/winetricks"
+  '';
+
+  meta = {
+    description = "A script to install DLLs needed to work around problems in Wine";
+    license = lib.licenses.lgpl21;
+    homepage = "https://github.com/Winetricks/winetricks";
+    platforms = with lib.platforms; linux;
+  };
+}