14

プロトコル バッファ ファイルがサブディレクトリにあるプロジェクトで FindProtobuf モジュールを使用しています。そのサブディレクトリにある CMakeLists.txt ファイルで protoc を呼び出して CPP ファイルを生成する必要があります。私のプロジェクトのフォルダー構造は次のようになります。

cammy/CMakeLists.txt   # Root CMakeLists.txt
cammy/protofiles/test.proto # protofile
cammy/protofiles/CMakeLists.txt

protobuf フォルダーの CMakeLists.txt ファイルに、include(FindProtobuf)、find_package 呼び出し、および PROTOBUF_GENERATE_CPP の呼び出しがあります。

実行可能ビルド ステップはルート CMakeLists.txt ファイルにあり、生成されたファイルをこのファイルのターゲット実行可能ファイルに追加します。

add_executable( ${EXEC} ${SRCS} ${PROTO_SRC} ${PROTO_HEADER} )
target_link_libraries( ${EXEC} ${PROTOBUF_LIBRARIES} )

どちらもルート CMakeLists.txt で定義されています

cmake を実行すると、生成されたソースを実行可能ファイルに明示的に結び付けて依存関係を作成しているにもかかわらず、protoc を実行してソース ファイルを生成しません。

protofiles フォルダーの CMakeLists.txt のすべてのコンテンツをルート CMakeLists.txt に移動すると、proto ファイルがコンパイルされます。

誰でもこれで私を助けることができますか?protofiles フォルダーに作成された CMakeLists.txt ファイルにすべてのプロトコル バッファー ビルドを入れたいと思います。

また、内側の CMakeLists.txt で生成された変数 ( PROTO_SRC など) は、印刷時に内側のファイルで定義されていることに気付きました (つまり、正しい生成された CPP ファイル名を取得します) が、同じ変数をルート ファイルに印刷すると..空です。 . 変数をルートフォルダーに「エクスポート」する必要があるかのようです( cmake に方法があった場合)。

どんな助けでも大歓迎です。

ありがとうカルティック

4

1 に答える 1

25

FindProtobufは、このように使用することを意図したものではないと思います。そのドキュメントから:

注:PROTOBUF_GENERATE_CPPマクロ &add_executable()またはadd_library() 呼び出しは、同じディレクトリ内でのみ正しく機能します。

サブディレクトリでマクロを使用しようとしていますPROTOBUF_GENERATE_CPP。CMake ドキュメントでは実際には明確にされていませんが、サブディレクトリは変数の新しいスコープを導入しています。つまり、subdir スコープで設定または変更された変数は、親スコープの同様の名前の変数には影響しません。PROTO_SRCしたがって、プロファイルディレクトリでは使用できますが、親では使用できない理由です。

変数をスコープに渡す方法は、を使用するset(... PARENT_SCOPE)ことです。そのため、protofiles/CMakeLists.txt で次のように実行できます。

PROTOBUF_GENERATE_CPP(PROTO_SRC PROTO_HEADER test.proto)

set(PROTOBUF_INCLUDE_DIRS ${PROTOBUF_INCLUDE_DIRS} PARENT_SCOPE)
set(PROTOBUF_LIBRARIES ${PROTOBUF_LIBRARIES} PARENT_SCOPE)
set(PROTO_SRC ${PROTO_SRC} PARENT_SCOPE)
set(PROTO_HEADER ${PROTO_HEADER} PARENT_SCOPE)

しかし、これですべてが解決するわけではありません。

CMake は、実際には protoc コンパイラを呼び出して .pb.h および .pb.cc ファイルを生成しadd_custom_commandません。これを行うために使用します。カスタム コマンドは .pb.h および .pb.cc ファイルを出力として指定し、カスタム コマンドは、これらのファイルに依存する後続のターゲットがビルドされる場合にのみ呼び出されます (つまり、protoc が実行されます)。

したがって、構成時 (CMake の実行時) には、これらのファイルは存在しません。add_libraryこれらをソースとしてorコマンドに追加しようとすると、これが問題になります。これらのファイルは実行時に存在しないが、ビルド時にadd_executable存在することを CMake に通知する必要があります。

これを行う方法は、これらのファイルのGENERATEDプロパティをに設定することです。TRUEマクロはこれPROTOBUF_GENERATE_CPPを自動的に行いますが、変数と同様に、プロパティは親スコープに取り込まれません。そのため、最上位の CMakeLists.txt に、以下も追加する必要があります。

set_source_files_properties(${PROTO_SRC} ${PROTO_HEADER} PROPERTIES
                            GENERATED TRUE)

ご覧のとおりPROTOBUF_GENERATE_CPP、対応するadd_library/add_executableコマンドとは別のディレクトリで使用するのは少し脆弱です。それを避けることができるなら、おそらくそうするべきです。

于 2013-10-13T10:48:33.107 に答える