Ответ 1
Я думаю, FindProtobuf
на самом деле не предназначена для использования сюда. Из своих документов:
ПРИМЕЧАНИЕ. Макрос
PROTOBUF_GENERATE_CPP
иadd_executable()
илиadd_library()
звонки работают только в одном каталоге.
Вы пытаетесь использовать макрос PROTOBUF_GENERATE_CPP
в подкаталоге, и хотя документы CMake действительно не дают ясности, подкаталог вводит новую область переменных. Это означает, что любые переменные, установленные или измененные в области subdir, не влияют на аналогично названные переменные в родительской области. Следовательно, причина для PROTO_SRC
доступна в вашем прототипе dir, но не в родительском.
Способ передачи переменных в область видимости заключается в использовании 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
или 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
немного хрупко. Если вы можете избежать этого, вы, вероятно, должны.