web-dev-qa-db-ja.com

CMakeリンクエラー(未定義の参照)

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)
project(TestClient)

find_package(PkgConfigが必要)
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が必要)
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)

欠落している可能性があります#includemessages_ssl_...ファイルですが、それらはすべて自動生成され、正しいようです。

messages_robocup_ssl_detection.pb.hおよびmessages_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ファイルには、ヘッダーと他の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リンケージ前に既にビルドされている場合、エラーを表示しますか?

追加情報が必要な場合は、お問い合わせください!

14
Lucas

リンク順である可能性があります。

_messages_robocup_ssl_wrapper.pb_は_messages_robocup_ssl_geometry.pb_に依存しているようです。その場合、ラッパーはリンク行にbeforeジオメトリが来るはずです。

_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_を省略することを選択できます。

22
Fraser

undefined reference to ...のもう1つの理由は、ヘッダーではないソースファイルでinlineとしてマークされている関数です。最適化が有効な場合、コンパイラは実際に関数をインライン化し、エラーにつながるシンボルの生成をスキップできます。

この場合の解決策は、インライン関数をヘッダーに移動するか、インラインマークを削除することです。

6
Helmut

このエラーを観察するさらに別の理由は、おそらくそれほど一般的ではないかもしれませんが、ABIには互換性がないことです。

たとえば、ライブラリファイルの1つをフラグ-D_GLIBCXX_USE_CXX11_ABI=0でビルドし、プロジェクトをビルドすることはできません。これは、特にこれが問題になる可能性があることに気付いていない場合、デバッグするのが面倒です。

これはあなたの特定のシナリオの問題ではないことを理解していますが、この答えは他のつまずきの助けになるかもしれません。

5
Martin R.