如果我想在 cmake 中重新创建以下 protoc 命令:
protoc -I ../proto/ --cpp_out=. service.proto
我在 cmake 中使用以下几行:
file(GLOB ProtoFiles "${CMAKE_CURRENT_SOURCE_DIR}/*.proto")
PROTOBUF_GENERATE_CPP(ProtoSources ProtoHeaders ${ProtoFiles})
如果我想重新创建下面的 protoc 命令:
protoc -I ../proto/ --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` service.proto
在上述情况下,我无法确定如何更改cmake文件,请帮忙!
问题是我该如何解决:
--plugin=EXECUTABLE Specifies a plugin executable to use.
Normally, protoc searches the PATH for
plugins, but you may specify additional
executables not in the path using this flag.
Additionally, EXECUTABLE may be of the form
NAME=PATH, in which case the given plugin name
is mapped to the given executable even if
the executable's own name differs.
我一直在阅读PROTOBUF_GENERATE_CPP文档,但没有找到答案!
模块
findProtobuf.cmake
仅为常见的protoc
调用定义函数包装器:PROTOBUF_GENERATE_CPP
- 用于--cpp_out
和PROTOBUF_GENERATE_PYTHON - 用于--py_out
。但是您可以为所需的插件实现自己的函数包装器。下面的代码基于 PROTOBUF_GENERATE_CPP
实现。
find_program(GRPC_CPP_PLUGIN grpc_cpp_plugin) # Get full path to plugin
function(PROTOBUF_GENERATE_GRPC_CPP SRCS HDRS)
if(NOT ARGN)
message(SEND_ERROR "Error: PROTOBUF_GENERATE_GRPC_CPP() called without any proto files")
return()
endif()
if(PROTOBUF_GENERATE_CPP_APPEND_PATH) # This variable is common for all types of output.
# Create an include path for each file specified
foreach(FIL ${ARGN})
get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
get_filename_component(ABS_PATH ${ABS_FIL} PATH)
list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
if(${_contains_already} EQUAL -1)
list(APPEND _protobuf_include_path -I ${ABS_PATH})
endif()
endforeach()
else()
set(_protobuf_include_path -I ${CMAKE_CURRENT_SOURCE_DIR})
endif()
if(DEFINED PROTOBUF_IMPORT_DIRS)
foreach(DIR ${Protobuf_IMPORT_DIRS})
get_filename_component(ABS_PATH ${DIR} ABSOLUTE)
list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
if(${_contains_already} EQUAL -1)
list(APPEND _protobuf_include_path -I ${ABS_PATH})
endif()
endforeach()
endif()
set(${SRCS})
set(${HDRS})
foreach(FIL ${ARGN})
get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
get_filename_component(FIL_WE ${FIL} NAME_WE)
list(APPEND ${SRCS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.grpc.pb.cc")
list(APPEND ${HDRS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.grpc.pb.h")
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.grpc.pb.cc"
"${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.grpc.pb.h"
COMMAND ${Protobuf_PROTOC_EXECUTABLE}
ARGS --grpc_out=${CMAKE_CURRENT_BINARY_DIR}
--plugin=protoc-gen-grpc=${GRPC_CPP_PLUGIN}
${_protobuf_include_path} ${ABS_FIL}
DEPENDS ${ABS_FIL} ${Protobuf_PROTOC_EXECUTABLE}
COMMENT "Running gRPC C++ protocol buffer compiler on ${FIL}"
VERBATIM)
endforeach()
set_source_files_properties(${${SRCS}} ${${HDRS}} PROPERTIES GENERATED TRUE)
set(${SRCS} ${${SRCS}} PARENT_SCOPE)
set(${HDRS} ${${HDRS}} PARENT_SCOPE)
endfunction()
用法与
PROTOBUF_GENERATE_CPP
相同:
file(GLOB ProtoFiles "${CMAKE_CURRENT_SOURCE_DIR}/*.proto")
PROTOBUF_GENERATE_GRPC_CPP(ProtoGRPCSources ProtoGRPCHeaders ${ProtoFiles})
对我来说,这篇博客文章取得了成功,因为它提供了完整的示例(感谢@powerpete)。
我将代码放在这里,以便它可以作为答案,而不仅仅是作为评论:
project(my-service VERSION 1.0 LANGUAGES CXX C)
find_package(protobuf CONFIG REQUIRED)
find_package(gRPC CONFIG REQUIRED)
find_package(Threads)
set(PROTO_FILES
MyService.proto
)
# protobuf source files go into the lib just like any other CPP source file
add_library(my-service ${PROTO_FILES})
target_link_libraries(my-service
PUBLIC
protobuf::libprotobuf
gRPC::grpc
gRPC::grpc++
)
target_include_directories(my-service
PUBLIC
${CMAKE_CURRENT_BINARY_DIR}
)
get_target_property(grpc_cpp_plugin_location gRPC::grpc_cpp_plugin LOCATION)
# compile the message types
protobuf_generate(TARGET my-service LANGUAGE cpp)
# compile the GRPC services
protobuf_generate(
TARGET
my-service
LANGUAGE
grpc
GENERATE_EXTENSIONS
.grpc.pb.h
.grpc.pb.cc
PLUGIN
"protoc-gen-grpc=${grpc_cpp_plugin_location}"
)
从版本 3.12 开始,protobuf_generate 支持 PLUGIN 参数
https://github.com/protocolbuffers/protobuf/blob/v3.12.0/cmake/protobuf-config.cmake.in#L46
所以你可以尝试一些方法:
PROTOBUF_GENERATE_CPP(ProtoSources ProtoHeaders ${ProtoFiles} PLUGIN protoc-gen-grpc=${GRPC_CPP_PLUGIN_PATH})