在 ubuntu 12.04 上设置 Xerces 以与 cmake 和 clang 一起使用



我想在我的项目中使用 Xerces,我在 cmake 和 clang 的帮助下编译了它。

我所做的是:

  • 下载源码
  • 将其解压缩到名为"Xerces-C-3.1.1"的文件夹中
  • CD 到该文件夹中
  • ./configure
  • make
  • make install

然后我把LINK_DIRECTORIES(/usr/local/lib)写到我的CMakeLists.txt中,#include <xercesc/parsers/XercesDOMParser.hpp>写进我的主.cpp。

它编译得很好,但链接不起作用。我得到以下结果:

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

出了什么问题,适当的解决方案是什么?提前非常感谢。

使用 FindXercesC 是一个简单快捷的解决方案。

include(FindXercesC)
find_package(XercesC REQUIRED)
include_directories( ${XercesC_INCLUDE_DIR} )
target_link_libraries ( ${PROJECT_NAME} ${XercesC_LIBRARY} )

您可能希望将link_directories的使用替换为find_librarytarget_link_libraries

link_directories仅提供链接器可以搜索依赖项的路径 - 它实际上并未指定这些依赖项是什么。 此外,从文档中:

请注意,此命令很少是必需的。find_package()返回的库位置和find_library()是绝对路径。将这些绝对库文件路径直接传递给 target_link_libraries() 命令。CMake 将确保链接器找到它们。

我不熟悉 Xerces,但假设它只有 1 个名为"libxerces-c.a"的库,您可能应该有这样的东西:

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})

您可能需要大大扩展此find_library过程;比给出/usr/local/libPATHS;您可能需要找到一个以上的库(例如Windows上的调试版本?)等。 如果库在不同的操作系统上具有不同的名称,则可能需要提供更多NAME选项(请记住,CMake 可能会调整搜索名称 - 请参阅CMAKE_FIND_LIBRARY_PREFIXESCMAKE_FIND_LIBRARY_SUFFIXES)。

此外,如果查找尝试失败,更有用的错误消息可能非常宝贵。 您可以建议设置一个变量(例如 XERCES_LIB_DIR ) 指示 Xerces 库的位置,这可以添加到find_library调用中的PATHS列表中。

最新更新