2013-05-15 36 views
9

Tôi đang làm việc với phần mềm SSL-Vision. Nó có một khách hàng ví dụ mà tôi đã cố gắng tách ra khỏi toàn bộ dự án. Tôi tìm thấy các nguồn cần thiết để chỉnh sửa một khách hàng, vì vậy tôi chỉ sao chép chúng từ phần mềm và sử dụng CMake để xây dựng khách hàng của tôi.Lỗi liên kết CMake (tham chiếu không xác định)

Cấu trúc dự án bên dưới được đơn giản hóa, thu hẹp cho vấn đề (tôi tin!).

. 
├── 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) dự án
(TestClient)

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

bao gồm (FindProtobuf)
find_package (Protobuf REQUIRED)
include_directories ($ {PROTOBUF_INCLUDE_DIRS})

find_package (PkgConfig REQUIRED)
pkg_check_modules (GLIB_PKG lém lỉnh-2.0)
include_directories ($ {GLIB_PKG_INCLUDE_DIRS})

include_directories ("src") add_subdirectory (src)

include_directories ("buil d") add_subdirectory (xây dựng)

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 CHIA SẺ messages_robocup_ssl_detection.pb.cc)

add_library (messages_robocup_ssl_refbox_log.pb messages_robocup_ssl_refbox_log.pb.cc CHIA SẺ)

add_library (messages_robocup_ssl_geometry.pb messages_robocup_ssl_geometry.pb.cc chia sẻ)

add_library (messages_robocup_ssl_wrapper.pb CHIA SẺ messages_robocup_ssl_wrapper.pb.cc)

Có thể thiếu #include trong các tệp messages_ssl_... nhưng tất cả đều được tạo tự động và có vẻ chính xác.

Trong messages_robocup_ssl_detection.pb.hmessages_robocup_ssl_detection.pb.h chỉ có bao gồm protobuf.

Trong messages_robocup_ssl_refbox_log.pb.h:

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

Trong messages_robocup_ssl_wrapper.h:

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

Trong mỗi tập tin .cc được bao gồm chỉ tiêu đề và libs protobuf khác.

Cuối cùng, khi tôi thực hiện, các lỗi sau đây được tạo:

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 

Tôi đã cố gắng để sửa lỗi này trong một thời gian. Tại sao libmessages_robocup_ssl_wrapper.pb.so hiển thị lỗi nếu nó đã được tạo trước liên kết?

Nếu có bất kỳ thông tin bổ sung nào cần thiết, chỉ cần hỏi!

Trả lời

14

Nó cũng có thể là thứ tự liên kết.

Có vẻ như messages_robocup_ssl_wrapper.pb phụ thuộc vào messages_robocup_ssl_geometry.pb. Nếu vậy, trình bao bọc phải đến trước hình dạng trong dòng liên kết.

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) 

Thậm chí tốt hơn, hãy để CMake chăm sóc các phụ thuộc như thế này.

Nếu bạn thêm ...

target_link_libraries(messages_robocup_ssl_wrapper.pb 
         messages_robocup_ssl_geometry.pb) 

sau đó CMake sẽ tự động giữ lại phụ thuộc mà khi messages_robocup_ssl_wrapper.pb được quy định như một sự phụ thuộc của đối tượng khác. Nếu bạn làm điều này, bạn có thể chọn bỏ qua messages_robocup_ssl_geometry.pb từ cuộc gọi target_link_libraries(clientTest ...).

+0

Đã hoạt động! Chỉ cần vuốt các dòng như bạn đã nói, và nó hoạt động hoàn hảo. Tôi cũng đã thêm hai dòng đó và CMake đã biết rằng 'messages_robocup_ssl_wrapper.pb' phụ thuộc vào' messages_robocup_ssl_geometry.pb' từ bây giờ trở đi. Cảm ơn bạn! – Lucas

+0

Nội dung hay. Vui vì bạn đã sửa nó. – Fraser

3

Lý do khác cho undefined reference to ... có thể là chức năng được đánh dấu là inline trong tệp nguồn không phải là tiêu đề. Khi tối ưu hóa được kích hoạt, trình biên dịch có thể thực sự inline chức năng và bỏ qua tạo ra các biểu tượng dẫn đến lỗi.

Đối với trường hợp này, giải pháp là di chuyển các hàm nội tuyến sang tiêu đề hoặc loại bỏ dấu nội dòng.

Các vấn đề liên quan