You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用FetchContent安装Protobuf时,如何解决protobuf_generate未识别问题?

问题描述

使用gRPC编写客户端/服务端程序时,通过FetchContent安装Protobuf后,执行CMake报错:Unknown CMake command "protobuf_generate"。但预先本地安装Protobuf时,protobuf_generate命令可正常使用。

代码示例:

cmake_minimum_required(VERSION 3.16)
project(ProtoObjects)

include(FetchContent)
set(FETCHCONTENT_QUIET OFF)
FetchContent_Declare(
  gRPC
  GIT_REPOSITORY https://github.com/grpc/grpc
  GIT_TAG        v1.49.2
  )
FetchContent_Declare(
    Protobuf
    GIT_REPOSITORY https://github.com/protocolbuffers/protobuf
    GIT_TAG        v21.12 
    SOURCE_SUBDIR  cmake
)
FetchContent_MakeAvailable(gRPC Protobuf)

add_library(
    proto-objects
        PUBLIC
            grpc++
)

target_include_directories(proto-objects PUBLIC "$<BUILD_INTERFACE:${PROTO_GENERATED_DIR}>")

protobuf_generate(
    TARGET proto-objects
    IMPORT_DIRS ${PROTO_IMPORT_DIRS}
    PROTOC_OUT_DIR ${PROTO_GENERATED_DIR}
)

protobuf_generate(
    TARGET proto-objects
    LANGUAGE grpc
    GENERATE_EXTENSIONS .grpc.pb.h .grpc.pb.cc
    PLUGIN "protoc-gen-grpc=$<TARGET_FILE:gRPC::grpc_cpp_plugin>"
    IMPORT_DIRS ${PROTO_IMPORT_DIRS}
    PROTOC_OUT_DIR "${PROTO_GENERATED_DIR}"
)

错误信息:

Unknown CMake command "protobuf_generate".
解决方法

问题根源是:用FetchContent拉取的Protobuf,它的CMake模块不会自动加载到当前项目中,得手动引入对应的配置文件才能用protobuf_generate这类命令。

按以下步骤修改代码:

  1. 手动引入Protobuf的CMake模块
    在FetchContent_MakeAvailable(gRPC Protobuf)这行之后,添加两行引入模块的代码:
include(${Protobuf_SOURCE_DIR}/cmake/protobuf-generate.cmake)
include(${Protobuf_SOURCE_DIR}/cmake/protobuf-module.cmake)

这两个文件定义了protobuf_generate命令和相关的Protobuf CMake逻辑。

  1. 显式关联Protobuf目标
    FetchContent拉取的Protobuf会生成官方的CMake目标,把它们加到你的库依赖里,避免依赖缺失:
    修改add_library部分,补充Protobuf的目标:
add_library(
    proto-objects
        PUBLIC
            grpc++
            Protobuf::libprotobuf
            Protobuf::protoc
)
  1. 确认路径正确
    你代码里的SOURCE_SUBDIR cmake是对的,Protobuf v21.12的CMake配置文件确实在cmake子目录下,后续换版本的话记得核对这个路径。

修改后的完整代码示例:

cmake_minimum_required(VERSION 3.16)
project(ProtoObjects)

include(FetchContent)
set(FETCHCONTENT_QUIET OFF)
FetchContent_Declare(
  gRPC
  GIT_REPOSITORY https://github.com/grpc/grpc
  GIT_TAG        v1.49.2
  )
FetchContent_Declare(
    Protobuf
    GIT_REPOSITORY https://github.com/protocolbuffers/protobuf
    GIT_TAG        v21.12 
    SOURCE_SUBDIR  cmake
)
FetchContent_MakeAvailable(gRPC Protobuf)

# 引入Protobuf的CMake模块
include(${Protobuf_SOURCE_DIR}/cmake/protobuf-generate.cmake)
include(${Protobuf_SOURCE_DIR}/cmake/protobuf-module.cmake)

add_library(
    proto-objects
        PUBLIC
            grpc++
            Protobuf::libprotobuf
            Protobuf::protoc
)

target_include_directories(proto-objects PUBLIC "$<BUILD_INTERFACE:${PROTO_GENERATED_DIR}>")

protobuf_generate(
    TARGET proto-objects
    IMPORT_DIRS ${PROTO_IMPORT_DIRS}
    PROTOC_OUT_DIR ${PROTO_GENERATED_DIR}
)

protobuf_generate(
    TARGET proto-objects
    LANGUAGE grpc
    GENERATE_EXTENSIONS .grpc.pb.h .grpc.pb.cc
    PLUGIN "protoc-gen-grpc=$<TARGET_FILE:gRPC::grpc_cpp_plugin>"
    IMPORT_DIRS ${PROTO_IMPORT_DIRS}
    PROTOC_OUT_DIR "${PROTO_GENERATED_DIR}"
)

内容的提问来源于stack exchange,提问作者Tom McLean

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 11:50:32