Linking with TinyXML++
For a project I'm starting work on, I decided that XML would be a useful tool to make use of. Since I intended to write my program in C++, I cast about for a good library, and came across TinyXML and from there came to TinyXML++. It looked great: very light weight (only 9 source code files) and the example code I looked at showed that it was very easy to use.
So I downloaded it, wrote up a simple test program and tried to compile it. Well, it compiled, but it most certainly didn't link:
collect2: ld returned 1 exit status
ld: symbol(s) not found
"ticpp::Document::LoadFile(TiXmlEncoding)", referenced from:
load(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)in main.o
"ticpp::Element::HasAttribute(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const", referenced from:
GraphicRecord::GraphicRecord(ticpp::Element&)in main.o
GraphicRecord::GraphicRecord(ticpp::Element&)in main.o
GraphicRecord::GraphicRecord(ticpp::Element&)in main.o
. . . And so on. After a little poking around, I could see that the definitions of all of the missing symbols were wrapped in #ifdef TIXML_USE_TICPP blocks. I had thought that this would be no problem, as I had (before including any of the TiCPP headers) thrown in a #define TIXML_USE_TICPP since I did, in fact, want to use the TiCPP additions to TinyXML. I tried editing the TiCPP headers to #define the constant by brute force, and even tried just plain commenting out the #ifdefs, but none of it worked.
Today I got suspicious and did a full project search, causing me to discover this charming little bit of code at the top of the main implementation file:
#ifdef TIXML_USE_TICPP
#include "ticpp.h"
#include "ticpprc.h"
#include "tinyxml.h"
#include <sstream>
This #ifdef wrapped the entire contents of the file, including the #includes. This meant that the preprocessor would skip the entire contents of the file without being able to find out that one of the included headers would tell it not to. This choice on the part of the creators of the library strikes me a s a little odd; after all if I'm compiling and linking this file it had had better be because I want to use the library of which it is a part, which this simple preprocessor directive make very difficult.