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

3

我有一个dotnet core 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>

官方文档提到了一种替代方案来自定义目标构建,以便我可以使用protoc

protoc --plugin=protoc-gen-grpc=$(gRPC_PluginFullPath)  -I $(Protobuf_StandardImportsPath) ...

但是上面的命令忽略了服务定义并且没有生成服务器存根代码,正如这里所述,而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 - Jan Tattermusch
或者,您可以在msbuild中设置ProtoRoot="protoc",并确保所有.proto文件都位于该目录下(具有与包名称对应的子目录)。在您的情况下,您将拥有protos/myproto.protoprotos/google/api/annotations.proto(不包括“googleapis”目录,因为“google/api”需要对应于annotations.proto的命名空间),然后一切都应该能够正常构建。 - Jan Tattermusch
1个回答

12

最终弄清楚了。正如Jan Tattermusch所建议的那样,ProtoRoot指定了msbuild Include属性以及proto import关键字将要查找文件的目录,而ProtoRoot对于Include的工作方式与其对于import的工作方式不同。因此,为了自定义proto文件结构如此,ProtoRoot必须包括所有应该的不同路径,这些路径应该是:

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

更新:

对于grpc-dotnet v2.31.0之前的版本,上述方法可以正常工作。对于更新版本,会出现警告,提示ProtoRoot路径不是Include路径的前缀。为了解决这个问题,请改用以下配置:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接