GHCi fails to load C++ object files (missing symbol)

Hi, I'm trying to have GHCi load a haskell file that depends on a C++ object file, which causes GHCi to fail because of an unknown symbol (*and I did link with **libstdc++*), whereas the link into an executable with ghc works and runs perfectly. I've reduced my code to the smallest one that produces the problem: The C++ part defines a mere class and C externals that enable communication with Haskell: // Header Stuff.hpp class Base { public: Base(); ~Base(); } extern "C" { Base* mkthing(); void delthing(Base*); } ----------- // Source Stuff.cpp #include <iostream> #include "Stuff.hpp" using namespace std; Base::Base() { cout << "Base created" << endl; } Base::~Base() { cout << "Base deleted" << endl; } extern "C" { Base* mkthing() { return new Base(); } void delthing(Base* b) { delete b; } } Haskell code (just for reference, but I'm not sure it's relevant), Main.hs: {-# LANGUAGE ForeignFunctionInterface #-} import Foreign import Foreign.C foreign import ccall unsafe "mkthing" mkthing :: IO (Ptr ()) foreign import ccall unsafe "delthing" delthing :: Ptr () -> IO () main = do p <- mkthing delthing p I then compile it with: g++ -c Stuff.cpp ghci Main.hs Stuff.o -lstdc++ And then the error is: Loading object (static) Stuff.o ... done Loading object (dynamic) /usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/libstdc++.so ... done final link ... ghc: Stuff.o: unknown symbol `__dso_handle' linking extra libraries/objects failed Whereas 'ghc Main.hs Stuff.o -lstdc++' works just fine. Does GHCi lacks a link directive that regular GHC has?

Sorry for the double post, but I forgot to mention I'm using GHC 7.4 and
gcc/libstdc++ 4.5.2.
(Running Ubuntu 11.04 Natty Narwhal).
2012/3/7 Yves Parès
Hi, I'm trying to have GHCi load a haskell file that depends on a C++ object file, which causes GHCi to fail because of an unknown symbol (*and I did link with **libstdc++*), whereas the link into an executable with ghc works and runs perfectly.
I've reduced my code to the smallest one that produces the problem: The C++ part defines a mere class and C externals that enable communication with Haskell:
// Header Stuff.hpp class Base { public: Base(); ~Base(); }
extern "C" { Base* mkthing(); void delthing(Base*); }
-----------
// Source Stuff.cpp #include <iostream> #include "Stuff.hpp" using namespace std;
Base::Base() { cout << "Base created" << endl; }
Base::~Base() { cout << "Base deleted" << endl; }
extern "C" { Base* mkthing() { return new Base(); }
void delthing(Base* b) { delete b; } }
Haskell code (just for reference, but I'm not sure it's relevant), Main.hs:
{-# LANGUAGE ForeignFunctionInterface #-} import Foreign import Foreign.C
foreign import ccall unsafe "mkthing" mkthing :: IO (Ptr ())
foreign import ccall unsafe "delthing" delthing :: Ptr () -> IO ()
main = do p <- mkthing delthing p
I then compile it with: g++ -c Stuff.cpp ghci Main.hs Stuff.o -lstdc++
And then the error is: Loading object (static) Stuff.o ... done Loading object (dynamic) /usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/libstdc++.so ... done final link ... ghc: Stuff.o: unknown symbol `__dso_handle' linking extra libraries/objects failed
Whereas 'ghc Main.hs Stuff.o -lstdc++' works just fine. Does GHCi lacks a link directive that regular GHC has?

Hi Yves, It works (on Gentoo) when I compile it as a shared library. % g++ -o libstuff.so -fpic -shared Stuff.cpp % ghci Main.hs -L$PWD -lstuff GHCi, version 7.4.1: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Loading object (dynamic) /h/argus/2/eng/haskell/cxx_stuff/libstuff.so ... done final link ... done Loading package filepath-1.3.0.0 ... linking ... done. Loading package bytestring-0.9.2.1 ... linking ... done. Loading package unix-2.5.1.0 ... linking ... done. Loading package old-locale-1.0.0.4 ... linking ... done. Loading package old-time-1.1.0.0 ... linking ... done. Loading package directory-1.1.0.2 ... linking ... done. Loading package process-1.1.0.1 ... linking ... done. Loading package goa-3.1 ... linking ... done. [1 of 1] Compiling Main ( Main.hs, interpreted ) Ok, modules loaded: Main. *Main GOA> Hope this helps. Regards, Mark

Thanks Mark!
It works also here, and even without the "-fpic" flag. Was it necessary for
you?
2012/3/8 Mark Wright
Hi Yves,
It works (on Gentoo) when I compile it as a shared library.
% g++ -o libstuff.so -fpic -shared Stuff.cpp % ghci Main.hs -L$PWD -lstuff GHCi, version 7.4.1: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Loading object (dynamic) /h/argus/2/eng/haskell/cxx_stuff/libstuff.so ... done final link ... done Loading package filepath-1.3.0.0 ... linking ... done. Loading package bytestring-0.9.2.1 ... linking ... done. Loading package unix-2.5.1.0 ... linking ... done. Loading package old-locale-1.0.0.4 ... linking ... done. Loading package old-time-1.1.0.0 ... linking ... done. Loading package directory-1.1.0.2 ... linking ... done. Loading package process-1.1.0.1 ... linking ... done. Loading package goa-3.1 ... linking ... done. [1 of 1] Compiling Main ( Main.hs, interpreted ) Ok, modules loaded: Main. *Main GOA>
Hope this helps.
Regards, Mark

On Thu, 8 Mar 2012 12:55:51 +0100, Yves Parès
Thanks Mark! It works also here, and even without the "-fpic" flag. Was it necessary for you?
Hi Yves, Yes it is necessary for me to use -fpic when building C/C++ shared libraries as: - I'm on amd64 - Its a Gentoo developer policy to compile C/C++ shared libraries with -fPIC (same as -fpic on amd64) on amd64: http://devmanual.gentoo.org/archs/amd64/index.html Its normal to compile and link all the C/C++ with -fpic or -fPIC when building shared libraries. It might work without -fpic on x86 (32 bit): http://www.mail-archive.com/gentoo-dev@gentoo.org/msg01420.html "2) If it needs an -fPIC to compile on a non-x86 arch, it actually also needs -fPIC on x86 -- not to get the thing to compile correctly of course but for another reason: to avoid wasting memory when the code is used. Non-PIC library code on x86 wastes memory when used, even though it technically "works". The dynamic loader is forced to create a private copy for each process using the non-PIC code, defeating one of the main reasons of using shared libraries in the first place -- to conserve RAM." Thanks, Mark

On 8 Mar 2012, at 13:21, Mark Wright wrote:
It might work without -fpic on x86 (32 bit):
http://www.mail-archive.com/gentoo-dev@gentoo.org/msg01420.html
On OS X, it is always on; I tried the example on 10.7, Xcode 4.3. I had to add ln -s /Applications/Xcode.app/Contents/Developer /Developer as ghc 7.0.4 looks for /Developer/usr/bin/gcc. For some funny reason ghc is at /usr/bin/ghc; since it is not a system distribution, it should be at /usr/local/bin/, which is also in the system path. On x86-64, there special relative addressing support, so there is no reason having it turned off, but some other good reasons for having on, like the security reason mentioned here: http://stackoverflow.com/questions/7078253/pic-on-osxs-gcc Hans
participants (3)
-
Hans Aberg
-
Mark Wright
-
Yves Parès