A Haskell adventure in Windows

I’ve been blogging about my recent project using Haskell – a strategy game using SDL. I use GNU/Linux as my primary operating system, Ubuntu 10.4 to be exact, but I wanted to make sure my project can run in Windows too because that’s what my wife uses. This turned out to be much harder than I first anticipated, considering the general ease in which you can code Haskell in linux.

For this post, I’m using a fresh installation of Windows 7 x64 running inside VirtualBox 3.1.6 OSE. Your mileage with other versions of Windows may vary. Installing Haskell and manually installing FFI bindings, as well as installing git tools to clone the source code repository and building it, will all be covered here. This is mostly here to preserve my notes for myself, though maybe someone else on the Internet will find it useful.

The first thing I do is install some basic free software that I find very useful: the great Firefox web browser, a nice programming text editor called Notepad++, a better command line called Console2 and a good archive utility called 7-zip. These packages provide the needed functionality to accomplish everything below, though are not strictly required if you have other software to handle the job.

Installing Haskell, the SDL, SDL-image, SDL-ttf FFI bindings

Installing the Haskell Platform for Windows is easy. You can download the latest version here. I used the 2010.1.0.0 version. Accepting the defaults while installing will be fine. This gives you the GHC compiler and GHCi interpreter and adds the binaries to your PATH environment variable.

The platform only installs commonly used packages and SDL and associated libraries don’t make the cut. Installing the libraries on Windows must be done by hand with edits made to the build files.

Download that SDL development package for MinGW32, SDL-devel-1.2.14-mingw32.tar.gz; then the SDL_image development package, SDL_image-devel-1.2.10-VC.zip; then the SDL_ttf development package, SDL_ttf-devel-2.0.9-VC8.zip .I unzipped all of them to the C:\ folder as shown in this screen shot:

Unzipped SDL and SDL_image folders .

This will provide the c headers and libraries that we’ll need for the Haskell FFI bindings. The first binding we’ll install will be SDL. Go to the SDL page on hackage, and download the SDL-0.5.9.tar.gz archive at the bottom. Unzip it somewhere that’s convenient for you, but the exact location isn’t important.

Inside the SDL-0.5.9 folder there is a WIN32 file that describes the process of building the Haskell bindings on Windows. The following is an abbreviated version:

1. Open the SDL-0.5.9/SDL.cabal file in your favorite editor.

2. Change the line that reads “Extra-Libraries: SDL” to “Extra-Libraries: SDL.dll SDLmain”

3. Below the line you just edited, add the following two lines (corrected from original version):

  Include-Dirs: C:\SDL-1.2.14\include\SDL
  Extra-Lib-Dirs: C:\SDL-1.2.14\lib

4. Open up a command line window – either cmd.exe or use Console2. I run this as administrator because I’ll be using this command line to install the Haskell packages which, by default, end up installing to C:\Program Files (x64).

5. Run the following command:

runghc Setup.lhs configure

You’ll see this error message about the use of a configure script but ignore it:

Error in configuring SDL

6. Run the next two commands. The last one will require admin rights to write to the C:\Program Files (x86)\Haskell folder.

runghc Setup.lhs build
runghc Setup.lhs install

After building the main SDL binding, it is time to build the SDL-image binding. A lot of the steps will be similar to what we just did for SDL. Go to the SDL-image page on hackage and download the SDL-image-0.5.2.tar.gz file. Unzip it somewhere convenient; I put it on my desktop.

1. Open up the SDL-image-0.5.2\SDL-image.cabal file in your favorite editor. Add the following line to the end of the file.

Include-Dirs: C:\SDL_image-1.2.10\include

2. Open up the SDL-image-0.5.2\Graphics\UI\SDL\Image\Version.hsc file and underneath #include “SDL_image.h” add:

#include "SDL.h"
#ifdef main
#undef main
#endif

This fix was originally found here.

3. Run the following commands ignoring the complaints about the configure script:

runghc Setup.lhs configure
runghc Setup.lhs build
runghc Setup.lhs install

Proof that this too can be installed is here:

