Visual Studio中通过Vcpkg让生成器项目重导出gRPC头文件的方案
问题描述
- 生成器项目:包含
.proto文件、生成的.pb.h/.grpc.pb.h文件,通过Vcpkg清单依赖gRPC,可正常构建。 - 业务项目:共10个,引用生成器项目并包含其
.pb.h/.grpc.pb.h文件,但编译时找不到#include<grpcpp/impl/...>这类gRPC内部头文件。 - 需求:不想给每个业务项目单独添加gRPC依赖(避免版本维护复杂度和冗余引用),也不想将生成器转为Vcpkg本地包(需手动打包,变更成本高),希望通过生成器项目重导出gRPC头文件来解决(此前手动构建gRPC时该方案有效)。
补充:生成的.grpc.pb.h示例代码
// Generated by the gRPC C++ plugin. // If you make any local change, they will be lost. // source: myprotofile.proto #ifndef GRPC_myprotofile_2eproto__INCLUDED #define GRPC_myprotofile_2eproto__INCLUDED #include "myprotofile.pb.h" #include <functional> #include <grpcpp/impl/codegen/async_generic_service.h> #include <grpcpp/impl/codegen/async_stream.h> #include <grpcpp/impl/codegen/async_unary_call.h> #include <grpcpp/impl/codegen/client_callback.h> #include <grpcpp/impl/codegen/client_context.h> #include <grpcpp/impl/codegen/completion_queue.h> #include <grpcpp/impl/codegen/message_allocator.h> #include <grpcpp/impl/codegen/method_handler.h> #include <grpcpp/impl/codegen/proto_utils.h> #include <grpcpp/impl/codegen/rpc_method.h> #include <grpcpp/impl/codegen/server_callback.h> #include <grpcpp/impl/codegen/server_callback_handlers.h> #include <grpcpp/impl/codegen/server_context.h> #include <grpcpp/impl/codegen/service_type.h> #include <grpcpp/impl/codegen/status.h> #include <grpcpp/impl/codegen/stub_options.h> #include <grpcpp/impl/codegen/sync_stream.h> namespace proto { } // namespace proto #endif // GRPC_myprotofile_2eproto__INCLUDED
注:正如@HansPassant指出,生成文件引用gRPC内部头文件虽不符合规范,但这是gRPC的固有机制,只能接受。
最优解决方案:让生成器项目重导出gRPC依赖头文件
通过配置生成器项目的包含目录传递性和Vcpkg的依赖导出,让业务项目仅通过引用生成器就能获取gRPC的头文件路径,无需单独依赖gRPC。
步骤1:配置生成器项目的包含目录传递
在Visual Studio中打开生成器项目的属性:
- 进入C/C++ > 常规 > 附加包含目录,确认已通过Vcpkg自动添加了gRPC的头文件路径(通常是
$(VcpkgRoot)\installed\x64-windows\include等)。 - 进入项目属性 > 通用属性 > 框架和引用,确保生成器项目的引用输出属性中,将
附加包含目录设置为传递(即业务项目引用生成器时,自动继承其包含目录)。
步骤2:配置Vcpkg清单的依赖导出
在生成器项目的vcpkg.json中,添加"exports"字段,将gRPC的头文件路径导出给依赖该项目的业务项目:
{ "name": "your-generator-project", "version": "1.0.0", "dependencies": [ "grpc" ], "exports": [ { "include": [ "**/*.h", "$(VcpkgRoot)/installed/$(VcpkgTriplet)/include/grpcpp", "$(VcpkgRoot)/installed/$(VcpkgTriplet)/include/grpc" ] } ] }
注:
$(VcpkgTriplet)会自动替换为你的目标架构(如x64-windows),确保路径正确。
步骤3:验证业务项目的引用设置
在每个业务项目中:
- 确保已正确引用生成器项目(右键项目 > 添加 > 引用 > 勾选生成器项目)。
- 检查业务项目的C/C++ > 常规 > 附加包含目录,确认已自动包含生成器项目的目录以及Vcpkg提供的gRPC头文件路径(无需手动添加)。
- 编译业务项目,验证
#include<grpcpp/impl/...>类头文件是否能被正确找到。
替代方案(如果Vcpkg导出不生效)
如果Vcpkg的exports配置无法满足需求,可手动在生成器项目中添加自定义属性表,将gRPC的包含目录通过PUBLIC模式传递:
- 在生成器项目中创建属性表(
.props文件),添加:
<?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemDefinitionGroup> <ClCompile> <AdditionalIncludeDirectory>$(VcpkgRoot)\installed\$(VcpkgTriplet)\include;%(AdditionalIncludeDirectory)</AdditionalIncludeDirectory> </ClCompile> </ItemDefinitionGroup> </Project>
- 将该属性表设置为公共(右键属性表 > 属性 > 常规 > 作用域 > 公共),确保业务项目引用生成器时自动继承。
内容的提问来源于stack exchange,提问作者Daniël van den Berg
相关产品推荐
相关产品推荐

