Files

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

315 lines
9.8 KiB
Nix
Raw Permalink Normal View History

2025-10-09 14:15:47 +02:00
{
stdenv,
lib,
pkgArches,
makeSetupHook,
pname,
version,
src,
mingwGccs,
monos,
geckos,
platforms,
bison,
flex,
fontforge,
gettext,
makeWrapper,
pkg-config,
nixosTests,
supportFlags,
wineRelease,
patches,
moltenvk,
buildScript ? null,
configureFlags ? [ ],
mainProgram ? "wine",
}:
with import ./util.nix { inherit lib; };
let
prevName = pname;
prevConfigFlags = configureFlags;
setupHookDarwin = makeSetupHook {
name = "darwin-mingw-hook";
substitutions = {
darwinSuffixSalt = stdenv.cc.suffixSalt;
mingwGccsSuffixSalts = map (gcc: gcc.suffixSalt) mingwGccs;
};
} ./setup-hook-darwin.sh;
# Using the 14.4 SDK allows Wine to use `os_sync_wait_on_address` for its futex implementation on Darwin.
# It does an availability check, so older systems will still work.
darwinFrameworks = lib.optionals stdenv.hostPlatform.isDarwin (
toBuildInputs pkgArches (pkgs: [ pkgs.apple-sdk_14 ])
);
# Building Wine with these flags isnt supported on Darwin. Using any of them will result in an evaluation failures
# because they will put Darwin in `meta.badPlatforms`.
darwinUnsupportedFlags = [
"alsaSupport"
"cairoSupport"
"dbusSupport"
"fontconfigSupport"
"gtkSupport"
"netapiSupport"
"pulseaudioSupport"
"udevSupport"
"v4lSupport"
"vaSupport"
"waylandSupport"
"x11Support"
"xineramaSupport"
];
badPlatforms = lib.optional (
!supportFlags.mingwSupport || lib.any (flag: supportFlags.${flag}) darwinUnsupportedFlags
) "x86_64-darwin";
in
stdenv.mkDerivation (
finalAttrs:
lib.optionalAttrs (buildScript != null) { builder = buildScript; }
// lib.optionalAttrs stdenv.hostPlatform.isDarwin {
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.
for preloader in wine-preloader wine64-preloader; do
rm loader/$preloader &> /dev/null \
&& ( echo "Relinking loader/$preloader"; make loader/$preloader NIX_LDFLAGS="" NIX_LDFLAGS_${stdenv.cc.suffixSalt}="" ) \
|| echo "loader/$preloader not built, skipping relink."
done
'';
}
// {
inherit version src;
pname =
prevName
+ lib.optionalString (wineRelease != "stable" && wineRelease != "unstable") "-${wineRelease}";
# Fixes "Compiler cannot create executables" building wineWow with mingwSupport
strictDeps = true;
nativeBuildInputs =
with supportFlags;
[
bison
flex
fontforge
makeWrapper
pkg-config
]
++ lib.optional gettextSupport gettext
++ lib.optionals mingwSupport (
mingwGccs ++ lib.optional stdenv.hostPlatform.isDarwin setupHookDarwin
);
buildInputs = toBuildInputs pkgArches (
with supportFlags;
(
pkgs:
[
pkgs.freetype
pkgs.perl
pkgs.libunwind
]
++ lib.optional stdenv.hostPlatform.isLinux pkgs.libcap
++ lib.optional stdenv.hostPlatform.isDarwin pkgs.libinotify-kqueue
++ lib.optional cupsSupport pkgs.cups
++ lib.optional dbusSupport pkgs.dbus
++ 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 fontconfigSupport pkgs.fontconfig
++ lib.optional alsaSupport pkgs.alsa-lib
++ lib.optional pulseaudioSupport pkgs.libpulseaudio
++ lib.optional (xineramaSupport && x11Support) pkgs.xorg.libXinerama
++ lib.optional udevSupport pkgs.udev
++ lib.optional vulkanSupport (
if stdenv.hostPlatform.isDarwin then moltenvk else pkgs.vulkan-loader
)
++ lib.optional sdlSupport pkgs.SDL2
++ lib.optional usbSupport pkgs.libusb1
++ lib.optionals gstreamerSupport (
with pkgs.gst_all_1;
[
gstreamer
gst-plugins-base
gst-plugins-good
gst-plugins-ugly
gst-libav
gst-plugins-bad
]
)
++ 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.hostPlatform.isDarwin) [
pkgs.libGLU
pkgs.libGL
pkgs.libdrm
]
++ lib.optionals stdenv.hostPlatform.isDarwin darwinFrameworks
++ lib.optionals x11Support (
with pkgs.xorg;
[
libX11
libXcomposite
libXcursor
libXext
libXfixes
libXi
libXrandr
libXrender
libXxf86vm
]
)
++ lib.optionals waylandSupport (
with pkgs;
[
wayland
wayland-scanner
libxkbcommon
wayland-protocols
wayland.dev
libxkbcommon.dev
libgbm
]
)
)
);
inherit patches;
configureFlags =
prevConfigFlags
++ lib.optionals supportFlags.waylandSupport [ "--with-wayland" ]
++ lib.optionals supportFlags.vulkanSupport [ "--with-vulkan" ]
++ lib.optionals (
(stdenv.hostPlatform.isDarwin && !supportFlags.xineramaSupport) || !supportFlags.x11Support
) [ "--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 ]
# Avoid adding rpath references to non-existent framework `lib` paths.
++ lib.subtractLists darwinFrameworks finalAttrs.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" \
${lib.optionalString (lib.versionAtLeast version "10.1") "--inherit-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"
"stackclashprotection"
]
++ lib.optional (stdenv.hostPlatform.isDarwin) "fortify"
++ lib.optional (supportFlags.mingwSupport) "format";
passthru = {
inherit pkgArches;
tests = { inherit (nixosTests) wine; };
updateScript = src.updateScript or null;
};
meta = {
inherit version;
homepage = "https://www.winehq.org/";
license = with lib.licenses; [ lgpl21Plus ];
sourceProvenance = with lib.sourceTypes; [
fromSource
binaryNativeCode # mono, gecko
];
description = "Open Source implementation of the Windows API on top of X, OpenGL, and Unix";
inherit badPlatforms platforms;
maintainers = with lib.maintainers; [
avnik
bendlas
jmc-figueira
kira-bruneau
raskin
reckenrode
];
inherit mainProgram;
};
}
)