The last binding necessary is SDL_ttf. The process should be familiar to you now. Go to the SDL-ttf page on hackage and download the SDL-ttf-0.5.5.tar.gz file. Unzip it somewhere.

1. Open up the SDL-ttf-0.5.5\SDL-ttf.cabal file in your favorite editor. Add the following line to the end of the file.

Include-Dirs: C:\SDL_ttf-2.0.9\include

2. Open up the SDL-ttf-0.5.5\Graphics\UI\SDL\TTF\Version.hsc file and underneath #include “SDL_ttf.h” add:

#include "SDL.h"
#ifdef main
#undef main
#endif

3. Run the following commands ignoring the complaints about the configure script:

runghc Setup.lhs configure
runghc Setup.lhs build
runghc Setup.lhs install

I’ll spare the boring screen shot of a terminal.

Installing git and cloning the source code

Per the Pro Git book, I use msysgit to provide the basic git functionality. Do not follow the “InstallMSysGit” wiki page because it will lead you down the wrong path. Just download the full installer for git (Git-1.7.0.2-preview20100309.exe) and install it. I use all of the default settings in the installer except the one regarding the PATH variable – I choose “Run Git from the Windows Command Prompt.”

To get a good difference view, I install the KDiff3 package, which integrates well with the next tool I install. Download the KDiff3 installer and install it.

Next up is the GitExtentions package. This is a nicer GUI for dealing with git. Grab the complete installer here. I install it will all default settings. When it first runs, it will scan your system and try to find the software it wants to use. If you have set up git and kdiff3 as above, it should automatically find them. To complete the GitExtensions setup, switch to the Global settings tab in the Settings window and enter a user name and email. Switch back to the Checklist tab and click the “Save and rescan” button, then the “Ok”button to finish the setup.

Click the “Clone repository” button and use http://github.com/tbogdala/ExitStrategy.git as the repository to clone (link). I set the destination to C:\Projects as that is my standard folder. Click “Clone” to download a copy of the source files.

For more information on git, check out the Pro Git book. The Seeker’s Quill has a good post on using git. There’s also a blog series on lostechies that I found helpful.

Building the game

Now that we have the prerequisite software installed and a copy of the source code for the project we’re all set to go …

Well, not quite. If you perform a cabal configure and build on the project right now you get massive linker errors pointing to SDL-image and SDL-ttf. Undefined reference to ‘IMG_Load_RW’, undefined reference to ‘IMG_Load’, etc …

1. Open up the exitstrategy.cabal file and add these two lines to the end:

  Extra-Lib-Dirs:    C:\SDL_image-1.2.10\lib, C:\SDL_ttf-2.0.9\lib
  Extra-Libraries:   SDL_image, SDL_ttf

2. Go to the C:\SDL_image\lib folder and make a copy of SDL_image.dll and call it libSDL_image.dll.a (lib*.a)

3. Go to the C:\SDL_ttf-2.0.9\lib folder and make a copy of SDL_ttf.dll and call it libSDL_ttf.dll.a, similar to what we did in step 2.

After that, the project will build.

One last step is to make a copy of the following files and place them in C:\Projects\ExitStrategy\dist\build\exitstrategy-editor:

  • C:\SDL-1.2.14\bin\SDL.dll
  • C:\SDL_image-1.2.10\lib\jpeg.dll
  • C:\SDL_image-1.2.10\lib\libpng12-0.dll
  • C:\SDL_image-1.2.10\lib\libtiff-3.dll
  • C:\SDL_image-1.2.10\lib\SDL_image.dll
  • C:\SDL_image-1.2.10\lib\zlib1.dll
  • C:\SDL_ttf-2.0.9\lib\libfreetype-6.dll
  • C:\SDL_ttf-2.0.9\lib\SDL_ttf.dll

Finally, from the C:\Projects\ExitStrategy folder, run “dist\build\exitstrategy-editor\exitstrategy-editor.exe” in the command line. Success!

For now, double clicking on the exitstrategy-editor.exe file won’t work because it won’t find the art/64×74 folder where all of the art is (unless you also copy that folder to the build directory with the dlls). That will be fixed in a future version.

