2013-12-18 126 views
4

我想在我的項目中使用Xerces,在cmake和clang的幫助下編譯我的項目。在ubuntu 12.04上設置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 

出了什麼問題,什麼是合適的解決方案? 非常感謝提前。

回答

3

您可能想要將link_directories的使用替換爲find_librarytarget_link_libraries

link_directories只提供鏈接器可以搜索依賴關係的路徑 - 它實際上並不指定這些依賴關係是什麼。此外,從文檔:

請注意,此命令很少需要。由find_package()find_library()返回的庫位置是絕對路徑。將這些絕對庫文件路徑直接傳遞給target_link_libraries()命令。 CMake將確保鏈接器找到它們。

我不熟悉使用Xerces,但假設它只有1個庫稱爲「libxerces-CA」,你應該有類似:

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_PREFIXESCMAKE_FIND_LIBRARY_SUFFIXES)。

此外,如果發現嘗試失敗,更有用的錯誤消息可能無價。您可以建議設置一個指示Xerces庫的位置的變量(例如XERCES_LIB_DIR),這可以添加到find_library調用中的PATHS列表中。

+0

謝謝你這個詳細的答案。但不幸的是,我沒有得到它的工作。我在CMakeLists中添加了這些行。TXT:'find_library(PATH_TO_XERCES libxerces-C的/ usr/local/lib目錄/) IF(NOT PATH_TO_XERCES) 消息(是fatal_error 「無法找到了Xerces庫」)。 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-ca /usr/local/lib/libxerces -c.la /usr/local/lib/libxerces-c.so '所以它應該工作... –

+1

我認爲CMake會在Unix上自動預先設置「lib」作爲名稱。你可以嘗試將名稱設置爲「xerces-c」嗎? – Fraser

+0

謝謝!就是這樣。我會盡量記住,CMake預先「lib」...再次感謝!編輯:你可以編輯你的答案,它包括CMake prepends「lib」,所以我可以將其標記爲答案? –

4

使用FindXercesC是一個簡單快捷的解決方案。

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

target_link_libraries (${PROJECT_NAME} ${XercesC_LIBRARY})