[Haskell-cafe] Re: Using Gtk2Hs version 0.9.12 on a PPC Mac

Thorkil Naur naur at post11.tele.dk
Sat Jul 28 11:08:26 EDT 2007


Hello,

On Saturday 28 July 2007 14:22, Duncan Coutts wrote:
> On Sat, 2007-07-28 at 12:16 +0200, Thorkil Naur wrote:
> > Hello,
> > 
> > (From the archives:)
> > > [Haskell] ANNOUNCE: Gtk2Hs version 0.9.12 released
> > > Duncan Coutts duncan.coutts at worc.ox.ac.uk 
> > > Fri Jul 27 15:20:57 EDT 2007 
> > 
> > > Gtk2Hs - A GUI Library for Haskell based on Gtk+
> > 
> > > Version 0.9.12 is now available from:
> > > ...
> > > Duncan
> > > (on behalf of the Gtk2Hs team)
> > 
> > Following the advice of nominolo_ from #haskell yesterday, I added 
> > -L/opt/local/lib to my ghc command and then the helloworld demo of Gtk2Hs 
> > worked. The problem seems to be the order in which the two library 
> > directories /usr/X11R6/lib and /opt/local/lib appear on the link command: 
For 
> > the GTK+ example that worked, /opt/local/lib comes first. For the Gtk2Hs 
demo 
> > that failed, /usr/X11R6/lib comes first.
> 
> That's very interesting.
> 
> > I compared these two directories and found these common files:
> 
> [...]
> 
> > Since some of these (Xrender, fontconfig, and freetype) are actually used 
in 
> > GTK+ (and therefore also Gtk2Hs) applications, there is clearly a 
potential 
> > for conflict here.
> 
> Certainly and if I recall correctly, the gdb backtrace you got showed
> that it was failing in a call to a fontconfig function.

A good guess:

> (gdb) run
> Starting 
program: /Users/thorkilnaur/tn/Gtk2Hs/gtk2hs-0.9.12/demo/hello/helloworld
> Reading symbols for shared libraries .+....+++++...++...+.+.
+...............................................++++. done

> Program received signal EXC_BAD_ACCESS, Could not access memory.
> Reason: KERN_PROTECTION_FAILURE at address: 0x00000001
> FcFontSetSort (config=0x0, sets=0xbfffba50, nsets=2, p=0x2114fb0, trim=1, 
csp=0x0, result=0xbfffbb18) at fcmatch.c:696
> ...


> 
> > In any case, adding -L/opt/local/lib to the ghc command makes this library 
> > appear before /usr/X11R6/lib on the link command and this seems to solve 
the 
> > problem. Subsequently, I have tried a handful of the other demos, and as 
far 
> > as they didn't require something that wasn't available (glade, for 
example), 
> > they seemed to work.
> 
> So what I wonder is how we can make this work reliably. We use the flags
> that pkg-config tells us to use, I'd rather not add platform-specific
> hacks if we can get the pkg-config settings fixed. So I presume when you
> run pkg-config --libs gtk+-2.0 it does not list -L/opt/local/lib, or if
> it does it lists it after -L/usr/X11R6/lib. Is that the case?

For the GTK+ tutorial helloworld.c program:

