aboutsummaryrefslogtreecommitdiff

Cross-compile Haskell on Linux targeting Windows using WINE

This is aimed at Linux + Haskell + SDL2 + SDL2_Image, but it could be used for other cases.

The main idea is to run the Windows version of all the needed compilers, on Linux using Wine. Cabal it is the entry point and it needs a script wrapping it so it runs with Wine and it can find the needed tools.

It comes with no warranty, I'm documenting this for myself, and sharing it because it is fiddly and I hope that it might help other people.

What is needed:

  • Cabal for Windows
  • GHC for Windows
  • MingGW-W64
  • SDL2 and SDL2_Image development for MinGW
  • pkg-config-lite for Windows
  • Wine on a Linux host (used Debian 11)
  • Patience and luck!

Install Wine with:

sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get install --no-install-recommends -y wine wine32 wine64

(or similar, I don't think it matters much as long it is a healthy Wine installation)

bootstrap script

Edit the bootstrap script (you may need to adapt it to your system), and check that you are happy with the versions. It is a convenient way of setting up everything for me, but may not be useful for anybody else (also: it is a bit fragile).

It requires: wget, 7z, unzip, tar and make (among other more common POSIX tools).

The directory structure will be:

  • cache: where the requirements are downloaded.
  • packages: where the different Windows tools are setup.
  • workdir: where you should put your project (can be in any directory).
  • bin: contains cabal-wine helper.

Currently I'm using:

  • Cabal 3.8.1.0
  • GHC 9.2.5
  • MinGW-W64 12.2.0
  • SDL2 2.26.3
  • SDL2_Image 2.6.3

Important: you need to copy SDL2.dll and SDL2_image.dll to your system32 directory in Wine, usually:

~/.wine/drive_c/windows/system32/

This is needed to compile sdl2 and sdl2-image. When you have your binary, you need to distribute those two DLLs with your exe.

Updating packages

Run bin/cabal-wine update and Cabal should download the latest package list from hackage.

Building your project

Get into workdir/your-project and run:

../../bin/cabal-wine build --builddir build

And it should work!

Troubleshooting

Extra logging

Pass -v option when running cabal-wine for extra output (useful with pkg-config issues).

Failed to compile SDL2_Image

I have found that SDL2_Image is trying to include a SDL_Main when is not necessary.

Once you have compiled sdl2, you can edit packages/mingw64/x86_64-w64-mingw32/include/SDL2/SDL.h and comment out the #include "SDL_main.h" line.

There must be a better way of fixing this (perhaps a bug report to sdl2-image could help!).

Wine can't run the resulting binary

I use Debian stable, and the Wine version can be a bit old. It compiles fine, but running the resulting binary may not work. Try a more recent Wine version (tested with 8 and works fine).