如何使用CMake FetchContent生成gRPC对应的C++文件?
解决方案
当使用FetchContent拉取gRPC时,protobuf作为gRPC的依赖会被自动拉取,但CMake不会自动导入protobuf的CMake模块(其中包含protobuf_generate函数),所以需要手动加载这些模块。
修改后的完整CMake配置
cmake_minimum_required(VERSION 3.24) project(my-project) set(CMAKE_CXX_STANDARD 17) # gRPC FetchContent_Declare( gRPC GIT_REPOSITORY https://github.com/grpc/grpc GIT_TAG master ) set(FETCHCONTENT_QUIET OFF) FetchContent_MakeAvailable(gRPC) # 处理protobuf的CMake模块导入 FetchContent_GetProperties(protobuf) if(NOT protobuf_POPULATED) FetchContent_Populate(protobuf) # 将protobuf的cmake目录加入模块路径,让CMake找到protobuf_generate等函数 list(APPEND CMAKE_MODULE_PATH "${protobuf_SOURCE_DIR}/cmake") endif() # 导入protobuf的生成模块 include(protobuf-generate) include(protobuf-module) # 定义proto文件 set(PROTO_FILES protos/myservice.proto) # 创建库目标 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}) # 获取gRPC C++插件路径 get_target_property(grpc_cpp_plugin_location gRPC::grpc_cpp_plugin LOCATION) # 生成普通protobuf C++文件 protobuf_generate( TARGET my-service LANGUAGE cpp OUT_DIR ${CMAKE_CURRENT_BINARY_DIR} ) # 生成gRPC服务文件 protobuf_generate( TARGET my-service LANGUAGE grpc GENERATE_EXTENSIONS .grpc.pb.h .grpc.pb.cc PLUGIN "protoc-gen-grpc=${grpc_cpp_plugin_location}" OUT_DIR ${CMAKE_CURRENT_BINARY_DIR} )
关键修改说明
- 导入protobuf的CMake模块:通过
FetchContent_GetProperties获取自动拉取的protobuf源目录,将其cmake子目录加入CMAKE_MODULE_PATH,确保CMake能找到protobuf-generate.cmake文件。 - 修正
protobuf_generate调用语法:原代码中第一个protobuf_generate的写法错误,改为以TARGET关联目标的标准写法,生成的文件会自动添加到目标的源文件列表中。 - 指定输出目录:通过
OUT_DIR明确生成文件的输出路径为CMAKE_CURRENT_BINARY_DIR,确保头文件和源文件能被正确引用。
这样配置后,无需预先安装protobuf和gRPC,CMake会在构建时自动拉取依赖并生成对应的C++文件。
内容的提问来源于stack exchange,提问作者Connor
相关产品推荐
相关产品推荐