> $ pkg-config --libs gtk+-2.0
> -L/Users/thorkilnaur/tn/install/gtk+-2.10.14/lib -L/opt/local/lib 
-L/usr/X11R6/lib -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgdk_pixbuf-2.0 -lm 
-lpangocairo-1.0 -lpango-1.0 -lcairo -lSM -lICE -lgobject-2.0 -lgmodule-2.0 
-lglib-2.0 -lintl -liconv -lfreetype -lz -lfontconfig -lpng12 -lXrender -lX11
> $ gcc -v -Wall -g helloworld.c -o helloworld `pkg-config --cflags gtk+-2.0` 
`pkg-config --libs gtk+-2.0`
> ...
>  /usr/libexec/gcc/powerpc-apple-darwin8/4.0.1/collect2 -dynamic -arch ppc 
-weak_reference_mismatches non-weak -o helloworld 
-lcrt1.o /usr/lib/gcc/powerpc-apple-darwin8/4.0.1/crt2.o 
-L/Users/thorkilnaur/tn/install/gtk+-2.10.14/lib -L/opt/local/lib 
-L/usr/X11R6/lib -L/usr/lib/gcc/powerpc-apple-darwin8/4.0.1 
-L/usr/lib/gcc/powerpc-apple-darwin8/4.0.1 
-L/usr/lib/gcc/powerpc-apple-darwin8/4.0.1/../../.. /var/tmp//cctkdfsu.o 
-lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgdk_pixbuf-2.0 -lm -lpangocairo-1.0 
-lpango-1.0 -lcairo -lSM -lICE -lgobject-2.0 -lgmodule-2.0 -lglib-2.0 -lintl 
-liconv -lfreetype -lz -lfontconfig -lpng12 -lXrender -lX11 -lgcc 
-lSystemStubs -lSystem
> $

Scrutinizing the link arguments output by gcc, it appears that the -Ls and the 
-ls specified on the gcc command have been separated and inserted between 
other -Ls and -ls supplied by gcc. But the order of the -Ls produced by 
pkg-config is retained and, as mentioned, this is the case that works without 
change.

For the Gtk2Hs demo World.hs program, the matter is more complex, especially 
since the link arguments generated by ghc presumably goes via ghc-pkg that I 
have never studied in detail before. But let me venture a guess anyway.

First we look at the gtk package and its dependents:

> $ for p in gtk-0.9.12 glib-0.9.12 cairo-0.9.12; do echo $p: `ghc-pkg field 
$p depends`; done
> gtk-0.9.12: depends: base-2.0 mtl-1.0 glib-0.9.12 cairo-0.9.12
> glib-0.9.12: depends: base-2.0
> cairo-0.9.12: depends: base-2.0 mtl-1.0 glib-0.9.12
> $

Further:

> $ for p in gtk-0.9.12 glib-0.9.12 cairo-0.9.12; do echo $p: `ghc-pkg field 
$p library-dirs`; done
> gtk-0.9.12: 
library-dirs: /Users/thorkilnaur/tn/install/gtk+-2.10.14/lib /usr/X11R6/lib /Users/thorkilnaur/tn/install/gtk2hs-0.9.12/lib/gtk2hs
> glib-0.9.12: 
library-dirs: /opt/local/lib /Users/thorkilnaur/tn/install/gtk2hs-0.9.12/lib/gtk2hs
> cairo-0.9.12: 
library-dirs: /opt/local/lib /usr/X11R6/lib /Users/thorkilnaur/tn/install/gtk2hs-0.9.12/lib/gtk2hs
> $

The actual link arguments constructed by ghc when compiling World.hs are:

