Issue
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?
Solution
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.
Answered By - Fraser