Linking problems: graphml.c/hpp

I'm trying to use graphml.cpp/hpp in a project.

When linking the main executable against expat-2.0.0, I get:

Link separator
graphml.o: In function
`graphml_reader::handle_vertex(std::basic_string<char,
std::char_traits<char>, std::allocator<char> > const&)':
graphml.cpp:(.text._ZN14graphml_reader13handle_vertexERKSs[graphml_reader::handle_vertex(std::basic_string<char,
std::char_traits<char>, std::allocator<char> > const&)]+0xf5): undefined
reference to `__cxa_get_exception_ptr'
graphml.o: In function
`graphml_reader::handle_edge(std::basic_string<char,
std::char_traits<char>, std::allocator<char> > const&,
std::basic_string<char, std::char_traits<char>, std::allocator<char> >
const&, std::basic_string<char, std::char_traits<char>,
std::allocator<char> > const&)':
graphml.cpp:(.text._ZN14graphml_reader11handle_edgeERKSsS1_S1_[graphml_reader::handle_edge(std::basic_string<char,
std::char_traits<char>, std::allocator<char> > const&,
std::basic_string<char, std::char_traits<char>, std::allocator<char> >
const&, std::basic_string<char, std::char_traits<char>,
std::allocator<char> > const&)]+0x465): undefined reference to
`__cxa_get_exception_ptr'

Anyone knows, what's going wrong here?

Do you know if expat was compiled with a C++ compiler? Eg. g++ instead
of gcc? It looks like that may be the problem.

Tiago de Paula Peixoto schrieb:

std::basic_string<char, std::char_traits<char>, std::allocator<char> >
const&, std::basic_string<char, std::char_traits<char>,
std::allocator<char> > const&)]+0x465): undefined reference to
`__cxa_get_exception_ptr'

Anyone knows, what's going wrong here?

Do you know if expat was compiled with a C++ compiler? Eg. g++ instead
of gcc? It looks like that may be the problem.

Well, I compiled it myself and installed it in my user dir.

CC is gcc, that should be a C compiler ...

But honestly, I don't get it. Why should libexpat provide the symbol
`__cxa_get_exception_ptr' if compiled with a C compiler.

I just looked at libexpat.a with mc - all the names exported look nice
and unmangled. Shouldn't there a name mangling be in place if compiled
as C++?

Yes, which means you used gcc to compile it. As far as I know you should
have to compile expat with g++, instead of gcc, so that exceptions can
be thrown from inside the hook functions, and caught outside. Otherwise
the "main loop" from expat doesn't know anything about exceptions, and
they wouldn't come through... This problem manifests itself with missing
symbols during linkage, but honestly I don't know the details. It could
be that "__cxa_get_exception_ptr" is referenced by your program, and the
linker expects it to be defined in the expat library... If you compile
libexpat with g++ everything should just work.

Tiago de Paula Peixoto schrieb:

Tiago de Paula Peixoto schrieb:

std::basic_string<char, std::char_traits<char>, std::allocator<char> >
const&, std::basic_string<char, std::char_traits<char>,
std::allocator<char> > const&)]+0x465): undefined reference to
`__cxa_get_exception_ptr'

Anyone knows, what's going wrong here?

Do you know if expat was compiled with a C++ compiler? Eg. g++ instead
of gcc? It looks like that may be the problem.

Well, I compiled it myself and installed it in my user dir.

CC is gcc, that should be a C compiler ...

But honestly, I don't get it. Why should libexpat provide the symbol
`__cxa_get_exception_ptr' if compiled with a C compiler.

I just looked at libexpat.a with mc - all the names exported look nice
and unmangled. Shouldn't there a name mangling be in place if compiled
as C++?

Yes, which means you used gcc to compile it. As far as I know you should
have to compile expat with g++, instead of gcc, so that exceptions can
be thrown from inside the hook functions, and caught outside. Otherwise
the "main loop" from expat doesn't know anything about exceptions, and
they wouldn't come through... This problem manifests itself with missing
symbols during linkage, but honestly I don't know the details. It could
be that "__cxa_get_exception_ptr" is referenced by your program, and the
linker expects it to be defined in the expat library... If you compile
libexpat with g++ everything should just work.

I set CC=g++ when building expat, but I don't think it's meant to work
like that:

