CMake链接错误(未定义引用)

时间:2013-05-15 20:12:00

标签: cmake linker-errors robocup

我正在使用SSL-Vision软件。它有一个示例客户端,我一直试图从整个项目中分离出来。我找到了自己编辑客户端所需的资源,所以我只是从软件中复制它们并使用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(VERSION 2.6)
  project(TestClient)

     

find_package(PkgConfig REQUIRED)
  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 glib-2.0)
  include_directories($ {GLIB_PKG_INCLUDE_DIRS})

     

include_directories(“src”)add_subdirectory(src)

     

include_directories(“build”)add_subdirectory(build)

     

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)

./建立/的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在链接之前已经构建错误,为什么会显示错误?

如果需要任何其他信息,请询问!

3 个答案:

答案 0 :(得分:18)

很可能是链接顺序。

看起来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将自动保留该依赖关系。如果您这样做,则可以选择忽略messages_robocup_ssl_geometry.pb来电中的target_link_libraries( clientTest ... )

答案 1 :(得分:4)

undefined reference to ...的另一个原因可能是源文件中标记为inline的函数不是标题。启用优化后,编译器实际上可以内联函数并跳过生成导致错误的符号。

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

答案 2 :(得分:1)

观察到此错误的另一个原因(虽然可能不太常见)是ABI不兼容。

例如,可以使用标志-D_GLIBCXX_USE_CXX11_ABI=0来构建其中一个库文件,而不能使用该标志。调试起来很麻烦,尤其是在不知道这可能是问题的时候。

我意识到这不是您的特定情况下的问题,但是此答案可能会帮助其他人对此绊脚石。