2013-05-15 183 views
9

我正在使用SSL-Vision軟件。它有一個示例客戶端,我一直試圖從整個項目中分離出來。我發現自己需要編輯客戶端的源代碼,所以我只是從軟件中複製它們並使用CMake來構建我的客戶端。CMake鏈接錯誤(未定義參考)

下面的項目結構被簡化,縮小到問題(我相信!)。

. 
├── CMakeLists.txt 
├── main.cc 
├── build 
│ ├── CMakeLists.txt 
│ └── messages_ssl_... (.cc/.h, 4 each) 
└── src 
    ├── CMakeLists.txt 
    └── (Other subdirs and sources/headers) 

./CMakeLists.txt

cmake_minimum_required(版本2.6)
項目(TestClient的)

find_package(PkgConfig必填)
pkg_check_modules(QTCORE_PKG QtCore)
include_directories($ {QTCORE_PKG_INCLUDE_DIRS})

包括(FindProtobuf)
find_package(的Protobuf REQUIRED)
include_directories($ {PROTOBUF_INCLUDE_DIRS})

find_package(PkgConfig REQUIRED)
pkg_check_modules(GLIB_PKG油嘴-2.0)
include_directories($ {GLIB_PKG_INCLUDE_DIRS})

include_directories( 「SRC」)add_subdirectory(SRC)

include_directories(「BUIL d」)add_subdirectory(構建)

add_executable(clientTest clientTest.cc)

target_link_libraries(clientTest robocup_ssl_client messages_robocup_ssl_detection.pb messages_robocup_ssl_geometry.pb messages_robocup_ssl_wrapper.pb messages_robocup_ssl_refbox_log.pb netraw robocup_ssl_client protobuf的QtCore)

./build/CMakeLists.txt

add_library(messages_robocup_ssl_detection.pb SHARED messages_robocup_ssl_detection.pb.cc)

add_library(messages_robocup_ssl_refbox_log.pb SHARED messages_robocup_ssl_refbox_log.pb.cc)

add_library(messages_robocup_ssl_geometry.pb SHARED messages_robocup_ssl_geometry.pb.cc)

add_library(messages_robocup_ssl_wrapper.pb SHARED messages_robocup_ssl_wrapper.pb.cc)

messages_ssl_...文件中可能缺少#include,但它們都是自動生成的,似乎是正確的。

messages_robocup_ssl_detection.pb.hmessages_robocup_ssl_detection.pb.h只有protobuf包括。

messages_robocup_ssl_refbox_log.pb.h

#include "messages_robocup_ssl_detection.pb.h" 
// Other protobuf includes 

messages_robocup_ssl_wrapper.h

#include "messages_robocup_ssl_detection.pb.h" 
#include "messages_robocup_ssl_geometry.pb.h" 
// Other protobuf includes 

在各.cc文件僅包括其標題和其他的protobuf庫。

最後,當我做,會生成以下錯誤:

Linking CXX executable clientTest 
build/libmessages_robocup_ssl_wrapper.pb.so: undefined reference to `SSL_GeometryData::ByteSize() const' 
build/libmessages_robocup_ssl_wrapper.pb.so: undefined reference to `SSL_GeometryData::MergeFrom(SSL_GeometryData const&)' 
build/libmessages_robocup_ssl_wrapper.pb.so: undefined reference to `protobuf_AddDesc_messages_5frobocup_5fssl_5fgeometry_2eproto()' 
build/libmessages_robocup_ssl_wrapper.pb.so: undefined reference to `SSL_GeometryData::Clear()' 
build/libmessages_robocup_ssl_wrapper.pb.so: undefined reference to `SSL_GeometryData::SSL_GeometryData()' 
build/libmessages_robocup_ssl_wrapper.pb.so: undefined reference to `SSL_GeometryData::default_instance()' 
build/libmessages_robocup_ssl_wrapper.pb.so: undefined reference to `SSL_GeometryData::SerializeWithCachedSizesToArray(unsigned char*) const' 
build/libmessages_robocup_ssl_wrapper.pb.so: undefined reference to `SSL_GeometryData::MergePartialFromCodedStream(google::protobuf::io::CodedInputStream*)' 
collect2: ld returned 1 exit status 
make[2]: ** [clientTest] Erro 1 
make[1]: ** [CMakeFiles/clientTest.dir/all] Erro 2 
make: ** [all] Erro 2 

我一直在試圖解決這一問題有一段時間了。 爲什麼libmessages_robocup_ssl_wrapper.pb.so顯示錯誤,如果它已經建立在鏈接之前?

如果有任何額外的信息需要,請問!

回答

14

這可能是鏈接順序。

看起來像messages_robocup_ssl_wrapper.pb取決於messages_robocup_ssl_geometry.pb。如果是這樣,包裝應在之前來連接線的幾何。

target_link_libraries(clientTest robocup_ssl_client 
         messages_robocup_ssl_detection.pb 
         messages_robocup_ssl_wrapper.pb 
         messages_robocup_ssl_geometry.pb 
         messages_robocup_ssl_refbox_log.pb 
         netraw 
         robocup_ssl_client 
         protobuf 
         QtCore) 

更好的是,讓CMake照顧這樣的依賴關係。

如果添加...

target_link_libraries(messages_robocup_ssl_wrapper.pb 
         messages_robocup_ssl_geometry.pb) 

那麼當messages_robocup_ssl_wrapper.pb被指定爲另一個目標的依賴的CMake將自動保留該相關性。如果你這樣做,那麼你可以選擇從target_link_libraries(clientTest ...)呼叫中省略messages_robocup_ssl_geometry.pb

+0

它的工作! 就像你所說的那樣只是換了一條線,而且它完美地工作。 我還添加了這兩行,CMake從現在開始已經知道'messages_robocup_ssl_wrapper.pb'依賴於'messages_robocup_ssl_geometry.pb'。 謝謝! – Lucas

+0

好東西。很高興你修好了它。 – Fraser

3

undefined reference to ...的另一個原因可能是標記爲inline的函數不是標題的源文件。啓用優化時,編譯器可以實際內聯函數並跳過生成導致錯誤的符號。

對於這種情況,解決方案是將內聯函數移動到標題或移除內聯標記。

相關問題