2013-05-15 11 views
9

Pracuję z oprogramowaniem SSL-Vision. Ma przykład klienta, który próbuję oddzielić od całego projektu. Znalazłem źródła potrzebne do samodzielnej edycji klienta, więc skopiowałem je z oprogramowania i użyłem CMake do zbudowania mojego klienta.Błąd łączenia CMake (niezdefiniowane odniesienie do)

Poniższa struktura projektu jest uproszczona, zawężona do problemu (chyba!).

. 
├── 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 (wersja 2.6)
Project (TestClient)

find_package (WYMAGANY PkgConfig)
pkg_check_modules (QTCORE_PKG QtCore)
include_directories ($ {QTCORE_PKG_INCLUDE_DIRS})

obejmują (FindProtobuf)
find_package (buforów WYMAGANY)
include_directories ($ {PROTOBUF_INCLUDE_DIRS})

find_package (PkgConfig WYMAGANY)
pkg_check_modules (GLIB_PKG płynny-2.0)
include_directories ($ {GLIB_PKG_INCLUDE_DIRS})

include_directories ("src") add_subdirectory (sRC)

include_directories („bu d”) add_subdirectory (budowa)

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 buforów QtCore)

./build/CMakeLists.txt:

add_library (messages_robocup_ssl_detection.pb dzielony 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 dzielony messages_robocup_ssl_wrapper.pb.cc)

Może to być brakujące #include w plikach messages_ssl_..., ale wszystkie są generowane automatycznie i wydają się poprawne.

W messages_robocup_ssl_detection.pb.h i messages_robocup_ssl_detection.pb.h obejmuje tylko protobuf.

W messages_robocup_ssl_refbox_log.pb.h:

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

W messages_robocup_ssl_wrapper.h:

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

W każdym pliku .cc wliczone jest tylko jego nagłówek i inne bibliotekami Protobuf.

Wreszcie, kiedy robią następujący błąd jest generowany:

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 

Próbowałem rozwiązać ten problem przez pewien czas. Dlaczego libmessages_robocup_ssl_wrapper.pb.so pokazuje błędy, jeśli zostały już zbudowane przed połączeniem?

Jeśli potrzebujesz dodatkowych informacji, po prostu zapytaj!

Odpowiedz

14

Może to być również kolejność linków.

Wygląda na to, że messages_robocup_ssl_wrapper.pb zależy od messages_robocup_ssl_geometry.pb. Jeśli tak, to wrapper powinien przyjść przed geometrią w linii łącza.

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) 

Jeszcze lepiej, niech CMake zajmie się zależnościami takimi jak ta.

Jeśli dodać ...

target_link_libraries(messages_robocup_ssl_wrapper.pb 
         messages_robocup_ssl_geometry.pb) 

następnie CUpewnij automatycznie zachować tę zależność, gdy messages_robocup_ssl_wrapper.pb jest określony jako zależność innego celu. Jeśli to zrobisz, możesz pominąć messages_robocup_ssl_geometry.pb z połączenia target_link_libraries(clientTest ...).

+0

Zadziałało! Po prostu zamieniłem linie, tak jak powiedziałeś, i zadziałało idealnie. Też dodałem te dwie linie, a CMake już wie, że 'messages_robocup_ssl_wrapper.pb' zależy od' messages_robocup_ssl_geometry.pb' od teraz. Dziękujemy! – Lucas

+0

Dobre rzeczy. Cieszę się, że to naprawiłeś. – Fraser

3

Innym powodem dla undefined reference to ... może być funkcja oznaczona jako inline w pliku źródłowym, który nie jest nagłówkiem. Po włączeniu optymalizacji kompilator może wstawić funkcję i pominąć generowanie symbolu prowadzącego do błędu.

W tym przypadku rozwiązaniem jest przeniesienie funkcji wbudowanych do nagłówków lub usunięcie znaku wbudowanego.