Я интегрирую Protobuf компиляция файлов в моем проекте CMake-основанный процесс сборки. В настоящее время я использую следующий скрипт CMake:
set (TARGET_NAME ProtobufMessages)
file (GLOB_RECURSE PROTOBUF_FILES "protobuf/*.proto")
set (HEADER_FILES "")
set (SOURCE_FILES "")
foreach (FILE ${PROTOBUF_FILES})
string (REPLACE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} FILE ${FILE})
string (REPLACE ".proto" ".pb.h" HEADER_FILE ${FILE})
string (REPLACE ".proto" ".pb.cc" SOURCE_FILE ${FILE})
list (APPEND HEADER_FILES ${HEADER_FILE})
list (APPEND SOURCE_FILES ${SOURCE_FILE})
endforeach ()
add_library(${TARGET_NAME} STATIC
${HEADER_FILES}
${SOURCE_FILES}
${PROTOBUF_FILES}
)
set_target_properties (${TARGET_NAME} PROPERTIES
FOLDER ${COMMON_PROJECTS_FOLDER_NAME})
set (PROTOBUF_COMPILE_COMMAND
${CONAN_BIN_DIRS_PROTOBUF_RELEASE}/protoc
--cpp_out=${CMAKE_CURRENT_BINARY_DIR}/protobuf
-I${CMAKE_CURRENT_SOURCE_DIR}/protobuf
${PROTOBUF_FILES}
)
add_custom_command(OUTPUT ${HEADER_FILES} ${SOURCE_FILES}
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/protobuf
COMMAND ${PROTOBUF_COMPILE_COMMAND}
DEPENDS ${PROTOBUF_FILES}
COMMENT "Compiling protocol buffer files ...")
source_group (TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES
${PROTOBUF_FILES}
)
set_target_properties (${TARGET_NAME} PROPERTIES
FOLDER ${COMMON_PROJECTS_FOLDER_NAME}
)
target_link_libraries (${TARGET_NAME}
CONAN_PKG::protobuf
)
Он работает нормально, но проблема с этим подходом заключается в том, что когда один proto
файл изменен, все файлы восстановлены.
Простая модификация этого подхода с вызовом add_custom_command
в цикле частично решается проблема:
set (PROTOBUF_COMPILE_COMMAND
${CONAN_BIN_DIRS_PROTOBUF_RELEASE}/protoc
--cpp_out=${CMAKE_CURRENT_BINARY_DIR}/protobuf
-I${CMAKE_CURRENT_SOURCE_DIR}/protobuf
)
foreach (PROTOBUF_FILE ${PROTOBUF_FILES})
string (REPLACE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} TEMP_FILE ${PROTOBUF_FILE})
string (REPLACE ".proto" ".pb.h" HEADER_FILE ${TEMP_FILE})
string (REPLACE ".proto" ".pb.cc" SOURCE_FILE ${TEMP_FILE})
add_custom_command(OUTPUT ${HEADER_FILE} ${SOURCE_FILE}
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/protobuf
COMMAND ${PROTOBUF_COMPILE_COMMAND} ${PROTOBUF_FILE}
DEPENDS ${PROTOBUF_FILE}
COMMENT "Compiling ${PROTOBUF_FILE} ...")
endforeach ()
Но есть еще проблема, потому что protobuf
поддерживает в том числе один protobuf
файл в другой:
import "myproject/base.proto";
В этом случае, когда base.proto
изменены файлы, в том числе и его необходимо перекомпилировать. На самом деле зависимости могут образовывать произвольные DAG. Хотя текущая проблема возникает именно с protobuf
Компиляция файлов это относится ко всем этапам генерации кода, когда некоторые из входных файлов могут зависеть от других.
Можно ли решить эту проблему с CMake?
Задача ещё не решена.
Других решений пока нет …