Personal Log »

Cross-compiling Haskell

It is complicated. May be my games aren’t that good or interesting, but if you can only play them if you compile them from source –and besides, written in Haskell–, that is perhaps too niche even for me.

This weekend I put some time into researching it, and there’s some documentation (for example: Cross Compiling GHC), but things don’t quite work. The most interesting issues I have found:

  • Haskell is written in Haskell, so you need a Haskell compiler. Apparently 9.2.5 won’t compile 9.2.5, or I did something wrong. Using 8.10.7 seems to be OK.
  • The cross-compiler is hosted in Linux and the target is Windows, yet the compilation of stage1 tried to include windows.h; which is not available in Linux. I must confess don’t quite understand what was going on, but I couldn’t get past that.

It is slow to try and repeat. Besides, once things fail, there isn’t much I can do.

So I shifted my focus to a different approach: can I run the Windows binaries in Linux using Wine?

It is possible, and I have put together some docs and scripts in cross-compile-hs-wine.

The first part was easy: getting GHC –the Haskell compiler– and Cabal –one of the Haskell’s tools to build Haskell projects– to run using Wine. I mean, is not trivial, but is not too hard. At least for pure Haskell projects, because if your dependencies need a C compiler, or even worse, are bindings to C libraries –like SDL2 and SDL2_Image–, things get very fiddly.

So at the end I had to get everything running in Wine, which includes:

  • Cabal for Windows.
  • GHC for Windows.
  • MingGW-W64, a port of the GCC compiler suite to run in Windows.
  • SDL2 and SDL2_Image development for MinGW.
  • pkg-config-lite, a version of pkg-config for Windows.

Looking around, seems like installing Haskell on Windows (and SDL2) isn’t that easy.

For the second part, because Cabal is awesome, I only had to write a wrapper for it so it can find everything it needs when running from Wine, and after that it was just a couple of issues to get the sdl2 to compile. First I couldn’t get Cabal to find pkg-config, and second I think it might be a bug in sdl2-image –I will open a bug report–.

The compilation is slower than the native Linux versions, and the generated binary doesn’t quite work in the Wine version shipped by my Debian 11 (stable) –tried with unstable from a container, and Wine 8 runs it perfectly–, but this makes things OK: I can build and distribute binaries for Linux and Windows –even if the Windows part is a bit awkward–.

So now I can stop procrastinating and keep working on the game.

Would you like to discuss the post? You can send me an email!