web-dev-qa-db-ja.com

CMake with Google Protocol Buffers

Cmakeを使用して、プロトコルバッファーを使用して小さなプロジェクトをビルドしようとしています。

多数のライブラリと実行可能ファイルを含む多数のサブディレクトリを持つルートディレクトリがあります。私の最初の考えは、サブディレクトリに.proto-filesを置くことでしたが、私が読んだとき この答え 代わりにライブラリを作成しました。しかし、実行可能ファイルにメッセージヘッダーを含めようとしても、見つかりません。

エラーメッセージ:

fatal error: msgs.pb.h: No such file or directory
 #include "msgs.pb.h"
                     ^
compilation terminated.

Dir "build"を作成し、その中から "cmake .. && make"を作成して実行しています。私が見たところ、生成されたファイルがビルド/メッセージに入れられるようですので、include_directories(build/messages)を行うことができましたが、それは...適切ではないようです。 protobufでこれを行う適切な方法はありますか?メッセージファイルを独自のフォルダに配置する理由は、メッセージがさまざまな小さな実行可能ファイルで使用されるためです。

私のCMake構造を改善するための他の一般的なヒントも評価されます:)

ディレクトリ:

root
   messages
   core
   server

root/CMakeLists.txt:

project(lillebror)
cmake_minimum_required(VERSION 2.8)
cmake_policy(SET CMP0015 NEW)

set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
find_package(Boost COMPONENTS date_time log thread system)
find_package(Protobuf REQUIRED)
if(Boost_FOUND)
    add_definitions(-std=c++11)
    add_subdirectory(messages)
    add_subdirectory(core)
    add_subdirectory(server)
    add_subdirectory(testserver)
endif()

messages/CMakeLists.txt:

file(GLOB ProtoFiles "${CMAKE_CURRENT_SOURCE_DIR}/*.proto")
PROTOBUF_GENERATE_CPP(ProtoSources ProtoHeaders ${ProtoFiles})
add_library(messages STATIC ${ProtoSources} ${ProtoHeaders})
target_link_libraries(messages ${Boost_LIBRARIES} ${PROTOBUF_LIBRARY})

core/CMakeLists.txt:

aux_source_directory(src SRC_LIST)
add_library(core STATIC ${SRC_LIST})
target_link_libraries(core messages ${Boost_LIBRARIES})

server/CMakeLists.txt:

aux_source_directory(src SRC_LIST)
include_directories(../messages) <---- I thought this would sove my problem
include_directories(../core/src)
link_directories(../core/build)
add_executable(server ${SRC_LIST})
target_link_libraries(server core ${Boost_LIBRARIES})

server/main.cpp:

#include "msgs.pb.h"
int main()
{
    return 0;
}
17
dutt

ここでの問題は _PROTOBUF_GENERATE_CPP_ 関数が.pb.hファイルと.pb.ccファイルをソースツリーではなくビルドツリーに存在するように設定することだと思います。

これは良い方法です(ソースツリーを汚染しない)が、呼び出しinclude_directories(../messages)が誤った値を検索パスに追加していることを意味します。これにより、ソースディレクトリ「root/messages」が追加されますが、「[ビルドルート]/messages」が必要です。

あなたはおそらくその行を単に次のように置き換えることができます:

_include_directories(${CMAKE_BINARY_DIR}/messages)
_

ただし、より堅牢で保守可能な方法は、messages/CMakeLists.txt内に必要なインクルードパスを設定することです。この値を親スコープに公開するには、set(... PARENT_SCOPE)または次のいずれかを使用する必要があります。

_set(ProtobufIncludePath ${CMAKE_CURRENT_BINARY_DIR}
    CACHE INTERNAL "Path to generated protobuf files.")
_

次に、最上位のCMakeLists.txtで次のことができます。

_include_directories(${ProtobufIncludePath})
_

messagesライブラリ自体が生成されたprotobufファイルを#includeする必要がある場合(これは正常です)、同様に_include_directories_呼び出しが必要です。

以上のことから、CMake v2.8.12を最小として指定できる場合は、代わりに _target_include_directories_ コマンドを使用できます。

_add_library_呼び出し後のmessages/CMakeLists.txtでは、次のようにします。

_target_include_directories(messages PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
_

次に、messagesに依存する他のターゲットには、適切な「メッセージ」インクルードディレクトリが自動的に追加されます。明示的に_include_directories_を呼び出す必要はありません。

23
Fraser