【问题标题】:set up Xerces on ubuntu 12.04 to use with cmake and clang在 ubuntu 12.04 上设置 Xerces 以与 cmake 和 clang 一起使用
【发布时间】:2014-01-07 00:16:47
【问题描述】:

我想在我的项目中使用 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> 写入我的main.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

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

【问题讨论】:

    标签: c++ cmake ubuntu-12.04 clang xerces-c


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      您可能希望将 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 流程;可以给出更多的PATHS 而不仅仅是/usr/local/lib;您可能需要查找超过 1 个库(例如 Windows 上的 Debug 版本?)等。如果库在不同操作系统上具有不同的名称,您可能需要提供更多 NAME 选项(记住 CMake 可能会调整搜索名称- 见CMAKE_FIND_LIBRARY_PREFIXESCMAKE_FIND_LIBRARY_SUFFIXES)。

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

      【讨论】:

      • 感谢您的详细回答。但不幸的是,我没有让它工作。我在我的 CMakeLists.txt 中添加了这些行:find_library( PATH_TO_XERCES libxerces-c /usr/local/lib/ ) IF(NOT PATH_TO_XERCES) message(FATAL_ERROR "Failed to find the Xerces library.") ENDIF() target_link_libraries (DG5_RE ${PATH_TO_XERCES}),我收到错误“无法找到 Xerces 库”。但我在 shell 中做了:locate xerces,输出为:/usr/local/lib/libxerces-c-3.1.so /usr/local/lib/libxerces-c.a /usr/local/lib/libxerces-c.la /usr/local/lib/libxerces-c.so 所以它应该可以工作......
      • 我认为 CMake 会自动在 Unix 上的名称前添加“lib”。您可以尝试将名称设置为“xerces-c”吗?
      • 谢谢!就是这样。我会尽量记住,CMake 会在前面加上“lib”……再次感谢!编辑:你能编辑你的答案吗,它包括 CMake 前置“lib”,所以我可以将它标记为答案?
      • @Rico-E - 现已更新。谢谢。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-07-27
      • 1970-01-01
      • 1970-01-01
      • 2012-09-23
      • 2012-10-27
      • 2023-03-24
      • 1970-01-01
      相关资源
      最近更新 更多