
Greetings fellow Haskellers and other readers, During my ongoing research on "doing whatever I feel like", I discovered that using C++ libaries in GHCi (no problems with GHC) wasn't as pleasant as I had hoped. Apparently C++ sources requires to be linked with crtbegin.o and crtend.o (and others?) and I was wondering how to solve this nicely. Any hints or pointers would be greatly appreciated. -- Friendly, Lemmih

On Fri, 2005-02-25 at 19:05 +0100, Lemmih wrote:
Greetings fellow Haskellers and other readers,
During my ongoing research on "doing whatever I feel like", I discovered that using C++ libaries in GHCi (no problems with GHC) wasn't as pleasant as I had hoped. Apparently C++ sources requires to be linked with crtbegin.o and crtend.o (and others?) and I was wondering how to solve this nicely. Any hints or pointers would be greatly appreciated.
How about creating a dummy ghc package that has no Haskell code but specifies all the nasty link time options. i.e. using the extra_libraries, extra_ghc_opts, extra_cc_opts and extra_ld_opts fields. Then when compiling your program you just use -package c++ or (-package "cpp" or "cpp-support" if "c++" is not a valid package name). if you make packages that depend on C++ support it's still easy, just make the new package depend on the "cpp" package. Duncan

On Fri, 25 Feb 2005 18:27:03 +0000, Duncan Coutts
On Fri, 2005-02-25 at 19:05 +0100, Lemmih wrote:
Greetings fellow Haskellers and other readers,
During my ongoing research on "doing whatever I feel like", I discovered that using C++ libaries in GHCi (no problems with GHC) wasn't as pleasant as I had hoped. Apparently C++ sources requires to be linked with crtbegin.o and crtend.o (and others?) and I was wondering how to solve this nicely. Any hints or pointers would be greatly appreciated.
How about creating a dummy ghc package that has no Haskell code but specifies all the nasty link time options. i.e. using the extra_libraries, extra_ghc_opts, extra_cc_opts and extra_ld_opts fields.
Then when compiling your program you just use -package c++ or (-package "cpp" or "cpp-support" if "c++" is not a valid package name). if you make packages that depend on C++ support it's still easy, just make the new package depend on the "cpp" package.
Thanks for replying and it all sounds nice, but I'm not sure which linker options I'm missing since the location of the crt*.o files appears to be implementation specific. -- Friendly, Lemmih

During my ongoing research on "doing whatever I feel like", I discovered that using C++ libaries in GHCi (no problems with GHC) wasn't as pleasant as I had hoped. Apparently C++ sources requires to be linked with crtbegin.o and crtend.o (and others?) and I was wondering how to solve this nicely. Any hints or pointers would be greatly appreciated.
I think the files crtbegin.o and crtend.o are Linux-specific or maybe GNU-binutils-specific. Different platforms tend to have different strange requirements for C++ code. Loading shared libraries that happen to be written in C++ into GHCi shouldn't be a problem (or is it? definitely works on Mac OS X). Loading C++ .o files is a different story. Generally speaking, there are at least two things that set C++ .o files apart from "normal" C .o files: *) static constructors/destructors Sometimes there are pieces of code that expect to be called before main() or at program termination. The GHCi Linker doesn't support this, so some code may crash because things haven't been initialised properly. *) multiple definitions There is often some code in C++ header files (e.g. templates, inline functions, class members declared in the class declaration). These pieces of code are sometimes inlined, but sometimes they are not; in that case, gcc generates code for them in every .o file that uses them and counts on the linker to just include one version in the final executable. The GHCi linker will probably just abort and complain about multiply-defined symbols. The above is just theory, there might be even more problems in practice :-( . Cheers, Wolfgang

On Fri, 25 Feb 2005 13:58:52 -0500, Wolfgang Thaller
During my ongoing research on "doing whatever I feel like", I discovered that using C++ libaries in GHCi (no problems with GHC) wasn't as pleasant as I had hoped. Apparently C++ sources requires to be linked with crtbegin.o and crtend.o (and others?) and I was wondering how to solve this nicely. Any hints or pointers would be greatly appreciated.
I think the files crtbegin.o and crtend.o are Linux-specific or maybe GNU-binutils-specific. Different platforms tend to have different strange requirements for C++ code.
Loading shared libraries that happen to be written in C++ into GHCi shouldn't be a problem (or is it? definitely works on Mac OS X). Loading C++ .o files is a different story.
Generally speaking, there are at least two things that set C++ .o files apart from "normal" C .o files:
*) static constructors/destructors
Sometimes there are pieces of code that expect to be called before main() or at program termination. The GHCi Linker doesn't support this, so some code may crash because things haven't been initialised properly.
*) multiple definitions
There is often some code in C++ header files (e.g. templates, inline functions, class members declared in the class declaration). These pieces of code are sometimes inlined, but sometimes they are not; in that case, gcc generates code for them in every .o file that uses them and counts on the linker to just include one version in the final executable. The GHCi linker will probably just abort and complain about multiply-defined symbols.
The above is just theory, there might be even more problems in practice :-( .
I've written a binding to a C++ library where I use a simple wrapper file to overcome the name mangling (extern "C" functions calling C++, nothing fancy). Is there a way to make that more GHCi friendly or should I explore other options? -- Friendly, Lemmih

I've written a binding to a C++ library where I use a simple wrapper file to overcome the name mangling (extern "C" functions calling C++, nothing fancy). Is there a way to make that more GHCi friendly or should I explore other options?
What exactly is going wrong? Try wrapping your binding in a .so, that should hide all the C++ stuff from GHCi. Cheers, Wolfgang

Wolfgang Thaller wrote:
[...] *) static constructors/destructors
Sometimes there are pieces of code that expect to be called before main() or at program termination. The GHCi Linker doesn't support this, so some code may crash because things haven't been initialised properly.
This will definitely be a source of trouble if you use any C++ library whatsoever. I don't know the story for Linux, but at least one other platform I know has the addresses of those constructors/destructors in special ELF sections. GHCi could easily iterate through these, but this is really highly platform-specific. There used to be a description of a widespread C++ ABI on codesourcery.com, but I can't find it anymore... :-(
*) multiple definitions
There is often some code in C++ header files (e.g. templates, inline functions, class members declared in the class declaration). These pieces of code are sometimes inlined, but sometimes they are not; in that case, gcc generates code for them in every .o file that uses them and counts on the linker to just include one version in the final executable. The GHCi linker will probably just abort and complain about multiply-defined symbols.
IIRC, g++ uses weak symbols for this, at least on some platforms. Handling these doesn't sound too hard (easy sentence when one doesn't intend to implement it :-).
The above is just theory, there might be even more problems in practice :-( .
Exception handling comes to my mind. Nowadays it's often done via stack unwinding, but I don't know about the details anymore. This might cause some trouble when C++ code is called from Haskell. The only golden rule I know about this all: Use only a single C++ compiler for the compilation *and* linking of all your libraries and programs, otherwise be prepared for long hours in front of gdb... :-( Cheers, S.
participants (4)
-
Duncan Coutts
-
Lemmih
-
Sven Panne
-
Wolfgang Thaller