Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CMake linking error (undefined reference to)

Tags:

I am working with the SSL-Vision software. It has an example client that I've been trying to separate from the whole project. I found the sources needed to edit a client myself, so I just copied them from the software and used CMake to build my client.

The project structure below is simplified, narrowing to the issue (I believe!).

. ├── 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} )  include(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 ) 

./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 ) 

It could be a missing #include in the messages_ssl_... files, but they all are auto-generated and seems to be correct.

In messages_robocup_ssl_detection.pb.h and messages_robocup_ssl_detection.pb.h there are only protobuf includes.

In messages_robocup_ssl_refbox_log.pb.h:

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

In messages_robocup_ssl_wrapper.h:

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

In each .cc file is included only its header and other protobuf libs.

Finally, when I do make, the following error is generated:

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 

I've been trying to fix this for some time. Why is the libmessages_robocup_ssl_wrapper.pb.so showing errors if it has already been built before the linkage?

like image 576
Lucas Avatar asked May 15 '13 20:05

Lucas


1 Answers

It could well be the linking order.

It looks like messages_robocup_ssl_wrapper.pb depends on messages_robocup_ssl_geometry.pb. If so, wrapper should come before geometry in the link line.

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 ) 

Even better, let CMake take care of dependencies like this.

If you add...

target_link_libraries( messages_robocup_ssl_wrapper.pb                        messages_robocup_ssl_geometry.pb ) 

then CMake will automatically retain that dependency when messages_robocup_ssl_wrapper.pb is specified as a dependency of another target. If you do this, then you can choose to omit messages_robocup_ssl_geometry.pb from the target_link_libraries( clientTest ... ) call.

like image 77
Fraser Avatar answered Oct 11 '22 14:10

Fraser