> $ ghc -v --make World.hs -o helloworld
> ...
> Linking helloworld ...
> *** Linker:
> gcc -v -o helloworld World.o 
-L/Users/thorkilnaur/tn/install/gtk+-2.10.14/lib -L/usr/X11R6/lib 
-L/Users/thorkilnaur/tn/install/gtk2hs-0.9.12/lib/gtk2hs -L/opt/local/lib 
-L/Users/thorkilnaur/tn/install/ghc-6.6-for-buildbot-20070221_1000/lib/ghc-6.6.20070220 
-lHSgtk -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgdk_pixbuf-2.0 -lm 
-lpangocairo-1.0 -lpango-1.0 -lcairo -lSM -lICE -lgmodule-2.0 -lfreetype -lz 
-lfontconfig -lpng12 -lXrender -lX11 -lgthread-2.0 -lHScairo -lcairo -lSM 
-lICE -lfreetype -lz -lfontconfig -lpng12 -lXrender -lX11 -lHSglib 
-lgobject-2.0 -lglib-2.0 -lintl -liconv -lHSmtl -lHSbase -lHSbase_cbits 
-lHSrts -lm -u _base_GHCziBase_Izh_static_info -u 
_base_GHCziBase_Czh_static_info -u _base_GHCziFloat_Fzh_static_info -u 
_base_GHCziFloat_Dzh_static_info -u _base_GHCziPtr_Ptr_static_info -u 
_base_GHCziWord_Wzh_static_info -u _base_GHCziInt_I8zh_static_info -u 
_base_GHCziInt_I16zh_static_info -u _base_GHCziInt_I32zh_static_info -u 
_base_GHCziInt_I64zh_static_info -u _base_GHCziWord_W8zh_static_info -u 
_base_GHCziWord_W16zh_static_info -u _base_GHCziWord_W32zh_static_info -u 
_base_GHCziWord_W64zh_static_info -u _base_GHCziStable_StablePtr_static_info 
-u _base_GHCziBase_Izh_con_info -u _base_GHCziBase_Czh_con_info -u 
_base_GHCziFloat_Fzh_con_info -u _base_GHCziFloat_Dzh_con_info -u 
_base_GHCziPtr_Ptr_con_info -u _base_GHCziPtr_FunPtr_con_info -u 
_base_GHCziStable_StablePtr_con_info -u _base_GHCziBase_False_closure -u 
_base_GHCziBase_True_closure -u _base_GHCziPack_unpackCString_closure -u 
_base_GHCziIOBase_stackOverflow_closure -u 
_base_GHCziIOBase_heapOverflow_closure -u 
_base_GHCziIOBase_NonTermination_closure -u 
_base_GHCziIOBase_BlockedOnDeadMVar_closure -u 
_base_GHCziIOBase_BlockedIndefinitely_closure -u 
_base_GHCziIOBase_Deadlock_closure -u 
_base_GHCziIOBase_NestedAtomically_closure -u 
_base_GHCziWeak_runFinalizzerBatch_closure -u 
_base_GHCziConc_ensureIOManagerIsRunning_closure -framework GMP
> ...
> $

The -Ls are:

> -L/Users/thorkilnaur/tn/install/gtk+-2.10.14/lib -L/usr/X11R6/lib 
-L/Users/thorkilnaur/tn/install/gtk2hs-0.9.12/lib/gtk2hs -L/opt/local/lib 
-L/Users/thorkilnaur/tn/install/ghc-6.6-for-buildbot-20070221_1000/lib/ghc-6.6.20070220

My guess is now that ghc constructs this list from the package library-dirs, 
heaping new ones onto the growing list at the end. World.hs refers only 
gtk-0.9.12 which for some reason doesn't refer /opt/local/lib. However, gtk 
depends on glib and glib includes /opt/local/lib before /usr/X11R6/lib, but 
because the latter already appears in the current list, the new one 
(/opt/local/lib) is simply tucked onto the end. And so on, thereby explaining 
why /opt/local/lib ends up appearing after /usr/X11R6/lib.

I don't know what could be done about this, but certainly, the problem cannot 
be said to be caused by GTK+. Really, the basic problem is this horrendously 
primitive manner which is used on many of our systems of letting the order of 
appearance in certain lists influence the outcome of important processes. 
Plus, of course, the lack of possibility of warning users about this, for 
example by reporting on ambiguous references in case symbols are defined in 
multiple libraries.

> 
> Where did you install Gtk+ from? DarwinPorts or somewhere else?

I installed GTK+ from gtk.org. All dependent packages were already installed, 
some of them probably via Darwin/Mac-Ports.

> If it's 
> the pkg-config setting for Gtk+ that we think are wrong then we should
> get that fixed upstream in the package that installed Gtk+.
> 
> Duncan
> 
> 

Best regards
Thorkil


More information about the Haskell-Cafe mailing list