I want to use Xerces in my project, which I compile with the help of cmake and clang.
What I did is:
./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.
Use the FindXercesC is an easy and quick solution.
include(FindXercesC)
find_package(XercesC REQUIRED)
include_directories( ${XercesC_INCLUDE_DIR} )
target_link_libraries ( ${PROJECT_NAME} ${XercesC_LIBRARY} )
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()
andfind_library()
are absolute paths. Pass these absolute library file paths directly to thetarget_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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With