使用FetchContent引入gRPC时找不到google/protobuf/timestamp.proto的解决方法
修复FetchContent引入gRPC时proto文件找不到内置timestamp.proto的问题
错误根源是protoc编译你的grib_manager.proto时,找不到Google Protobuf内置的timestamp.proto文件——该文件属于Protobuf库的一部分,不在你的项目目录中,必须将Protobuf的头文件目录添加到protoc的搜索路径里。
修复步骤:
- 获取Protobuf的头文件目录
在FetchContent_MakeAvailable(grpc)之后,添加代码获取Protobuf的包含目录:
# 获取protobuf内置proto文件所在的头文件目录 get_target_property(PROTOBUF_INCLUDE_DIRS protobuf::libprotobuf INTERFACE_INCLUDE_DIRECTORIES)
- 更新protoc编译参数
修改add_custom_command的参数,把Protobuf的包含目录加入protoc的搜索路径:
add_custom_command( OUTPUT "${gm_proto_srcs}" "${gm_proto_hdrs}" "${gm_grpc_srcs}" "${gm_grpc_hdrs}" COMMAND ${_PROTOBUF_PROTOC} ARGS --grpc_out "${CMAKE_CURRENT_BINARY_DIR}" --cpp_out "${CMAKE_CURRENT_BINARY_DIR}" -I "${gm_proto_path}" -I "${PROTOBUF_INCLUDE_DIRS}" # 新增:让protoc找到内置proto文件 --plugin=protoc-gen-grpc="${_GRPC_CPP_PLUGIN_EXECUTABLE}" "${gm_proto}" DEPENDS "${gm_proto}")
- (可选)规范目标引用
将原代码中的libprotobuf替换为更标准的命名空间目标,提升兼容性:
set(_PROTOBUF_LIBPROTOBUF protobuf::libprotobuf)
修改后的完整CMake代码片段:
cmake_minimum_required(VERSION 3.15) project(example-grpc LANGUAGES CXX) set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") set(CMAKE_CXX_STANDARD 17) message(STATUS "Using gRPC via add_subdirectory (FetchContent).") include(FetchContent) FetchContent_Declare( grpc GIT_REPOSITORY https://github.com/grpc/grpc.git GIT_TAG v1.28.0 ) FetchContent_MakeAvailable(grpc) # 获取protobuf内置proto文件所在的头文件目录 get_target_property(PROTOBUF_INCLUDE_DIRS protobuf::libprotobuf INTERFACE_INCLUDE_DIRECTORIES) # 引用gRPC和Protobuf目标 set(_PROTOBUF_LIBPROTOBUF protobuf::libprotobuf) set(_REFLECTION grpc++_reflection) set(_PROTOBUF_PROTOC $<TARGET_FILE:protoc>) set(_GRPC_GRPCPP grpc++) if(CMAKE_CROSSCOMPILING) find_program(_GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin) else() set(_GRPC_CPP_PLUGIN_EXECUTABLE $<TARGET_FILE:grpc_cpp_plugin>) endif() # Proto文件路径处理 get_filename_component(gm_proto "${CMAKE_CURRENT_SOURCE_DIR}/grib_manager.proto" ABSOLUTE) get_filename_component(gm_proto_path "${gm_proto}" PATH) # 生成代码路径设置 set(gm_proto_srcs "${CMAKE_CURRENT_BINARY_DIR}/gribmanager.pb.cc") set(gm_proto_hdrs "${CMAKE_CURRENT_BINARY_DIR}/gribmanager.pb.h") set(gm_grpc_srcs "${CMAKE_CURRENT_BINARY_DIR}/gribmanager.grpc.pb.cc") set(gm_grpc_hdrs "${CMAKE_CURRENT_BINARY_DIR}/gribmanager.grpc.pb.h") # 自定义命令生成proto代码 add_custom_command( OUTPUT "${gm_proto_srcs}" "${gm_proto_hdrs}" "${gm_grpc_srcs}" "${gm_grpc_hdrs}" COMMAND ${_PROTOBUF_PROTOC} ARGS --grpc_out "${CMAKE_CURRENT_BINARY_DIR}" --cpp_out "${CMAKE_CURRENT_BINARY_DIR}" -I "${gm_proto_path}" -I "${PROTOBUF_INCLUDE_DIRS}" --plugin=protoc-gen-grpc="${_GRPC_CPP_PLUGIN_EXECUTABLE}" "${gm_proto}" DEPENDS "${gm_proto}") # 创建proto库 add_library(gm_grpc_proto ${gm_grpc_srcs} ${gm_grpc_hdrs} ${gm_proto_srcs} ${gm_proto_hdrs}) target_link_libraries(gm_grpc_proto ${_REFLECTION} ${_GRPC_GRPCPP} ${_PROTOBUF_LIBPROTOBUF}) # 包含生成的头文件目录 include_directories("${CMAKE_CURRENT_BINARY_DIR}")
内容的提问来源于stack exchange,提问作者Tom McLean
相关产品推荐
相关产品推荐

