Nixpkgs: Wine (with mingw support)

Created on 8 Nov 2020  Â·  17Comments  Â·  Source: NixOS/nixpkgs

Project description
There is a great wine package currently in NixOS but it lacks mingw support for the DLLs.

This is needed for a few games including World of Warcraft it seems. Basically we need to build WINE with "--with-mingw" compile flag. The problem I have here is - I have no idea how to actually include the mingw compiler as a dependency to WINE.

Any help here would be appreciated.

Metadata

packaging request

All 17 comments

cc @avnik @bendlas @7c6f434c

@cawilliamson I think something like this should work:

{ wine, pkgsCross }:

wine.overrideAttrs (attrs: {
  nativeBuildInputs = attrs.nativeBuildInputs ++ [
    # Needed if building with wine32 or wineWow
    pkgsCross.mingw32.buildPackages.gcc

    # Needed if building with wine64 or wineWow
    pkgsCross.mingwW64.buildPackages.gcc
  ];

  # Fixes -Werror=format-security
  hardeningDisable = attrs.hardeningDisable ++ [ "format" ];
})

You should see something like this in your build output:

checking for i686-w64-mingw32-gcc... i686-w64-mingw32-gcc
checking whether i686-w64-mingw32-gcc works... yes

I've had to do something similar when trying build Guy1524's Easy Anti-Cheat fork:
https://github.com/MetaDark/nur-packages/blob/6d867e5b3c14027981a2772d0a8b937120fe24e3/pkgs/misc/emulators/wine-eac/default.nix

@avnik @bendlas @7c6f434c Maybe it would make sense to add a mingwSupport parameter to handle this?

I am not sure what it actually does, but maybe

@MetaDark Thanks a lot for that - I also faced another problem which your linked code sorted - the "compiler cannot create executables" error - strictDeps looks to have solved it though. :+1:

@7c6f434c I can tell you - it uses the mingw compiler to compile "PE DLLs" (I believe this is in reference to Windows PE DLLs but could be wrong.) It then uses these in place of the normal fake builtin DLLs it uses. This enables a much more convincing Windows environment which some apps / games appear to need.

@7c6f434c I can tell you - it uses the mingw compiler to compile "PE DLLs" (I believe this is in reference to Windows PE DLLs but could be wrong.) It then uses these in place of the normal fake builtin DLLs it uses. This enables a much more convincing Windows environment which some apps / games appear to need.

Ahhh makes perfect sense.

Do I understand correctly that build closure grows quite a bit? Any impact on runtime closure? I will merge a PR adding an off-by-default MinGW option, absent some well-grounded onjections, but maybe it should indeed be off-by-default. I guess if runtime closure change is small and build closure change is within 20% or so, we could enable by default…

@7c6f434c I'm not too sure what closure means in this context D: What I will say, however, is that this is OFF by default in most distros so I think it should be added as an option and not enabled by default - just as you suggested.

@MetaDark Your changes got me a lot further in to the build but I believe I am missing one critical change - the build runs correctly and starts building DLLs via mingw but then fails out with:

/build/wine-5.20/dlls/msvcp60/tests/ios.c:1470:9: error: format not a string literal and no format arguments [-Werror=format-security]

Actual overlay pkg (including the fix for exactly this error from your code linked above.) I wonder if mingw is ignoring the hardeningDisable flag or is using defaults somewhere? We're so close to fixing this I can feel it! :+1: :

self: super:

{
  wine-mingw = super.wineWowPackages.full.overrideDerivation (oldAttrs: rec {
    name = "wine-${version}";
    version = "5.20";

    src = super.fetchurl {
      url = "https://dl.winehq.org/wine/source/5.x/wine-${version}.tar.xz";
      sha256 = "0746j29six9cjgxp9pxfw1r67xhi39kvmqaq5yhvmgdyrvw24mcg";
    };

    # Fixes "Compiler cannot create executables" building with wineWow
    strictDeps = true;

    # Intended to fix: -Werror=format-security - ignored by mingw
    hardeningDisable = oldAttrs.hardeningDisable ++ [ "format" ];

    nativeBuildInputs = oldAttrs.nativeBuildInputs ++ [
      # needed for wine32 or wineWow
      super.pkgsCross.mingw32.windows.crossThreadsStdenv.cc

      # needed for wine64 or wineWow
      super.pkgsCross.mingwW64.windows.crossThreadsStdenv.cc
    ];
  });
}

What I will say, however, is that this is OFF by default in most distros

I think Arch builds wine with mingw: https://github.com/archlinux/svntogit-community/blob/packages/wine-staging/trunk/PKGBUILD#L52 (mingw-w64-gcc)

