Compiling C++ project with libraries - c++

My friends developed a C++ game in Visual Studio on Windows, and I would like to compile it on my Linux x64 machine. I'm not very familiar with C++ but I'm trying g++ on command-line. However I only get a bunch of undefined reference errors.
The basic file structure is:
Libraries/SFML-2.0/lib
Libraries/SFML-2.0/include
Libraries/SFML_Linux64/lib
Libraries/SFML_Linux64/include
Libraries/Box2D/lib
Libraries/Box2D/include
Libraries/Box2DLinux/lib
Libraries/Box2DLinux/include
Game
Game/lib
Game/includes
Game/... (other subdirectories)
I tried the following command:
g++ -Wall Multiplaya/app.cpp -I Libraries/SFML_Linux64/include/ -I Libraries/Box2DLinux/include/ -L Libraries/SFML_Linux64/lib/ -L Libraries/Box2DLinux/lib/
This is the kind of errors I get (some lines snipped and replaced with ...):
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crt1.o: I funktionen "_start":
(.text+0x20): undefined reference to `main'
/tmp/ccFXe37c.o: I funktionen "mp::createNetworkThread(void*)":
app.cpp:(.text+0x10): undefined reference to `worldDataMutex'
app.cpp:(.text+0x15): undefined reference to `sf::Mutex::lock()'
...
/tmp/ccFXe37c.o: I funktionen "mp::App::exec()":
app.cpp:(.text+0x148): undefined reference to `mp::ResourceHandler::instance()'
app.cpp:(.text+0x15a): undefined reference to `mp::ResourceHandler::loadTexture(std::string)'
app.cpp:(.text+0x3d7): undefined reference to `mp::Window::Window(mp::WorldData*)'
app.cpp:(.text+0x406): undefined reference to `mp::Controller::Controller(mp::World*, mp::Window*)'
...
app.cpp:(.text+0x471): undefined reference to `sf::Mutex::unlock()'
app.cpp:(.text+0x4bb): undefined reference to `sf::Thread::launch()'
app.cpp:(.text+0x4d7): undefined reference to `sf::Clock::Clock()'
app.cpp:(.text+0x4e6): undefined reference to `sf::Clock::getElapsedTime() const'
...
collect2: fel: ld returnerade avslutningsstatus 1
(I hope you can look through the Swedish above.)

That's very courteous of you to provide library paths to the linker. However, linkers are ungrateful slobs and usually do not look for any library files on their own when they see an undefined reference to a function.
Like, undefined reference to `sf::Mutex::lock() — I bet there is libsfml-system.so.2.0 or whatever in the Libraries/SFML_Linux64/lib/ directory, with the definition for sf::Mutex::lock(). But the linker doesn't care. You have to say -lsfml-system at the end of your compile invocation.
This will make g++ understand to look for functions not only in libstdc++ library, but also in the libsfml-system file. And if g++ happen to find such a file in the default or additional (specified with -L flag) library directories, he will use it for resolving references to function calls.
But you have to say to it explicitly what library files you want to throw in, specifying only directories with libraries doesn't do much. So, try to use
g++ -Wall Multiplaya/app.cpp -I Libraries/SFML_Linux64/include/ -I Libraries/Box2DLinux/include/ -L Libraries/SFML_Linux64/lib/ -L Libraries/Box2DLinux/lib/ -lsfml-system
How to build C++ programs
C++ programs are built in two steps: the first step is compilation, and the second step is linking.
During compilation, you turn your source files into object files — things which contain compiled machine code. Now there is a trick you have to understand. Say, if you have a.cpp with
// a.cpp
int f(int x);
int main() {
return f(42);
}
you can compile it with g++ -c a.cpp and it will get you object file a.o (with compiled code), without any compilation errors. But wait! There is no actual definition of what f() is in a.cpp!
And now, when you go to the second step, linking, and invokes g++ -o test a.o, it will complain that there is undefined reference to f(). So let's make b.cpp with this text:
// b.cpp
int f(int x) {
return 2 * x - 3;
}
compile it with g++ -c b.cpp and then perform linking as g++ -o test a.o b.o — and wow, now it links without an error!
What happened? Well, when the compiler sees a function call, it puts in object file not an actual call instruction, but a placeholder that says "call a function with such and such name and such and such parameters". And then the linker takes a bunch of object files, and sews them together. When it sees such a placholder, it looks for the mentioned function in object files it was given, and puts actual call to it instead of the placeholder.
So, the building of C++ program looks something like this:
For each x.cpp file you have, call g++ -c x.cpp <bunch of flags> -I<include directories>
Then call g++ -o resultprogram a.o b.o c.o d.o ... <bunch of flags> -L<library directories> -l<additional libraries>
-l flag tells the linker that if he sees a call to a function, and there is no such function defined anywhere in the specified object files (a.o, b.o, etc), then it should look in this library. Please not, that the linker won't look in any object files and/or libraries except those you specified (okay, it will also look in standard C++ library libstdc++, but that's it).
However, this process is pretty boring to do by hand if you have 10 or more files. That's why people use "project files" and "build systems". When Visual Studio builds a project, it does all those steps I mentioned: it compiles every single file in a project, and then links the result together. On Linux, you don't have Visual Studio, but you have make utility. There are some utilities for converting VS projects to makefiles, I believe.

