首页 文章

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

提问于
浏览
9

我正在使用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(版本2.6)项目(TestClient的)find_package(PkgConfig必填)pkg_check_modules(QTCORE_PKG QtCore)include_directories($ )包括(FindProtobuf)find_package(的Protobuf必填)include_directories($ )find_package(PkgConfig必填)pkg_check_modules( GLIB_PKG油嘴-2.0)include_directories($ )include_directories( “SRC”)add_subdirectory(SRC)include_directories( “构建”)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文件中只包含其 Headers 和其他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 在链接之前已经构建错误,为什么会显示错误?

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

2 回答

  • 15

    它很可能是链接顺序 .

    它看起来像 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 .

  • 4

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

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

相关问题