如何通过CMake以跨平台方式在Windows环境下从.proto文件生成gRPC C++文件?解决跨平台CMake脚本Windows编译报错问题
解决Windows下CMake+gRPC清理阶段的文件名非法字符问题
你的问题核心在于Windows系统对文件名的特殊字符限制——当你把gRPC插件的完整路径(包含=和斜杠)直接写进protobuf_generate的PLUGIN参数时,CMake生成的Ninja脚本会把这个路径嵌入到要跟踪的生成文件名称里,而Windows不允许文件名包含=这类字符,导致清理阶段Ninja尝试删除这些非法命名的文件时失败。
修改方案
我们需要调整protobuf_generate的调用方式,避免把插件路径直接嵌入到生成文件的名称中,同时保持Linux平台的兼容性:
步骤1:移除手动获取插件路径的冗余代码
删掉以下两行,因为find_package(GRPC REQUIRED)已经自动处理了插件的路径定位:
get_target_property(grpc_cpp_plugin_location gRPC::grpc_cpp_plugin LOCATION) message("grpc_cpp_plugin location is: ${grpc_cpp_plugin_location}")
步骤2:修改gRPC代码生成的protobuf_generate调用
把原来的grpc生成行替换成:
protobuf_generate(TARGET CacheSvc APPEND_PATH LANGUAGE grpc GENERATE_EXTENSIONS .grpc.pb.h .grpc.pb.cc)
如果你的环境需要显式指定插件(比如某些特殊环境下),可以只指定插件名称而非完整路径:
protobuf_generate(TARGET CacheSvc APPEND_PATH LANGUAGE grpc GENERATE_EXTENSIONS .grpc.pb.h .grpc.pb.cc PLUGIN "grpc_cpp_plugin")
修改后的完整CMake配置
cmake_minimum_required (VERSION 3.20) # Protocol buffer find_package(Protobuf REQUIRED) find_package(GRPC REQUIRED) include_directories(${Protobuf_INCLUDE_DIRS}) include_directories(${CMAKE_CURRENT_BINARY_DIR}) # Protocol buffer files set(protoFiles ${ProtoDir}/Common/core_types.proto ${ProtoDir}/Cache/data_cache.proto ) # Private files directory set(pf "Source") # Private project files set(privateFiles ${pf}/CacheSvc.h ${pf}/CacheSvc.cpp ${pf}/main.cpp ) # Add source files to this project executable. add_executable (CacheSvc ${privateFiles} ${protoFiles} ) # Libraries to link with target_link_libraries(CacheSvc PRIVATE Common DataCache protobuf::libprotobuf gRPC::grpc gRPC::grpc++ ) # protobuf_generate function definition is available under the link below: # https://github.com/protocolbuffers/protobuf/blob/master/cmake/protobuf-config.cmake.in protobuf_generate(TARGET CacheSvc APPEND_PATH LANGUAGE cpp) protobuf_generate(TARGET CacheSvc APPEND_PATH LANGUAGE grpc GENERATE_EXTENSIONS .grpc.pb.h .grpc.pb.cc) # Installation install(TARGETS CacheSvc)
原理说明
当你通过find_package(GRPC REQUIRED)引入gRPC后,CMake已经知晓grpc_cpp_plugin的位置,protobuf_generate会自动使用正确的插件路径生成gRPC代码,不会把路径信息嵌入到生成的文件名称中。这样Windows系统就能正常识别和清理这些文件,同时Linux平台的编译逻辑也完全不受影响。
内容的提问来源于stack exchange,提问作者Aleksander Stankiewicz
相关产品推荐
相关产品推荐

