使用 MSBuild 构建 gRPC dotnet 核心项目时如何包含自定义目录

How to include custom directory when building gRPC dotnet core project with MSBuild

我有一个 dotnet 核心 gRPC 项目,我正在尝试在我的原型文件中包含路由注释,如下所示:

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.25.0\build\native\include`

更新:

另一种解决方法:

默认包含项目根目录,因此将其用作基本路径并将导入的 proto 文件复制到那里也可以(更好但仍然不理想)。

关于如何通过 MSBuild 包含上述自定义目录的任何想法?

终于想通了。正如 Jan Tattermusch 建议的那样,ProtoRoot 指定 msbuild Include 属性 以及 proto import 关键字将从中查找文件的目录,而 ProtoRoot 适用于 Include 的方式不同于它适用于 import 的方式。因此,为了将原型文件结构定制成这样,ProtoRoot 必须包含所有不同的路径,这些路径应该是:

<Protobuf Include="protos/*.proto" ProtoRoot="./protos; ./protos/googleapis" ... />

更新:

以上适用于 v2.31.0 之前的 grpc-dotnet 版本。对于较新的版本,warnings 会显示 ProtoRoot 路径不是 Include 路径的前缀。要修复它,请改用以下配置:

<Protobuf Include="protos/*.proto" ProtoRoot="protos" AdditionalImportDirs="protos/googleapis" ... />