首页 > 解决方案 > CMake 目标依赖项来编译 protobuf 文件

问题描述

我想protobufcmake/make.
我定制COMMAND了编译protobufto c++,并将其设置为PRE_BUILD我的静态库的依赖项。

project(mylib)

set(PROTO_PATH "${CMAKE_CURRENT_SOURCE_DIR}/proto_definitions")

file(GLOB PROTO_FILES "${PROTO_PATH}/*.proto")
foreach(PROTO_FILE in ${PROTO_FILES})
    string(REGEX REPLACE "[.]proto$" ".pb.cc" OUTPUT_SOURCE ${PROTO_FILE})
    list(APPEND OUTPUT_SOURCES ${OUTPUT_SOURCE}) 
endforeach()

add_custom_command(TARGET ${PROJECT_NAME}
                   PRE_BUILD
                   COMMAND protoc --cpp_out=${CMAKE_CURRENT_SOURCE_DIR}/compiled_proto ${PROTO_FILES}
                   WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
                   COMMENT "some comment")
add_library(${PROJECT_NAME} STATIC ${OUTPUT_SOURCES})

target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_BINARY_DIR})



运行 cmake 时出现以下错误:
CMake 错误:无法确定目标“mylib”的链接语言

不管这个错误,生成了makefile,但是当我make mylib时,它不会触发任何proto编译

标签: cmakeprotocol-buffers

解决方案


CMake 更原生的方法是添加带有OUTPUT签名的自定义命令来生成.cc文件,然后通常将它们用作库的源。这样,他们 CMake 就会知道它们是什么以及如何生成它们:

project(mylib)

set(PROTO_PATH "${CMAKE_CURRENT_SOURCE_DIR}/proto_definitions")

file(GLOB PROTO_FILES "${PROTO_PATH}/*.proto")
foreach(PROTO_FILE in ${PROTO_FILES})
    string(REGEX REPLACE "[.]proto$" ".pb.cc" OUTPUT_SOURCE ${PROTO_FILE})
    list(APPEND OUTPUT_SOURCES ${OUTPUT_SOURCE}) 
endforeach()

add_custom_command(OUTPUT ${OUTPUT_SOURCES}
                   COMMAND protoc --cpp_out=${CMAKE_CURRENT_SOURCE_DIR}/compiled_proto ${PROTO_FILES}
                   DEPENDS ${PROTO_FILES}
                   WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
                   COMMENT "some comment")
add_library(${PROJECT_NAME} STATIC ${OUTPUT_SOURCES})

target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_BINARY_DIR})

通过这种方式,将有一个命令读取所有.proto文件并生成所有.cc文件——这意味着如果任何.proto文件发生更改,所有.cc文件都将重新生成。我不熟悉 Protobuffers,所以我不知道这是否合理。如果它们是独立的,最好add_custom_command为每个输出文件引入一个。

此外,鉴于您传递给的参数protocc,您可能必须修改路径OUTPUT_SOURCES以正确指向生成的文件。

另请注意,CMake 带有一个定义命令的FindProtobufprotobuf_generate_cpp()模块,因此您可能希望使用它而不是手动编码 Protobuf 支持。


推荐阅读