jmueller(a)i11pc50:/amd.home/home/jmueller/software/expat-2.0.0$ make
/bin/sh ./libtool --silent --mode=compile g++ -I./lib -I. -g -O2 -Wall
-Wmissing-prototypes -Wstrict-prototypes -fexceptions
-DHAVE_EXPAT_CONFIG_H -o lib/xmlparse.lo -c lib/xmlparse.c
cc1plus: warning: command line option "-Wmissing-prototypes" is valid
for Ada/C/ObjC but not for C++
cc1plus: warning: command line option "-Wstrict-prototypes" is valid for
Ada/C/ObjC but not for C++
lib/xmlparse.c: In function 'const XML_LChar* XML_ErrorString(XML_Error)':
lib/xmlparse.c:1887: warning: comparison between signed and unsigned
integer expressions
/bin/sh ./libtool --silent --mode=compile g++ -I./lib -I. -g -O2 -Wall
-Wmissing-prototypes -Wstrict-prototypes -fexceptions
-DHAVE_EXPAT_CONFIG_H -o lib/xmltok.lo -c lib/xmltok.c
cc1plus: warning: command line option "-Wmissing-prototypes" is valid
for Ada/C/ObjC but not for C++
cc1plus: warning: command line option "-Wstrict-prototypes" is valid for
Ada/C/ObjC but not for C++
/bin/sh ./libtool --silent --mode=compile g++ -I./lib -I. -g -O2 -Wall
-Wmissing-prototypes -Wstrict-prototypes -fexceptions
-DHAVE_EXPAT_CONFIG_H -o lib/xmlrole.lo -c lib/xmlrole.c
cc1plus: warning: command line option "-Wmissing-prototypes" is valid
for Ada/C/ObjC but not for C++
cc1plus: warning: command line option "-Wstrict-prototypes" is valid for
Ada/C/ObjC but not for C++
/bin/sh ./libtool --silent --mode=link g++ -I./lib -I. -g -O2 -Wall
-Wmissing-prototypes -Wstrict-prototypes -fexceptions
-DHAVE_EXPAT_CONFIG_H -no-undefined -version-info 6:0:5 -rpath
/home/jmueller/software/expat/lib -o libexpat.la lib/xmlparse.lo
lib/xmltok.lo lib/xmlrole.lo
g++ -I./lib -I. -g -O2 -Wall -Wmissing-prototypes -Wstrict-prototypes
-fexceptions -DHAVE_EXPAT_CONFIG_H -o xmlwf/xmlwf.o -c xmlwf/xmlwf.c
cc1plus: warning: command line option "-Wmissing-prototypes" is valid
for Ada/C/ObjC but not for C++
cc1plus: warning: command line option "-Wstrict-prototypes" is valid for
Ada/C/ObjC but not for C++
g++ -I./lib -I. -g -O2 -Wall -Wmissing-prototypes -Wstrict-prototypes
-fexceptions -DHAVE_EXPAT_CONFIG_H -o xmlwf/xmlfile.o -c xmlwf/xmlfile.c
cc1plus: warning: command line option "-Wmissing-prototypes" is valid
for Ada/C/ObjC but not for C++
cc1plus: warning: command line option "-Wstrict-prototypes" is valid for
Ada/C/ObjC but not for C++
g++ -I./lib -I. -g -O2 -Wall -Wmissing-prototypes -Wstrict-prototypes
-fexceptions -DHAVE_EXPAT_CONFIG_H -o xmlwf/codepage.o -c xmlwf/codepage.c
cc1plus: warning: command line option "-Wmissing-prototypes" is valid
for Ada/C/ObjC but not for C++
cc1plus: warning: command line option "-Wstrict-prototypes" is valid for
Ada/C/ObjC but not for C++
g++ -I./lib -I. -g -O2 -Wall -Wmissing-prototypes -Wstrict-prototypes
-fexceptions -DHAVE_EXPAT_CONFIG_H -o xmlwf/unixfilemap.o -c
xmlwf/unixfilemap.c
cc1plus: warning: command line option "-Wmissing-prototypes" is valid
for Ada/C/ObjC but not for C++
cc1plus: warning: command line option "-Wstrict-prototypes" is valid for
Ada/C/ObjC but not for C++
/bin/sh ./libtool --silent --mode=link g++ -I./lib -I. -g -O2 -Wall
-Wmissing-prototypes -Wstrict-prototypes -fexceptions
-DHAVE_EXPAT_CONFIG_H -o xmlwf/xmlwf xmlwf/xmlwf.o xmlwf/xmlfile.o
xmlwf/codepage.o xmlwf/unixfilemap.o libexpat.la

But the error still occurs, anyway:
mueller(a)i11pc50:~/separator_devel/separator_jens$ jam
...found 737 target(s)...
...updating 3 target(s)...
C++ separator.o
C++ graphml.o
Link separator
graphml.o: In function
`graphml_reader::handle_vertex(std::basic_string<char,
std::char_traits<char>, std::allocator<char> > const&)':
graphml.cpp:(.text._ZN14graphml_reader13handle_vertexERKSs[graphml_reader::handle_vertex(std::basic_string<char,
std::char_traits<char>, std::allocator<char> > const&)]+0xf5): undefined
reference to `__cxa_get_exception_ptr'
graphml.o: In function
`graphml_reader::handle_edge(std::basic_string<char,
std::char_traits<char>, std::allocator<char> > const&,
std::basic_string<char, std::char_traits<char>, std::allocator<char> >
const&, std::basic_string<char, std::char_traits<char>,
std::allocator<char> > const&)':
graphml.cpp:(.text._ZN14graphml_reader11handle_edgeERKSsS1_S1_[graphml_reader::handle_edge(std::basic_string<char,
std::char_traits<char>, std::allocator<char> > const&,
std::basic_string<char, std::char_traits<char>, std::allocator<char> >
const&, std::basic_string<char, std::char_traits<char>,
std::allocator<char> > const&)]+0x465): undefined reference to
`__cxa_get_exception_ptr'
collect2: ld returned 1 exit status

cc -lboost_program_options-gcc-d -L/home/jmueller/software/boost/lib
-Bstatic -lexpat -L/home/jmueller/software/expat/lib -o separator
separator.o graphml.o

I wonder if cc is right for linking C++ object files?!

So I think I'll try to find out how to get Jam to do it right.

$ g++ -lboost_program_options-gcc-d -L/home/jmueller/software/boost/lib
-Bstatic -lexpat -L/home/jmueller/software/expat/lib -o separator
separator.o graphml.o

works fine.

So, thanks for your help and sorry for all the trouble ...