set up Xerces on ubuntu 12.04 to use with cmake and clang

c++, clang, cmake, ubuntu-12.04, xerces-c

Solution

You probably want to replace your use of `link_directories` with `find_library` and `target_link_libraries`.

`link_directories` only provides paths which the linker can search for dependencies - it doesn't actually specify what those dependencies are. Furthermore, from the docs:

Note that this command is rarely necessary. Library locations returned by `find_package()` and `find_library()` are absolute paths. Pass these absolute library file paths directly to the `target_link_libraries()` command. CMake will ensure the linker finds them.

I'm not familiar with Xerces, but assuming it has only 1 library called "libxerces-c.a", you should probably have something like:

find_library(XercesLibrary NAMES xerces-c PATHS /usr/local/lib)
if(NOT XercesLibrary)
  message(FATAL_ERROR "Failed to find the Xerces library.")
endif()
...
target_link_libraries(MyExe ${XercesLibrary})

You may need to significantly extend this `find_library` process; more `PATHS` than just `/usr/local/lib` could be given; you may need to find more than 1 library (e.g. a Debug version on Windows?), etc. If the library has different names on different operating systems, you may need to provide more `NAME` options (remember CMake may adjust the search name - see `CMAKE_FIND_LIBRARY_PREFIXES` and `CMAKE_FIND_LIBRARY_SUFFIXES`).

Also, a more helpful error message can be invaluable if the find attempt fails. You could suggest to set a variable (e.g. `XERCES_LIB_DIR`) indicating the location of the Xerces library, and this could be added to the list of `PATHS` in the `find_library` call.

Problem

I want to use Xerces in my project, which I compile with the help of cmake and clang. What I did is: - download source - extract it to a folder called 'xerces-c-3.1.1' - cd into that folder - `./configure` - `make` - `make install` Then I wrote `LINK_DIRECTORIES(/usr/local/lib)` into my CMakeLists.txt, and `#include <xercesc/parsers/XercesDOMParser.hpp>` into my main.cpp. It compiles fine, but linking doesn't work. I get the following results: ``` Linking CXX executable DG5_RE CMakeFiles/DG5_RE.dir/main.cpp.o: In function `xercesc_3_1::XMLAttDefList::~XMLAttDefList()': /home/reissmann/Dokumente/DGFromRepo/Source_Cpp_RE/main.cpp:(.text._ZN11xercesc_3_113XMLAttDefListD0Ev[_ZN11xercesc_3_113XMLAttDefListD0Ev]+0x1e): undefined reference to `xercesc_3_1::XMemory::operator delete(void*)' CMakeFiles/DG5_RE.dir/main.cpp.o: In function `xercesc_3_1::DTDEntityDecl::~DTDEntityDecl()': /home/reissmann/Dokumente/DGFromRepo/Source_Cpp_RE/main.cpp:(.text._ZN11xercesc_3_113DTDEntityDeclD0Ev[_ZN11xercesc_3_113DTDEntityDeclD0Ev]+0x1e): undefined reference to `xercesc_3_1::XMemory::operator delete(void*)' CMakeFiles/DG5_RE.dir/main.cpp.o: In function `xercesc_3_1::DTDEntityDecl::~DTDEntityDecl()': /home/reissmann/Dokumente/DGFromRepo/Source_Cpp_RE/main.cpp:(.text._ZN11xercesc_3_113DTDEntityDeclD2Ev[_ZN11xercesc_3_113DTDEntityDeclD2Ev]+0x11): undefined reference to `xercesc_3_1::XMLEntityDecl::~XMLEntityDecl()' CMakeFiles/DG5_RE.dir/main.cpp.o:(.rodata._ZTVN11xercesc_3_113XMLAttDefListE[_ZTVN11xercesc_3_113XMLAttDefListE]+0x20): undefined reference to `xercesc_3_1::XMLAttDefList::isSerializable() const' CMakeFiles/DG5_RE.dir/main.cpp.o:(.rodata._ZTVN11xercesc_3_113XMLAttDefListE[_ZTVN11xercesc_3_113XMLAttDefListE]+0x28): undefined reference to `xercesc_3_1::XMLAttDefList::serialize(xercesc_3_1::XSerializeEngine&)' CMakeFiles/DG5_RE.dir/main.cpp.o:(.rodata._ZTVN11xercesc_3_113XMLAttDefListE[_ZTVN11xercesc_3_113XMLAttDefListE]+0x30): undefined reference to `xercesc_3_1::XMLAttDefList::getProtoType() const' CMakeFiles/DG5_RE.dir/main.cpp.o:(.rodata._ZTVN11xercesc_3_113DTDEntityDeclE[_ZTVN11xercesc_3_113DTDEntityDeclE]+0x20): undefined reference to `xercesc_3_1::DTDEntityDecl::isSerializable() const' CMakeFiles/DG5_RE.dir/main.cpp.o:(.rodata._ZTVN11xercesc_3_113DTDEntityDeclE[_ZTVN11xercesc_3_113DTDEntityDeclE]+0x28): undefined reference to `xercesc_3_1::DTDEntityDecl::serialize(xercesc_3_1::XSerializeEngine&)' CMakeFiles/DG5_RE.dir/main.cpp.o:(.rodata._ZTVN11xercesc_3_113DTDEntityDeclE[_ZTVN11xercesc_3_113DTDEntityDeclE]+0x30): undefined reference to `xercesc_3_1::DTDEntityDecl::getProtoType() const' CMakeFiles/DG5_RE.dir/main.cpp.o:(.rodata._ZTIN11xercesc_3_113DTDEntityDeclE[_ZTIN11xercesc_3_113DTDEntityDeclE]+0x10): undefined reference to `typeinfo for xercesc_3_1::XMLEntityDecl' clang: error: linker command failed with exit code 1 (use -v to see invocation) make[2]: *** [DG5_RE] Fehler 1 make[1]: *** [CMakeFiles/DG5_RE.dir/all] Fehler 2 make: *** [all] Fehler 2 ``` What went wrong, and what is the appropriate solution? Many thanks in advance.

Original source