Version History

Apr 26, 2010: Updates: Project name changed to Exit Strategy. Updated the steps to reference the project with the new name. The steps should work with version v0.0.3 as tagged in gitthub.

Apr 19, 2010: Updated to include SDL_ttf for the master git branch. The new steps should fix the problems caused by adding the SDL_ttf dependency, but I have not run through all of the steps from scratch again to verify this. Leave a comment if something doesn’t work.

Apr 17, 2010: Originally published.

6 comments on “A Haskell adventure in Windows

  1. kulam on said:

    thanks for your tutorial! i get the following error, maybe you can help please:

    Setup.lhs:2:2:
    Warning: In the use of `defaultUserHooks’
    (imported from Distribution.Simple):
    Deprecated: “Use simpleUserHooks or autoconfUserHooks, unless you n
    eed Cabal-1.2
    compatibility in which case you must stick with defaultUserHooks”
    Warning: defaultUserHooks in Setup script is deprecated.
    Configuring SDL-0.5.9…
    checking for sdl-config… no
    checking for sdl11-config… no
    configure: error: *** SDL not found! Get SDL from www.libsdl.org.
    If you already installed it, check it’s in the path. If problem remains,
    please send a mail to the address that appears in ./configure –version
    indicating your platform, the version of configure script and the problem.

  2. kulam on said:

    solved it! :)
    add the following environment variable:
    SDL_CONFIG=c:/SDL-1.2.14/bin/sdl-config

    NOTE: you have to use forward slashes!

  3. kulam on said:

    build gives the following error:

    Setup.lhs:2:2:
    Warning: In the use of `defaultUserHooks’
    (imported from Distribution.Simple):
    Deprecated: “Use simpleUserHooks or autoconfUserHooks, unless you n
    eed Cabal-1.2
    compatibility in which case you must stick with defaultUserHooks”
    Preprocessing library SDL-0.6.2…
    distbuildGraphicsUISDLGeneral_hsc_make.o:General_hsc_make.c:(.text+0×0): mu
    ltiple definition of `main’
    C:/Program Files (x86)/Haskell Platform/2010.1.0.0/mingw/bin/../lib/libmingw32.a
    (main.o):main.c:(.text+0×0): first defined here
    C:/SDL-1.2.14/lib/libSDLmain.a(SDL_win32_main.o): In function `console_main’:
    /Users/hercules/trunk/SDL-1.2/./src/main/win32/SDL_win32_main.c:315: undefined reference to `SDL_main’
    collect2: ld returned 1 exit status
    linking distbuildGraphicsUISDLGeneral_hsc_make.o failed
    command was: C:Program Files (x86)Haskell Platform2010.1.0.0mingwbingcc.ex
    e -LC:/SDL-1.2.14/lib -lSDL.dll -lSDLmain -L/usr/local/lib -lmingw32 -lSDLmain -lSDL -mwindows -LC:Program Files (x86)Haskell Platform2010.1.0.0base-4.2.0.0 -lwsock32 -luser32 -lshell32 -LC:Program Files (x86)Haskell Platform2010.1.0.0integer-gmp-0.2.0.0 -LC:Program Files (x86)Haskell Platform2010.1.0.0ghc-prim-0.2.0.0 -LC:Program Files (x86)Haskell Platform2010.1.0.0 -LC:Program Files (x86)Haskell Platform2010.1.0.0/gcc-lib -lm -lwsock32 -LC:Program Files (x86)Haskell Platform2010.1.0.0 distbuildGraphicsUISDLGeneral_hsc_make.o -o distbuildGraphicsUISDLGeneral_hsc_make.exe

  4. With the SDL library, I just ignored the ‘cabal configure’ error output.

    Are you building this manually or trying to use cabal-install?

  5. Nathan Sorenson on said:

    I’m getting the same errors as kulam. I’m trying to install the file manually and I’ve set the paths correctly, as far as I can tell. I’m not sure where to begin in finding out what’s wrong.

  6. Pingback: A review of my Haskell adventure « Binary sculpting