Related

Compiling using gcc of a Cpp code which is calling a TCL script

I have a cpp code in which I have included tcl.h library. I am trying to compile it using the gcc compiler. but I'm getting the following error :
gcc -o top.o -std=c99 top.c
top.c:12: warning: return type defaults to 'int'
/tmp/ccDOTTZQ.o: In function `main':
top.c:(.text+0xa): undefined reference to `Tcl_CreateInterp'
top.c:(.text+0x1f): undefined reference to `Tcl_EvalFile'
top.c:(.text+0x3d): undefined reference to `Tcl_GetVar2Ex'
top.c:(.text+0x75): undefined reference to `Tcl_ListObjGetElements'
top.c:(.text+0xb1): undefined reference to `Tcl_GetString'
top.c:(.text+0xcc): undefined reference to `Tcl_GetInt'
collect2: ld returned 1 exit status
Its not able to find the Cpp-tcl APIs. Kindly help me with this.
Your code is not linking to the Tcl library, so obviously it can't find the implementations of those functions. (In C and C++, the linking to the implementations of functions is a separate stage from the use of the declarations of those functions, which is what the header files provide.)
Except that you're actually calling gcc wrong. You need to use two steps, first with -c to compile the source code to an object file:
gcc -c -o top.o -std=c99 top.c
Then like this to link the result and make an executable:
gcc -o top.exe -std=c99 top.o -ltcl
With the first, you might need to additionally specify an appropriate -I option to locate the include files (if they're not in the standard locations). With the second, you might need to specify an appropriate -L option to locate the library files (libtcl.so). Depending on the system, you might also need to specify some version numbers (e.g., -ltcl86 or -ltcl8.6 instead of -ltcl). These are all options that depend on your build system configuration, so they're hard to predict exactly here.

Libquantum code Understanding Makefile

I tried to run .c file called grover.c in this C application libquantum
www.libquantum.de/files/libquantum-1.1.1.tar.gz
Now I this application already contains a Makefile.in and I can generate the executables called shor and grover using the command
./configure
make
make demos
But when I try to run grover.c using gcc or clan like this
clang grover.c
It gives me error of lots of undefined function reference.
In function oracle':
grover.c:(.text+0x50): undefined reference toquantum_sigma_x'
grover.c:(.text+0x89): undefined reference to quantum_toffoli'
grover.c:(.text+0xc8): undefined reference toquantum_toffoli'
grover.c:(.text+0xf2): undefined reference to quantum_cnot'
grover.c:(.text+0x137): undefined reference toquantum_toffoli'
grover.c:(.text+0x16b): undefined reference to quantum_toffoli'
grover.c:(.text+0x1b0): undefined reference toquantum_sigma_x'
I need to know how can I remove this error and if I can run this c code called grover.c in this application.
Thanks,
It looks like your compiler can not find one or more libraries to link to. My hunch is that the makefile has the appropriate commands to invoke the linker.
If you look at your makefile, you probably will see some commands like -L -l,
when the flag -L add a directory to the default search path for libraries and the flag -l is used to name the library to link.
for example -L/lib/openGL -lglut32 would cause the library libglut32.so.X.Y.Z which is found in the directory /lib/openGL. (not this is for a Linux system, but it should be fairly similar for Mac).
N.B. X.Y.Z are the version number of the library.
Once you work this out, there may be issues with the load finding the libraries, especially if they are in non-standard locations.
------------------------ edit --------------------------
After I posted this, and went to bed I realized that I missed a potential case (and thanks to Paul Griffiths for also noticing my omission.....teach me to do multiple things at once).
Any how, just compiling a simple file, say hello.c, as clang hello.c -o hello works because everything is in one file and clang will automatically link to the C run-time library.
If, in your case the code is spread across multiple files, say grover.c and file1.c you would need to do:
clang -c grover.c -o grover.o
clang -c file1.c -o file1.o
clang grover.o file1.o -o grover
(or alteratively clang grover.c file1.c -o grover)
SO what the first two lines are doing is translating the source-code files (grover.c and file1.c) into object files. THe third line covers the two object files into an executable.
Finally, both these cases can be involved. You could have multiple files as well as missing libraries.

Position of compiler flag -l

I'm currently learning OpenCL. Now, when I want to compile my program, I get an error with this command:
g++ -Wall -l OpenCL main.cpp -o main
The errors are mostly undefined references, because the library is not linked, I think (nevertheless I will post the error code at the end).
But with this command everything works fine:
g++ -Wall main.cpp -o main -l OpenCL
So my question is, what do I have to do, to use the -l Flag in front of the command?
(The Background is: I want to use Netbeans to compile my programm and when i add the flag under -> properties -> build -> C++ Compiler -> additional options, it will put in in the Position, shown in the first command)
Thanks in advance for your help
Here's the error code:
/tmp/ccmKP4oI.o: In function `cl::detail::ReferenceHandler<_cl_context*>::release(_cl_context*)':
main.cpp:(.text._ZN2cl6detail16ReferenceHandlerIP11_cl_contextE7releaseES3_[_ZN2cl6detail16ReferenceHandlerIP11_cl_contextE7releaseES3_]+0x14): undefined reference to `clReleaseContext'
/tmp/ccmKP4oI.o: In function `cl::detail::ReferenceHandler<_cl_command_queue*>::release(_cl_command_queue*)':
main.cpp:(.text._ZN2cl6detail16ReferenceHandlerIP17_cl_command_queueE7releaseES3_[_ZN2cl6detail16ReferenceHandlerIP17_cl_command_queueE7releaseES3_]+0x14): undefined reference to `clReleaseCommandQueue'
/tmp/ccmKP4oI.o: In function `cl::Platform::getInfo(unsigned int, std::string*) const':
main.cpp:(.text._ZNK2cl8Platform7getInfoEjPSs[_ZNK2cl8Platform7getInfoEjPSs]+0x22): undefined reference to `clGetPlatformInfo'
/tmp/ccmKP4oI.o: In function `cl::Platform::get(std::vector<cl::Platform, std::allocator<cl::Platform> >*)':
main.cpp:(.text._ZN2cl8Platform3getEPSt6vectorIS0_SaIS0_EE[_ZN2cl8Platform3getEPSt6vectorIS0_SaIS0_EE]+0x41): undefined reference to `clGetPlatformIDs'
main.cpp:(.text._ZN2cl8Platform3getEPSt6vectorIS0_SaIS0_EE[_ZN2cl8Platform3getEPSt6vectorIS0_SaIS0_EE]+0xb4): undefined reference to `clGetPlatformIDs'
collect2: error: ld returned 1 exit status
Order of [most] arguments to g++ is very important.
Libraries should go last (at least after source and object files). You can't really change that.
The -l should preferably be glued to the library name:
g++ -Wall main.cpp -o main -lOpenCL
# ^^^ glue the -l to the library name
You probably want to also pass -g (in addition of -Wall) to the compiler to get a debuggable binary. Use the gdb debugger.
As James Kanze commented, you might want to replace -g with -ggdb if using specifically gdb.
With g++ (and generally under Unix), -l specifies a source of
input (either a .a or a .so), and input is processed in
order. When the input is a static library (a .a file), it
will be scanned for objects which resolve undefined references;
if it is a .so, there aren't any object files in it, but it
will still only be taken into consideration if it resolves some
undefined symbol.
When you put the -l before any object files, there are no
undefined symbols yet, so nothing will be incorporated into the
program.

