使用 MSBuild 构建 gRPC dotnet 核心项目时如何包含自定义目录
Posted
技术标签:
【中文标题】使用 MSBuild 构建 gRPC dotnet 核心项目时如何包含自定义目录【英文标题】:How to include custom directory when building gRPC dotnet core project with MSBuild 【发布时间】:2020-04-01 12:44:08 【问题描述】:我有一个 dotnet 核心 gRPC 项目,我正在尝试在我的 proto 文件中包含路由注释,如下所示:
import "google/api/annotations.proto";
文件结构是这样的(原因是我将googleapis
存储库作为git子模块导入):
protos/
myproto.proto
googleapis/
google/
api/
annotations.proto
...
在 go 项目中可以通过以下方式完成:
protoc -I . -I ./googleapis --go_out=plugins=grpc:. *.proto
其中-I ./googleapis
为编译器提供了可以找到annotations.proto
文件及其依赖项的目录。
但是,当我在使用如下配置的 dotnet grpc 项目中使用 MSBuild 时,我无法弄清楚如何包含自定义目录。
<ItemGroup>
<Protobuf Include="protos/*.proto" GrpcServices="Server" />
</ItemGroup>
Official doc 提到了自定义目标构建的替代方法,以便我可以使用protoc
:
protoc --plugin=protoc-gen-grpc=$(gRPC_PluginFullPath) -I $(Protobuf_StandardImportsPath) ...
但上面的命令会忽略服务定义,并且不会像here 中提到的那样生成服务器存根代码,而 MSBuild 会生成。
我找到但不理想的解决方法:
我意识到Grpc.Tools
dotnet 包分发了一些常用的 proto 文件,所以我在那里复制了annotations.proto
及其依赖项(在 macOS 中)并且它起作用了:
`~\.nuget\packages\grpc.tools\2.25.0\build\native\include`
更新:
另一种解决方法:
默认包含项目根目录,因此将其用作基本路径并复制导入的 proto 文件也可以(更好但仍然不理想)。
任何想法如何通过 MSBuild 包含上述自定义目录?
【问题讨论】:
您可能在自定义命令中缺少一些特定于 grpc 的选项:例如--grpc_out=OUT_DIR
或者,您可以在 msbuild 中设置 ProtoRoot="protoc" 并确保所有 .proto 文件都在该目录下(子目录对应于包名称)。在您的情况下,您将拥有 protos/myproto.proto
和 protos/google/api/annotations.proto
(没有“googleapis”目录,因为“google/api”需要对应于 annotations.proto 的命名空间)并且一切都应该构建得很好。
【参考方案1】:
终于想通了。正如Jan Tattermusch 所建议的那样,ProtoRoot
指定了 msbuild Include
属性以及 proto import
关键字将从中查找文件的目录,而 ProtoRoot
用于 Include
的方式与它的方式不同适用于import
。因此,为了将 proto 文件结构自定义为这样,ProtoRoot
必须包含所有不同的路径,这些路径应该是:
<Protobuf Include="protos/*.proto" ProtoRoot="./protos; ./protos/googleapis" ... />
更新:
以上方法适用于 v2.31.0 之前的 grpc-dotnet 版本。对于较新的版本,warnings 将显示为 ProtoRoot
path is not a prefix of Include
path。要修复它,请改用以下配置:
<Protobuf Include="protos/*.proto" ProtoRoot="protos" AdditionalImportDirs="protos/googleapis" ... />
【讨论】:
以上是关于使用 MSBuild 构建 gRPC dotnet 核心项目时如何包含自定义目录的主要内容,如果未能解决你的问题,请参考以下文章
Visual Studio 在构建、重建和清理解决方案时使用啥 dotnet core cli 命令(或 msbuild 命令)?
msbuild、dotnet sdks、azure、kudu等使用的环境变量列表
dotnet 通过引用 msbuild 程序集实现自己定制编译器