Dear all,

the repo at code.haskell.org 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 code.haskell.org:/srv/code/gtk2hs

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 http://www2.in.tum.de/~simona/gtk2hs-2.18 .

Building
--------

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. 
http://hackage.haskell.org/trac/hackage/ticket/663 
  )

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. 
http://hackage.haskell.org/trac/hackage/ticket/662 
  )

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 http://hackage.haskell.org/trac/hackage/ticket/326 
  )

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
OLD=$1;
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 change.sh). In order to convert all files in the library  
myLib do:

find myLib -name "*.chs.pp" -exec ./change.sh "{}" \;

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)


------------------------------------------------------------------------------
_______________________________________________
Gtk2hs-devel mailing list
Gtk2hs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/gtk2hs-devel

Reply via email to