boost test - 'undefined reference' errors

I have two simple files:
runner.cpp:
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE Main
#include <boost/test/unit_test.hpp>
and test1.cpp:
#define BOOST_TEST_DYN_LINK
#ifdef STAND_ALONE
# define BOOST_TEST_MODULE Main
#endif
#include <boost/test/unit_test.hpp>
BOOST_AUTO_TEST_SUITE( Foo)
BOOST_AUTO_TEST_CASE( TestSomething )
{
BOOST_CHECK( true );
}
BOOST_AUTO_TEST_SUITE_END()
To compile, I'm using:
$ g++ -I/e/code/boost_1_52_0 -o runner -lboost_unit_test_framework runner.cpp test1.cpp
I get the following error:
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ccU0cDSz.o:runner.cpp:(.text+0x8c): multiple definition of `main'
c:/pdev/mingw/bin/../lib/gcc/i686-pc-mingw32/4.7.2/../../../libboost_unit_test_framework.a(unit_test_main.o):unit_test_main.cpp:(.text.startup+0x0): first defined here
c:/pdev/mingw/bin/../lib/gcc/i686-pc-mingw32/4.7.2/../../../libboost_unit_test_framework.a(unit_test_main.o):unit_test_main.cpp:(.text.startup+0x14): undefined reference to `init_unit_test_suite(int, char**)'
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ccU0cDSz.o:runner.cpp:(.text+0x52): undefined reference to `_imp___ZN5boost9unit_test9framework17master_test_suiteEv'
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ccU0cDSz.o:runner.cpp:(.text+0xb0): undefined reference to `_imp___ZN5boost9unit_test14unit_test_mainEPFbvEiPPc'
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ccU0cDSz.o:runner.cpp:(.text$_ZN5boost9unit_test13test_observerD2Ev[__ZN5boost9unit_test13test_observerD2Ev]+0xe): undefined reference to `_imp___ZTVN5boost9unit_test13test_observerE'
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ccU0cDSz.o:runner.cpp:(.text$_ZN5boost9unit_test13test_observerC2Ev[__ZN5boost9unit_test13test_observerC2Ev]+0xe): undefined reference to `_imp___ZTVN5boost9unit_test13test_observerE'
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ccU0cDSz.o:runner.cpp:(.text$_ZN5boost9unit_test15unit_test_log_tC1Ev[__ZN5boost9unit_test15unit_test_log_tC1Ev]+0x22): undefined reference to `_imp___ZTVN5boost9unit_test15unit_test_log_tE'
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\cciSdkmB.o:test1.cpp:(.text+0x88): undefined reference to `_imp___ZN5boost9unit_test15unit_test_log_t14set_checkpointENS0_13basic_cstringIKcEEjS4_'
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\cciSdkmB.o:test1.cpp:(.text+0x136): undefined reference to `_imp___ZN5boost10test_tools9tt_detail10check_implERKNS0_16predicate_resultERKNS_9unit_test12lazy_ostreamENS5_13basic_cstringIKcEEjNS1_10tool_levelENS1_10check_typeEjz'
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\cciSdkmB.o:test1.cpp:(.text+0x21d): undefined reference to `_imp___ZN5boost9unit_test9ut_detail24auto_test_unit_registrarC1ENS0_13basic_cstringIKcEE'
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\cciSdkmB.o:test1.cpp:(.text+0x284): undefined reference to `_imp___ZN5boost9unit_test9ut_detail24auto_test_unit_registrarC1EPNS0_9test_caseEm'
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\cciSdkmB.o:test1.cpp:(.text+0x2a4): undefined reference to `_imp___ZN5boost9unit_test9ut_detail24auto_test_unit_registrarC1Ei'
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\cciSdkmB.o:test1.cpp:(.text$_ZN5boost9unit_test14make_test_caseERKNS0_9callback0INS0_9ut_detail6unusedEEENS0_13basic_cstringIKcEE[__ZN5boost9unit_test14make_test_caseERKNS0_9callback0INS0_9ut_detail6unusedEEENS0_13basic_cstringIKcEE]+0x1d): undefined reference to `_imp___ZN5boost9unit_test9ut_detail24normalize_test_case_nameENS0_13basic_cstringIKcEE'
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\cciSdkmB.o:test1.cpp:(.text$_ZN5boost9unit_test14make_test_caseERKNS0_9callback0INS0_9ut_detail6unusedEEENS0_13basic_cstringIKcEE[__ZN5boost9unit_test14make_test_caseERKNS0_9callback0INS0_9ut_detail6unusedEEENS0_13basic_cstringIKcEE]+0x5b): undefined reference to `_imp___ZN5boost9unit_test9test_caseC1ENS0_13basic_cstringIKcEERKNS0_9callback0INS0_9ut_detail6unusedEEE'
collect2.exe: error: ld returned 1 exit status
I'm using g++ 4.7.2 on MinGW, with boost 1.52.0.
I get the same errors when only trying to compile test1.cpp - except the "multiple main definition" one.
I perused the official documentation for quite a while, but its scarce on details regarding linking options. When I compiled the boost libs, besides unit_test_framework, I also got prg_exec_monitor and test_exec_monitor; perhaps I should link these somehow ? I tried many combinations, but all resulted in some kind of undefined reference linker error.
Complete list of boost generated libraries - I have them all in the project root:
libboost_prg_exec_monitor-mgw47-mt-1_52.a
libboost_prg_exec_monitor-mgw47-mt-1_52.dll
libboost_prg_exec_monitor-mgw47-mt-1_52.dll.a
libboost_prg_exec_monitor-mgw47-mt-d-1_52.a
libboost_prg_exec_monitor-mgw47-mt-d-1_52.dll
libboost_prg_exec_monitor-mgw47-mt-d-1_52.dll.a
libboost_test_exec_monitor-mgw47-mt-1_52.a
libboost_test_exec_monitor-mgw47-mt-d-1_52.a
libboost_unit_test_framework-mgw47-mt-1_52.a
libboost_unit_test_framework-mgw47-mt-1_52.dll
libboost_unit_test_framework-mgw47-mt-1_52.dll.a
libboost_unit_test_framework-mgw47-mt-d-1_52.a
libboost_unit_test_framework-mgw47-mt-d-1_52.dll
libboost_unit_test_framework-mgw47-mt-d-1_52.dll.a
With help from #llonesmiz, a number of issues were identified.
1. Libraries need to be specified after objects and sources which use them.
As described here:
The traditional behavior of linkers is to search for external functions from
left to right in the libraries specified on the command line. This means that a
library containing the definition of a function should appear after any source
files or object files which use it. This includes libraries specified with the
short-cut -l option, as shown in the following command:
$ gcc -Wall calc.c -lm -o calc (correct order)
With some linkers the opposite ordering (placing the -lm option before the file
which uses it) would result in an error,
$ cc -Wall -lm calc.c -o calc (incorrect order)
main.o: In function 'main':
main.o(.text+0xf): undefined reference to 'sqrt'
because there is no library or object file containing sqrt after ‘calc.c’. The
option -lm should appear after the file ‘calc.c’
2. Library paths should be explicitly specified.
If no lib paths are specified, the linker might look for the libs in a series
of default folders, thus loading a different library then intended. This is what
happened in my case - I wanted to link boost_unit_test_framework, but did not
specify a path because I assumed the linker would look in the current folder.
That's what happens at runtime, after all - if the dll is in the same folder
with the exe, it will find it.
I found it a little bit strange the linker would find the lib, since it was
named ibboost_unit_test_framework-mgw47-mt-1_52.dll. When I tried to link to
a non-existing lib, the linker complained though, so I assumed this isn't an
issue, and MinGW 's linker ignores those suffixes.
After some more research, I found this article about MinGW library paths.
The folders MinGW searches for libs can be found in the output of gcc -print-search-dirs.
The article also contains some bash magic to make sense of that output:
gcc -print-search-dirs | sed '/^lib/b 1;d;:1;s,/[^/.][^/]*/\.\./,/,;t 1;s,:[^=]*=,:;,;s,;,; ,g' | tr \; \\012 | grep -v '^ */'
This will print a nice list of those folders. gcc will not, by default,
look in the current directory for libs. I looked in each of them, and found the
lib that was being loaded - libboost_unit_test_framework.a, a static lib.
This brings into light another issue worth mentioning:
3. Static versus dynamic linking
I did not specify whether I want boost_unit_test_framework linked statically or dynamically.
In this case, gcc prefers dynamic linking:
Because of these advantages gcc compiles programs to use shared libraries by
default on most systems, if they are available. Whenever a static library
‘libNAME.a’ would be used for linking with the option -lNAME the compiler
first checks for an alternative shared library with the same name and a ‘.so’
extension.
(so is the extension for dynamic libraries on Unix - on Windows, the equivalent is dll.)
So, what happened is that gcc looked for libboost_unit_test_framework.dll
in all it's default folders, but couldn't find it. Then it looked for
libboost_unit_test_framework.a, and statically linked that. This resulted in
linking errors because the sources have #define BOOST_TEST_DYN_LINK, and
therefore expect to have the lib dynamically linked.
To enforce static or dynamic linking, the -Wl,-Bstatic and -Wl,-Bdynamic
linker options come into play, described here.
If I tell the linker that I want dynamic linking:
$ g++ -I/e/code/boost_1_52_0 runner.cpp test1.cpp -o runner -Wl,Bdynamic -lboost_unit_test_framework
This will fail, because the linker will not be able to find the dll.
4.Summary
The issues were:
libraries where specified before the sources which used them
the lib path wasn't specified
the type of linking wasn't specified
the name of the library was not correct
Final, working command:
$ g++ -I/e/code/boost_1_52_0 -o runner runner.cpp test1.cpp -L. -Wl,-Bdynamic -lboost_unit_test_framework-mgw47-mt-1_52

