我想在我的项目中使用 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_library
和target_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/lib
更PATHS
;您可能需要找到一个以上的库(例如Windows上的调试版本?)等。 如果库在不同的操作系统上具有不同的名称,则可能需要提供更多NAME
选项(请记住,CMake 可能会调整搜索名称 - 请参阅CMAKE_FIND_LIBRARY_PREFIXES
和CMAKE_FIND_LIBRARY_SUFFIXES
)。
此外,如果查找尝试失败,更有用的错误消息可能非常宝贵。 您可以建议设置一个变量(例如 XERCES_LIB_DIR
) 指示 Xerces 库的位置,这可以添加到find_library
调用中的PATHS
列表中。