MinGW package guidelines
32-bit – CLR – CMake – Cross – DKMS – Eclipse – Electron – Font – Free Pascal – GNOME – Go – Haskell – Java – KDE – Kernel modules – Lisp – Meson – MinGW – Node.js – Nonfree – OCaml – Perl – PHP – Python – R – Ruby – Rust - Security – Shell – VCS – Web – Wine
This page explains how to write PKGBUILDs for software running on Windows using GCC. There are two options to build software for Windows on Linux:
- mingw-w64: provides 32 and 64-bit toolchains with secure crt, Vista+ API, DDK (ReactOS), and DirectX (WINE) support. For a full list of supported features and differences with the old MinGW.org, see here. Available from the official repositories by installing mingw-w64-gcc.
- MinGW: provides 32-bit toolchains with limited DirectX support. It also suffers from long-standing breakage in the implementation of thread-local storage and the floating point library support. It has been removed from the official repositories and the AUR.
Package naming
A package for mingw-w64 should be named mingw-w64-pkgname
. If a static variant of the package is being built, suffix the package name with -static
(see below for the cases where this is necessary).
Packaging
Packaging for cross platform packages can be fairly tricky as there are many different build systems and low-level quirks. Take a note of the following things though:
- always add mingw-w64-crt to
depends
, unless it depends on another package which implicitly depends on it - always add mingw-w64-gcc to
makedepends
, unless using mingw-w64-configureAUR or mingw-w64-cmakeAUR - always add
!strip
,staticlibs
and!buildflags
tooptions
- always use the original
pkgdesc
and append(mingw-w64)
to the end ofpkgdesc
- always use and follow the original
pkgver
of the official package - always build both 32-bit and 64-bit versions of libraries
- always put all stuff under the
/usr/i686-w64-mingw32
and/usr/x86_64-w64-mingw32
prefix - always use
any
as the architecture (unless the package contains executables which must run on the build system) - always build both shared and static libraries
- autotools-based projects often support building both in one go, when using mingw-w64-configureAUR shared and static libraries are both enabled
- if the build system or project does not support this, build both separately
- if the shared and static build conflict (e.g. because headers or CMake configuration files differ) consider installing static libraries into
/usr/i686-w64-mingw32/static
and/usr/x86_64-w64-mingw32/static
- for bigger projects, consider creating a separate
-static
package
- consider removing unneeded documentation (
rm -r $pkgdir/usr/i686-w64-mingw32/share/{doc,info,man}
,rm -r $pkgdir/usr/x86_64-w64-mingw32/share/{doc,info,man}
) - consider using mingw-w64-configureAUR for building with configure scripts
- consider using mingw-w64-cmakeAUR for building with CMake
- consider using mingw-w64-mesonAUR for building with Meson
- consider using mingw-w64-makeAUR for building with raw Makefiles
- consider using mingw-w64-qt5-baseAUR for building with QMake
- consider explicitly stripping symbols with
${_arch}-strip
inpackage()
's for-loop as demonstrated in the below PKGBUILD examples.- consider using the find command to iterate over
$pkgdir
since not all DLLs, static libraries, or executables may reside in their appropriate locations.- if the binary is a DLL, use
${_arch}-strip --strip-unneeded *.dll
- if the binary is a static lib, use
${_arch}-strip -g *.a
- if the binary is a DLL, use
- consider using the find command to iterate over
- if a package is modular (requires certain build dependencies, but said dependencies are optional to the end user) add these to
makedepends
andoptdepends
. Be sure to subtract them fromdepends
if updating an existing package. Example of this in use: mingw-w64-qt6-baseAUR - if a package installs a
$pkgdir/usr/${_arch}/bin/*-config
script, symlink it to$pkgdir/usr/bin/${_arch}-*-config
- if a package uses autoconf, explicitly set
--build="$CHOST"
forconfigure
to workaround autoconf bug #108405 or use mingw-w64-configureAUR
As mentioned above, the files should all be installed into /usr/i686-w64-mingw32
and /usr/x86_64-w64-mingw32
. Specifically, all DLLs should be put into /usr/*-w64-mingw32/bin
as they are dynamic libraries needed at runtime. Their corresponding .dll.a
files should go into /usr/*-w64-mingw32/lib
. Please delete any unnecessary documentation and perhaps other files from /usr/share
. Cross-compilations packages are not meant for the user but only for the compiler and binary distribution, and as such you should try to make them as small as possible.
Always try to match the pkgver
in your mingw-w64 packages to the pkgver
of the corresponding regular packages in the official Arch Linux repos (not the testing repos). This ensures that the cross-compiled software works exactly the same way on Windows without any unexpected bugs. If packages in Arch are out-of-date, there usually is a good reason and you should still follow the Arch version instead of using the most recent upstream release. If the corresponding native package is in the AUR, you need not follow this version policy, as many AUR packages are often orphaned or left unmaintained.
Examples
The following examples will try to cover some of the most common conventions and build systems.
Autotools
pkgname=mingw-w64-foo pkgver=1.0 pkgrel=1 pkgdesc="Foo bar (mingw-w64)" arch=('any') url="http://www.foo.bar" license=('GPL') makedepends=('mingw-w64-configure') depends=('mingw-w64-crt') options=('!strip' '!buildflags' 'staticlibs') source=("http://www.foo.bar/foobar.tar.gz") sha256sums=('8f32d4617390d1c2d16f26a27ab60d97807b35440d45891fa340fc2648b04406') _architectures="i686-w64-mingw32 x86_64-w64-mingw32" build() { cd foo-$pkgver for _arch in ${_architectures}; do mkdir -p build-${_arch} && pushd build-${_arch} ${_arch}-configure .. make popd done } package() { for _arch in ${_architectures}; do cd "foo-$pkgver/build-${_arch}" make DESTDIR="${pkgdir}" install ${_arch}-strip --strip-unneeded "$pkgdir"/usr/${_arch}/bin/*.dll ${_arch}-strip -g "$pkgdir"/usr/${_arch}/lib/*.a done }
CMake
pkgname=mingw-w64-foo pkgver=1.0 pkgrel=1 pkgdesc="Foo bar (mingw-w64)" arch=('any') url="http://www.foo.bar" license=('GPL') makedepends=('mingw-w64-cmake') depends=('mingw-w64-crt') options=('!strip' '!buildflags' 'staticlibs') source=("http://www.foo.bar/foobar.tar.gz") sha256sums=('8f32d4617390d1c2d16f26a27ab60d97807b35440d45891fa340fc2648b04406') _architectures="i686-w64-mingw32 x86_64-w64-mingw32" build() { cd foo-$pkgver for _arch in ${_architectures}; do ${_arch}-cmake -B build-${_arch} . make -C build-${_arch} done } package() { for _arch in ${_architectures}; do cd "foo-$pkgver/build-${_arch}" make DESTDIR="${pkgdir}" install ${_arch}-strip --strip-unneeded "$pkgdir"/usr/${_arch}/bin/*.dll ${_arch}-strip -g "$pkgdir"/usr/${_arch}/lib/*.a done }