Search code examples
haskellsdlcabal

How can configuration tools like sdl-config be used with a cabalized project?


I have a working SDL/Haskell application that I would like to build using Cabal instead of the current Makefile (because that is the "Haskell way"). The Makefile is itself very simple, and I was hoping that the default cabal build process could allow me to reconstruct a build command specified in my Makefile. The problem is that it makes use of "sdl-config", a utility that gives you all the necessary cc- compiler options:

wrapper.o: SDLWrapper_stub.h
    ghc -no-hs-main `sdl-config --cflags` -Wall wrapper.c -c

Cabal does not seem to expand that into a shell call when calling GHC. How can I specify that sdl-config's options should be fed into GHC when compiling wrapper.o?


Solution

  • Using the configure style in Cabal, you can write a little configure script that substitutes a variable for the output of the sdl-config command. The values will then be replaced in a $foo.buildinfo.in file, yielding a $foo.buildinfo file, that Cabal will include in the build process.

    General solution: the configure script

     #!/bin/sh
    
     SDLFLAGS=`sdl-config --cflags`
     echo Found "$SDLFLAGS"
     sed 's,@SDLFLAGS@,'"$SDLFLAGS"',' z.buildinfo.in > z.buildinfo       
    

    The $foo.builinfo.in file

    cc-options: @SDLFLAGS@
    

    The .cabal file

    Build-type:          Configure
    

    When you run "cabal configure" the "cc-options" field in z.buildinfo will be created to hold:

    cc-options: -I/usr/include/SDL -D_GNU_SOURCE=1 -D_REENTRANT 
    

    which cabal will include in the build.

    Done.

    Specific solution for pkg-config tools

    For tools that support the pkg-config-style of configuration, such as sdl or cairo and others, Cabal has specific support already:

    pkgconfig-depends: package list

    A list of pkg-config packages, needed to build this package. They can be annotated with versions, e.g. gtk+-2.0 >= 2.10, cairo >= 1.0. If no version constraint is specified, any version is assumed to be acceptable. Cabal uses pkg-config to find if the packages are available on the system and to find the extra compilation and linker options needed to use the packages.

    If you need to bind to a C library that supports pkg-config (use pkg-config --list-all to find out if it is supported) then it is much preferable to use this field rather than hard code options into the other fields.

    So for sdl you just need:

    pkgconfig-depends: sdl