Cabalized version of Gtk2Hs now up for testing.

Dear all,

the repo at now contains a cabal version of Gtk2Hs, well, at least of the core packages glib, cairo, pango and gtk. In the future the package gio should be part of this set as well. All other add-on libraries, however, are likely to move into their own darcs repositories. During this transitional period it is not possible to build the other libraries but I encourage people to get the new cabal version using

darcs get

and to add cabal files to the any of these add-on libraries. Notes on that below (”Creating a cabal file for a Gtk2Hs add-on library”).

Observe that updating your current darcs repo of the previous version of Gtk2Hs is not possible since I had to obliterate several patches in order to merge changes. Furthermore, there are quite a few patches in the previous repository that added a lot of new functions but which need further review. These patches have been merged into the new cabal version but for now remain in a separate repository which can be accessed at .


The Gtk2Hs libraries need additional build tools. These live in tools/ and can be configured and installed in the usual Cabal way. The three tools have awkward names starting with gtk2hs and are thus not likely to clash with other programs. If you install as –user, then you need to add ~/.cabal/bin to your path. (I’ve filed a bug that cabal should look in it’s own /bin directory for build utilities. )

When configuring the gtk package, the cabal file will look for Gtk+ 2.20 which you most likely don’t have. You need to specify -f-gtk_2_20 for Gtk+ 2.18 and -f-gtk_2_20 -f-gtk_2_18 for Gtk+ 2.16 and so on. (I have filed a feature request that Cabal should be able to infer the best possible choice of flags for pkg-config requirements. )

When compiling the Setup.hs program, you will see a warning that the Cabal version is guessed. If compilation succeeds, this warning can be ignored. (Cabal should really define CPP macros with it’s version when it builds Setup.hs, see )

Creating a cabal file for a Gtk2Hs add-on library

The Setup.hs file for a Gtk2Hs add-on library will be the same as that for glib, pango, cairo and gtk. Thus, simply copy one of these files to the subdirectory of the add-on library you wish to cabalize. Even better: replace all Setup.hs files by a hard link. It would be good if all setup files remain identical.

The cabal file for a new add-on library is pretty much standard. You need to depend on gtk-0.10.5 and possibly others such as glib-0.10.5. Note that the core packages glib, cairo, pango, gtk will all evolve with the same version.

The category for the core files at the moment is Graphics or Rendering. Note that you could use cairo and pango to create PDF or PNG files without ever touching any GUI stuff. Thus, the category for the other libraries need to be Graphics. It would be interesting to hear if people think that Gtk2Hs should have it’s own category or not.

There are two sets of special fields: x-Types-XXX to build a type hierarchy and x-Signals-XXX to build a callback definitions. You should only need the former. If your package requires callback with arguments not provided in the gtk package then we need to add them to the Gtk package. This is unfortunate, but the infrastructure is not yet adjusted to build package-specific callback definitions.

As to the type hierarchy: The type generator comes with a list of built-in types is located in tools/hierarchyGen/hierarchy.list .
Any of the x-Type-XXX directives are basically specifying arguments to be passed to the type-file generator. You can find out about the arguments it takes by running ~/.cabal/bin/gtk2hsTypeGen without arguments.

For starters, you need to specify where the Types module should live. Use the following two directives:

x-Types-Files: Graphics/UI/MyLib/Types.chs
x-Types-ModName: Graphics.UI.MyLib.Types.chs

Now there are two variants on how you might want to use the type generator:

(a) Building an add-on library that relies only on glib, cairo and/or pango. Specify:

x-Types-Forward: *System.Glib.GObject

(b) Building an add-on library that depends on the gtk package. Specify:

x-Types-Forward: *System.Glib.GObject *Graphics.UI.Gtk.Types
x-Types-Destructor: objectUnrefFromMainloop

The deeper meaning of the different is that any library building on Gtk is assumed to be GUI library that interacts with X11 or Win32 and, thus, any object that is destroyed may release an X11 or Win32 resource which, in turn, may not be done from arbitrary threads. The above option ensures that the freeing happens in the Gtk+ main loop which ensure that the objects are freed from the correct thread. Libraries building on glib, cairo and pango do not interact with X11 or Win32 nor do they have a main loop. Here, freeing objects is done directly by GHC’s garbage collector.

One note for gstreamer: This package requires two type hierarchies. This is currently not supported by the Setup.hs script but it should not be too hard to add this.

