我在我的基于protobuf的基于CMake的构建过程中整合DAG个文件编译。目前我正在使用以下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
被更改时,包含它的文件也必须重新编译。实际上,依赖关系可以形成任意{{3}}。虽然当前问题是由protobuf
文件编译引起的,但这与所有代码生成步骤相关,而某些输入文件可能依赖于其他一些文件。
使用CMake可以解决这个问题吗?