Undefined Reference Error When Linking to Static Library

I am trying to compile a project that depends on the Xerces XML Parser. The project compiles for Windows without any difficulty, but I'm having some trouble compiling it with g++ in Cygwin.
In order to use Xerces, I am trying to compile my code against the static library libxerces-c.a. But when I do so, I get errors that look like this:
/tmp/cc2QGvMh.o:test.cpp:(.text+0x3a): undefined reference to `xercesc_2_8::DOMImplementationRegistry::getDOMImplementation(unsigned short const*)'
I've inspected the static library using ar, and confirmed that it contains the DOMImplementationRegistry.o file that defines the function that I am calling.
ar -t libxerces-c.a
...
DOMImplementationImpl.o
DOMImplementationRegistry.o
DOMLocatorImpl.o
...
I've also extracted the object files from the library, and used 'nm' to make sure that the function I am calling actually exists:
ar -x libxerces-c.a
nm --demangle DOMImplementationRegistry.o
...
00000080 T xercesc_2_8::getDOMImplSrcVectorMutex()
00000300 T xercesc_2_8::DOMImplementationRegistry::getDOMImplementation(unsigned short const*)
000002a0 T xercesc_2_8::DOMImplementationRegistry::addSource(xercesc_2_8::DOMImplementationSource*)
...
Since I can compile everything for Windows but not with g++, I thought that the error could be in the linker order (similar to the problem described in this question). However, even after changing the linker order, I am still getting the same compiler error. I have tried both
g++ -o test.exe test.cpp -Llib -lxerces-c
and
g++ -o test.exe test.cpp lib/libxerces-c.a
Any ideas?
Your project uses method from xercesc_2_6 namespace as pointed by compiler error message but your library offers xercesc_2_8 version. Problem is probably caused by mismatch between headers you use and library object file.
You didn't say the source of the archive. If it isn't compiled with cygwin, it could be a name mangling problem. Compiling the library from source might well fix this.
It could also be that the archive is built incorrectly so that it has internal resolution problems. Try giving the library name twice.
g++ -o test.exe test.cpp lib/libxerces-c.a lib/libxerces-c.a
If this works, the archive is broken and you should look for or build a new one.
Try the linker option --enable-stdcall-fixup (see 'man ld'). It will care for name mangling and calling conventions:
g++ -o test.exe test.o -Wl,--enable-stdcall-fixup -Llib -lxerces-c