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

Windows下CMake无法生成Protocol Buffers头文件与源文件

问题:Windows下CMake编译.proto文件未生成.cc/.h文件

在Windows系统使用CMake 3.23.1编译.proto文件,参考相关文档后仍未生成对应的.cc与.h文件。

我的CMakeLists.txt文件

project(test_proto)    
cmake_minimum_required(VERSION 3.23)

set(Protobuf_DIR "C:/grpc/debug/cmake")
set(gRPC_DIR "C:/grpc/debug/lib/cmake/grpc")
set(ZLIB_ROOT "C:/zlib/debug")
set(c-ares_DIR "C:/grpc/debug/lib/cmake/c-ares")

find_package(Protobuf CONFIG REQUIRED)
find_package(gRPC CONFIG REQUIRED)

set(PROTO_FILES ${CMAKE_CURRENT_SOURCE_DIR}/proto/server.proto)
add_library(test_proto ${PROTO_FILES})

target_link_libraries(test_proto
   PUBLIC protobuf::libprotobuf
   PUBLIC gRPC::grpc
   PUBLIC gRPC::grpc++
)

set(PROTO_BINARY_DIR  "${CMAKE_CURRENT_SOURCE_DIR}/tmp")
set(PROTO_IMPORT_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/proto")

get_target_property(grpc_cpp_plugin_location gRPC::grpc_cpp_plugin LOCATION)
message(STATUS  " The value of grpc cpp location is: ${grpc_cpp_plugin_location}")

protobuf_generate(
    TARGET test_proto
    LANGUAGE cpp
    OUT_VAR PROTO_GENERATED_FILES
    IMPORT_DIRS ${PROTO_IMPORT_DIRS}
    PROTOC_OUT_DIR "${PROTO_BINARY_DIR}")

protobuf_generate(
    TARGET test_proto
    OUT_VAR PROTO_GENERATED_FILES
    LANGUAGE grpc
    GENERATE_EXTENSIONS .grpc.pb.h .grpc.pb.cc
    PLUGIN "protoc-gen-grpc=${grpc_cpp_plugin_location}"
    IMPORT_DIRS ${PROTO_IMPORT_DIRS}
    PROTOC_OUT_DIR "${PROTO_BINARY_DIR}")

message(STATUS " The generated files are located in: ${PROTO_GENERATED_FILES}")

运行命令

cmake.exe -D CMAKE_BUILD_TYPE=Debug -G "Visual Studio 16 2019" -S D:\cmake-test -B D:\cmake-test

输出信息

-- Selecting Windows SDK version 10.0.19041.0 to target Windows 10.0.19042.
-- The C compiler identification is MSVC 19.29.30137.0
-- The CXX compiler identification is MSVC 19.29.30137.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: c:/VS/MVS16117/VC/Tools/MSVC/14.29.30133/bin/Hostx64/x64/cl.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: c:/VS/MVS16117/VC/Tools/MSVC/14.29.30133/bin/Hostx64/x64/cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found ZLIB: C:/zlib/debug/lib/zlibd.lib (found version "1.2.11")
-- Found OpenSSL: optimized;C:/Program Files/OpenSSL-Win64/lib/VC/libcrypto64MD.lib;debug;C:/Program Files/OpenSSL-Win64/lib/VC/libcrypto64MDd.lib (found version "3.0.3")
--  The value of grpc cpp location is: C:/grpc/debug/bin/grpc_cpp_plugin.exe
--  The generated files are located in: D:/cmake-test/tmp/proto/server.grpc.pb.h;D:/cmake-test/tmp/proto/server.grpc.pb.cc;D:/cmake-test/tmp/proto/serverPLUGIN;D:/cmake-test/tmp/proto/serverprotoc-gen-grpc=C:/data/tools/grpc/v1.15.1-2/win64/release/bin/grpc_cpp_plugin.exe
-- Configuring done
-- Generating done
-- Build files have been written to: D:/cmake-test

过程无报错,但对应的.h和.cc文件未生成,以下是解决思路:


解决思路

1. 执行Build命令而非仅Configure

protobuf_generate是在构建阶段执行的,不是配置阶段。你目前只运行了CMake的配置命令,生成了VS工程文件,但没有触发实际的代码生成动作。需要接着执行build命令:

cmake --build D:\cmake-test --config Debug

2. 修复grpc插件参数错误

从输出的生成文件列表可以看到异常条目:serverPLUGIN和serverprotoc-gen-grpc=...,这是因为protobuf_generate的PLUGIN参数格式错误。当使用LANGUAGE grpc时,不需要手动指定protoc-gen-grpc=前缀,且你已经通过find_package(gRPC)找到了插件,CMake会自动关联正确的grpc_cpp_plugin。

修改第二个protobuf_generate调用:

protobuf_generate(
    TARGET test_proto
    OUT_VAR PROTO_GENERATED_GRPC_FILES  # 单独用变量,避免覆盖
    LANGUAGE grpc
    GENERATE_EXTENSIONS .grpc.pb.h .grpc.pb.cc
    IMPORT_DIRS ${PROTO_IMPORT_DIRS}
    PROTOC_OUT_DIR "${PROTO_BINARY_DIR}")

3. 避免变量覆盖

两次protobuf_generate都使用了同一个OUT_VAR PROTO_GENERATED_FILES,会导致第一次生成的普通proto文件路径被覆盖。建议分开使用变量,比如第一次用PROTO_GENERATED_CPP_FILES,第二次用PROTO_GENERATED_GRPC_FILES,方便后续调试和追踪。

4. 显式关联生成文件到目标(可选)

虽然TARGET参数会自动关联生成文件到库,但如果仍有问题,可以显式添加生成的文件到目标源文件中:

# 在两次protobuf_generate调用后添加
target_sources(test_proto PRIVATE ${PROTO_GENERATED_CPP_FILES} ${PROTO_GENERATED_GRPC_FILES})

5. 检查路径合法性

确保PROTO_BINARY_DIR对应的D:/cmake-test/tmp目录存在,CMake默认会自动创建,但如果有权限问题可能导致创建失败,可以手动提前创建该目录。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 04:51:12