The files of each individual add-on libraries are often .chs, .chs.pp and .hsc files. No changes are normally necessary for .chs and .hsc files. Since Cabal is not able to run more than one pre-processor on a file (it cannot handle several extensions) every .chs.pp file must be renamed and a {-# LANGUAGE CPP #-} directive must be prepended to the file. I used the following bash script to do this:

#! /bin/bash
NEW=`dirname $1`/`basename $1 .pp`;
rm -f $NEW
darcs mv $OLD $NEW
mv $NEW “$NEW”.tmp
echo “{-# LANGUAGE CPP #-}” > $NEW
cat “$NEW”.tmp >> $NEW
rm “$NEW”.tmp

(save this in In order to convert all files in the library myLib do:

find myLib -name “*.chs.pp” -exec ./ “{}” \;

in the directory containing myLib.

You need to add any other language extension to each individual file that need it (e.g. replace “CPP” with “CPP, ScopedTypeVars” or whatever). Note that any file that is now called .chs and has a CPP directive in its first line is now run through cpp by our home-grown c2hs variant (making it even more incompatible with the mainstream c2hs).

A note on the new Setup

For those who are curious how the Gtk2Hs Setup.hs differs from Simple, the changes are as follows:

- during configuring, the signal and type files are generated. Both only happen if the appropriate x-Signals- and x-Types- fields are specified in the cabal file.

- our home grown c2hs is run on .chs files instead of the mainstream one

- our c2hs files produces .chi files that must be available to other packages, just like .hi files. These .chi files are therefore copied during installation of files

- before pre-processing the .chs files, we calculate the dependencies between the files and rearrange the list of files to build such that the dependencies are honored

That’s it!

Any feedback appreciated,
Axel (on behalf of the Gtk2Hs developers)

6 Responses to “Cabalized version of Gtk2Hs now up for testing.”

  1. Tim Says:

    This is excellent news - well done on the progress made.

    I will try it out soon….

  2. dtm Says:

    Hey Alex,
    I couldn’t access the repository at,
    so I downloaded the newer version you mention.
    However, I’m having problems installing it on windows.
    Basically, in msys I cd to the tools subdirectory, and run
    runhaskell Setup.hs configure
    …. …. build
    …. …. install
    By default, this installs everything at C:/Program Files/Haskell/bin
    Now when I go to build cairo (by cd’ing to the cairo subdirectory of
    the downloaded package),
    I run:
    runhaskell Setup.hs configure
    runhaskell Setup.hs build

    However the build step fails witht the output:
    Creating dist\build (and its parents)
    Creating dist\build\autogen (and its parents)
    Preprocessing library cairo-0.10.5…
    Creating dist\build\Graphics\Rendering\Cairo (and its parents)
    c:\Program Files\Haskell\bin\gtk2hsC2hs.exe –include=dist\build –include=C:\Users\James\Desktop\Dan\bin\HaskellPlatform_2009.2.0.2\array- –include=C:\Users\James\Desktop\Dan\bin\HaskellPlatform_2009.2.0.2\base- –include=C:\Users\James\Desktop\Dan\bin\HaskellPlatform_2009.2.0.2\bytestring- –include=C:\Users\James\Desktop\Dan\bin\HaskellPlatform_2009.2.0.2\haskell98- –include=C:\Users\James\Desktop\Dan\bin\HaskellPlatform_2009.2.0.2\mtl- –cppopts=-Ic:/devel/gtk/include/cairo –cppopts=-Ic:/devel/gtk/include/freetype2 –cppopts=-Ic:/devel/gtk/include –cppopts=-Ic:/devel/gtk/include/libpng14 –output-dir=dist\build\Graphics\Rendering\Cairo –output=Graphics\Rendering\Cairo\Matrix.hs –precomp=dist\build\precompchs.bin cairo-gtk2hs.h .\Graphics\Rendering\Cairo\Matrix.chs
    gtk2hsC2hs.exe: does not exist

    However, I have added gtk2hsC2hs.exe to my path.
    Might it be something to do with the space in the pathname?
    I’d try and figure it out myself, but I don’t know how to undo the
    original installation of the tools directory (I tried to just rerun
    setup for the tools using a different prefix but the build step
    for cairo continues to look in the old place). Any ideas?

  3. Sergey Shepelev Says:

    Darcs seems to use some kind of SSH and it wants password to authenticate.

    $ darcs get

  4. Live Amateurs Says:

    Nice site, favorited!

  5. andrew Says:

    When I run

    darcs get

    it asks me for a password which I don’t know. Is the address correct?

  6. IvanP Says:

    @dtm: Yes, it has something to do with the whitespace. At least, I solved by copying gtk2hsC2hs.exe to a path with no whitespace in its name. Apparently, having it in the PATH env variable was not enough.

Leave a Reply