In official wine repos for fedora (https://dl.winehq.org/wine-builds/fedora/33/x86_64/) there are lines:

BuildRequires:  mingw32-gcc
BuildRequires:  mingw64-gcc

and for Ubuntu (https://dl.winehq.org/wine-builds/ubuntu/dists/bionic/main/source/wine-staging_5.21~bionic.dsc), there is mingw-w64 in Build-Depends.

So, if it doesn't increase closure size by too much, I'd say it's a good idea to enable it by default.

@7c6f434c I'm not too sure what closure means in this context D: What I will say, however, is that this is OFF by default in most distros so I think it should be added as an option and not enabled by default - just as you suggested.

Transitive closure: deps, deps-of-deps, deps-of-deps-of-deps-of-deps…

This can go over runtime or build-time dependencies, of course

But yes, no need to look too deeply into impact if the default is off.

@MetaDark Your changes got me a lot further in to the build but I believe I am missing one critical change - the build runs correctly and starts building DLLs via mingw but then fails out with:

/build/wine-5.20/dlls/msvcp60/tests/ios.c:1470:9: error: format not a string literal and no format arguments [-Werror=format-security]

Actual overlay pkg (including the fix for exactly this error from your code linked above.) I wonder if mingw is ignoring the hardeningDisable flag or is using defaults somewhere? We're so close to fixing this I can feel it! :+1:

@cawilliamson Hmm, it worked for me when specifying hardeningDisable. Maybe there is a problem with using overrideDerivation? The Nixpkgs manual strongly recommends using overrideAttrs instead of overrideDerivation. I think it's very likely that's the cause: https://nixos.org/manual/nixpkgs/stable/#sec-pkg-overrideDerivation

@7c6f434c I'll gather information about the closure sizes for each configuration (wine32, wine64, wineWow) and I'll also look into creating a PR that adds a new support flag.

@MetaDark I hadn't noticed that little difference - changed it to overrideAttrs and it's now building properly from the looks of things. Thanks again for all of your help on this - that's super helpful! :+1:

@7c6f434c It looks like it was disabled by default in Gentoo (in: https://gitweb.gentoo.org/repo/gentoo.git/tree/app-emulation/wine-vanilla/wine-vanilla-5.21.ebuild) due to the following bug: https://bugs.gentoo.org/685172

^ This may not be all that relevant to NixOS - just wanted to bring it to your attention.

@cawilliamson Hm, interesting. We'll see.

@MetaDark if it is default-off, feel free to skip the closure-measuring step for anything you are not going to use anyway. No need to build something just for that.

@7c6f434c I noticed that runtime closures were dramatically increased with this option:

  • wine32 (minimal): 829.3M -> 2.6G
  • wine64 (minimal): 912.5M -> 2.6G
  • wineWow (minimal): 1.5G -> 4.9G

It looks like development header files from mingw-64-gcc are being referenced in all DLLS under lib/wine. For example, these paths are referenced in the wine32 build:

/nix/store/4pif79nqpcigcrq3934p0jaijq24dy3v-i686-w64-mingw32-stage-final-gcc-debug-9.3.0/i686-w64-mingw32/sys-include
/nix/store/lwlaj95fph6gbvvcnnzg1pws9vqa1np7-mingw-w64-6.0.0-i686-w64-mingw32-dev/include
/nix/store/xrswl3dhfjb3zi4dri7ijwzp2ql4zjkv-mingw-w64-6.0.0-i686-w64-mingw32-headers/include
/nix/store/xrswl3dhfjb3zi4dri7ijwzp2ql4zjkv-mingw-w64-6.0.0-i686-w64-mingw32-headers/include/psdk_inc

Right now I'm looking into why they're being added and if they can be removed / reduced.

If mingw is disabled by default, perhaps it could be added as a new attribute so that it's cached?

Considering it's enabled by default in (at least) Arch and official wine repos, some users may expect it to be enabled by default in NixOS too. Having to override wine for e.g. lutris and also build wine (which takes a pretty long time) is a lot of friction for an unexperienced NixOS user (or someone with not so powerful hardware).

@wedens Preferably we would enable it by default. Once, binutils 2.34 is merged to nixpkgs which contains the bugfix for stripping wine DLLS we can re-enable stripping to avoid the closure increase caused by the header references.

Considering the OP mentioned specifically games, I'll just mention that lutris now ships (via its "runners" machinery) wine 5.21 with mingw.

@cawilliamson Now that #103358 has been merged you can just use:

wine.override {
  mingwSupport = true;
}

This isn't currently enabled by default or cached, but does this solve your issue? Hopefully we can enable this on the base build once #89793 is merged, and after stripping is enabled.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

copumpkin picture copumpkin  Â·  3Comments

domenkozar picture domenkozar  Â·  3Comments

matthiasbeyer picture matthiasbeyer  Â·  3Comments

teto picture teto  Â·  3Comments

lverns picture lverns  Â·  3Comments