2013-05-15 97 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的函数不是标题的源文件。启用优化时,编译器可以实际内联函数并跳过生成导致错误的符号。

对于这种情况,解决方案是将内联函数移动到标题或移除内联标记。