Skip to content

Instantly share code, notes, and snippets.

@startergo
Last active May 2, 2026 19:53
Show Gist options
  • Select an option

  • Save startergo/7a9088993ab3c7fc23319704751ed09a to your computer and use it in GitHub Desktop.

Select an option

Save startergo/7a9088993ab3c7fc23319704751ed09a to your computer and use it in GitHub Desktop.
Building win32 wine libraries
FROM --platform=linux/amd64 archlinux:base-devel
RUN sed -i '/^#\[multilib\]/{N;s/#\[multilib\]\n#Include/\[multilib\]\nInclude/}' /etc/pacman.conf && \
pacman-key --init && \
pacman -Syu --noconfirm --disable-sandbox && \
pacman -S --noconfirm --disable-sandbox \
wget \
mingw-w64-gcc \
mingw-w64-binutils \
mingw-w64-crt \
mingw-w64-headers \
mingw-w64-winpthreads \
flex \
bison \
mesa \
lib32-gcc-libs \
lib32-glibc
ARG WINE_VERSION=8.0.2
ARG WINE_BRANCH=8.0
RUN wget https://dl.winehq.org/wine/source/${WINE_BRANCH}/wine-${WINE_VERSION}.tar.xz && \
tar xf wine-${WINE_VERSION}.tar.xz && \
cd wine-${WINE_VERSION} && \
./configure \
--without-x \
--without-alsa --without-capi --without-cups --without-dbus \
--without-fontconfig --without-freetype --without-gphoto \
--without-gstreamer --without-krb5 --without-ldap \
--without-openal --without-opencl --without-openssl \
--without-pcap --without-pulse --without-sane \
--without-sdl --without-udev --without-usb \
--without-v4l2 --without-vulkan \
--without-oss && \
make -j$(nproc) \
dlls/wined3d/i386-windows/wined3d.dll \
dlls/d3d9/i386-windows/d3d9.dll \
dlls/d3d8/i386-windows/d3d8.dll \
dlls/ddraw/i386-windows/ddraw.dll && \
mkdir -p /output/${WINE_VERSION} && \
cp dlls/wined3d/i386-windows/wined3d.dll \
dlls/d3d9/i386-windows/d3d9.dll \
dlls/d3d8/i386-windows/d3d8.dll \
dlls/ddraw/i386-windows/ddraw.dll \
/output/${WINE_VERSION}/ && \
printf "Built on %s\n binutils %s\n crt-git %s\n gcc-libs %s\n" \
"$(date '+%T %b %-e %Y')" \
"$(pacman -Q mingw-w64-binutils | awk '{print $2}')" \
"$(pacman -Q mingw-w64-crt | awk '{print $2}')" \
"$(pacman -Q gcc-libs | awk '{print $2}')" \
> /output/${WINE_VERSION}/build-timestamp && \
cd / && rm -rf wine-${WINE_VERSION}*
# Maintainer: startergo
# Run this in an MSYS2 MINGW32 shell:
# MINGW_ARCH=mingw32 makepkg-mingw -sCLf
#
# To build a specific version:
# WINE_BUILD_VER=1.9.7 MINGW_ARCH=mingw32 makepkg-mingw -sCLf
#
# Builds wined3d.dll, d3d8.dll, d3d9.dll, ddraw.dll as Win32 PE binaries
# for use with qemu-3dfx VMAddons (wine-get script).
_realname=wine-wined3d-legacy
pkgbase=mingw-w64-${_realname}
pkgname="${MINGW_PACKAGE_PREFIX}-${_realname}"
# Override with: WINE_BUILD_VER=x.y.z makepkg-mingw ...
_wine_ver="${WINE_BUILD_VER:-1.8.7}"
pkgver="${_wine_ver}"
pkgrel=1
pkgdesc="Wine wined3d/d3d8/d3d9/ddraw PE DLLs v${_wine_ver} for qemu-3dfx (mingw-w64)"
arch=('any')
mingw_arch=('mingw32')
url="https://www.winehq.org"
license=('LGPL2.1')
makedepends=(
"${MINGW_PACKAGE_PREFIX}-gcc"
"${MINGW_PACKAGE_PREFIX}-binutils"
"gcc" # native GCC for building Wine host tools
"flex"
"bison"
"make"
"autoconf"
)
# Version-specific source URL: 1.x/2.x use .bz2, 3.x/4.x use .xz
# Branch: 4.12.1 is on 4.x, all others match major.minor
_wine_major=$(echo ${_wine_ver} | cut -d. -f1)
_wine_minor=$(echo ${_wine_ver} | cut -d. -f2)
case "${_wine_ver}" in
1.8.*) _branch="1.8"; _ext="bz2" ;;
1.9.*) _branch="1.9"; _ext="bz2" ;;
2.0.*) _branch="2.0"; _ext="bz2" ;;
3.0.*) _branch="3.0"; _ext="xz" ;;
4.*) _branch="4.x"; _ext="xz" ;;
*) _branch="${_wine_major}.${_wine_minor}"; _ext="xz" ;;
esac
_source_url="https://dl.winehq.org/wine/source/${_branch}/wine-${_wine_ver}.tar.${_ext}"
source=("wine-${_wine_ver}.tar.${_ext}::${_source_url}")
sha256sums=(
# 1.8.7
# 22f3a313f4923e03c8c45622775302abc166387a9108ace9ad42d54334641df8
# 1.9.7
# 49705fe02505e26ef8022c662dda702cfcd5c4fd73886e00b43d32dc2f8887ec
# 2.0.5
# 342c55d37ea85ea24a2ae47df7fd1006dd48a80bc4c2fe49e30bed9114e0e118
# 3.0.5
# dc429095b564abe45306b957f3f27d426fb37e365b4dee3ec8d61dc66e8ce211
# 4.12.1
# a0cf2d6925c60344367e0197760c84be738c56c50d559ac20cc19330c572d227
'SKIP'
)
build() {
local _srcdir="${srcdir}/wine-${_wine_ver}"
local _nativedir="${srcdir}/build-native"
local _crossdir="${srcdir}/build-cross"
# ----------------------------------------------------------------
# Stage 1: Build Wine host tools natively (makedep, winebuild,
# wrc, widl). These need to run on the build machine (MSYS2/Linux)
# to process .spec files and .idl files during the cross-compile.
# ----------------------------------------------------------------
mkdir -p "${_nativedir}"
cd "${_nativedir}"
# Use the system gcc (not MinGW) for the native tools
CC=gcc CXX=g++ \
"${_srcdir}/configure" \
--without-x \
--without-alsa \
--without-capi \
--without-cups \
--without-dbus \
--without-fontconfig \
--without-freetype \
--without-gphoto \
--without-gstreamer \
--without-opencl \
--without-pcap \
--without-pulse \
--without-sane \
--without-oss
# Build only the host-side tools needed for cross-compilation
# Wine 1.x-2.x: targets are in tools/ flat layout
# Wine 3.x-4.x: targets are tools/winebuild, tools/wrc, tools/widl
make -j$(nproc) \
tools/makedep \
tools/winebuild \
tools/wrc \
tools/widl \
2>/dev/null || \
make -j$(nproc) \
makedep \
winebuild \
wrc \
widl
# ----------------------------------------------------------------
# Stage 2: Cross-compile the PE DLLs using MinGW
# In MSYS2, MINGW_CHOST=i686-w64-mingw32 (in MINGW32 shell)
# ----------------------------------------------------------------
mkdir -p "${_crossdir}"
cd "${_crossdir}"
"${_srcdir}/configure" \
--host="${MINGW_CHOST}" \
--with-wine-tools="${_nativedir}" \
--without-x \
--without-alsa \
--without-capi \
--without-cups \
--without-dbus \
--without-fontconfig \
--without-freetype \
--without-gphoto \
--without-gstreamer \
--without-opencl \
--without-pcap \
--without-pulse \
--without-sane \
--without-oss
make -j$(nproc) \
dlls/wined3d \
dlls/d3d9 \
dlls/d3d8 \
dlls/ddraw
}
package() {
local _crossdir="${srcdir}/build-cross"
local _outdir="${pkgdir}/${MINGW_PREFIX}/share/wine-dlls/${_wine_ver}"
mkdir -p "${_outdir}"
install -Dm755 "${_crossdir}/dlls/wined3d/wined3d.dll" "${_outdir}/wined3d.dll"
install -Dm755 "${_crossdir}/dlls/d3d9/d3d9.dll" "${_outdir}/d3d9.dll"
install -Dm755 "${_crossdir}/dlls/d3d8/d3d8.dll" "${_outdir}/d3d8.dll"
install -Dm755 "${_crossdir}/dlls/ddraw/ddraw.dll" "${_outdir}/ddraw.dll"
# Generate build-timestamp matching qemu-3dfx wine-get format:
# Built on HH:MM:SS Mon D YYYY
# binutils X.Y-Z
# crt-git X.Y.Z.rN.gHASH-R
# gcc-libs X.Y.Z-R
local _binutils_ver _crt_ver _gcclibs_ver
_binutils_ver=$(pacman -Q "${MINGW_PACKAGE_PREFIX}-binutils" 2>/dev/null \
| awk '{print $2}' || echo "unknown")
_crt_ver=$(pacman -Q "${MINGW_PACKAGE_PREFIX}-crt-git" 2>/dev/null \
| awk '{print $2}' || \
pacman -Q "${MINGW_PACKAGE_PREFIX}-crt" 2>/dev/null \
| awk '{print $2}' || echo "unknown")
_gcclibs_ver=$(pacman -Q "${MINGW_PACKAGE_PREFIX}-gcc-libs" 2>/dev/null \
| awk '{print $2}' || echo "unknown")
printf "Built on %s\n binutils %s\n crt-git %s\n gcc-libs %s\n" \
"$(date '+%T %b %-e %Y')" \
"${_binutils_ver}" \
"${_crt_ver}" \
"${_gcclibs_ver}" \
> "${_outdir}/build-timestamp"
# Also install a convenience script matching wine-get's expected layout
# so output can be dropped directly into qemu-3dfx VMAddons wine/ folder
msg2 "DLLs installed to: ${MINGW_PREFIX}/share/wine-dlls/${_wine_ver}/"
msg2 "Copy to qemu-3dfx extra/addons/win32/wine/${_wine_ver}/"
}

Build and extract:

# Build
docker build --platform linux/amd64 -t wine-dll-builder .

# Extract the DLLs from the container
mkdir -p ~/Downloads/wine-docker/wine-dlls/8.0.2
docker cp extract:/output/8.0.2/. ~/Downloads/wine-docker/wine-dlls/8.0.2/

To build multiple versions in one go:

for ver in "8.0.2:8.0" "7.0.2:7.0" "6.0.4:6.0"; do
    WINE_VERSION=${ver%%:*}
    WINE_BRANCH=${ver##*:}
    docker build --platform linux/amd64 \
        --build-arg WINE_VERSION=$WINE_VERSION \
        --build-arg WINE_BRANCH=$WINE_BRANCH \
        -t wine-dll-builder:$WINE_VERSION .
    docker create --name extract-$WINE_VERSION wine-dll-builder:$WINE_VERSION
    mkdir -p ~/Downloads/wine-docker/wine-dlls/$WINE_VERSION
    docker cp extract-$WINE_VERSION:/output/$WINE_VERSION/. \
        ~/Downloads/wine-docker/wine-dlls/$WINE_VERSION/
    docker rm extract-$WINE_VERSION
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment