普罗托布夫的路径

The path in protobuf

本文关键字:路径 罗托布      更新时间:2023-10-16

我不太明白protobuf中的路径。我的文件布局是这样的:

  • 返回页首
    • 一个
      • A.原型
    • C
      • c.proto//import "A/a.proto";

我已经编写了一个基于 protobuf 的 RPC 系统,我需要从 c.proto 生成两种文件(客户端和服务器代码)。客户端代码应放在 B 中,服务器代码仍应放在 C 中。

我无法编写正确的命令。

Top> protoc -I=. --client_out=./B/ C/c.proto将在B/C中生成客户端代码,代码中的#include将具有错误的路径。

Top/C> protoc -I=../ -I=./ --client_out=./ ./c.proto导致protobuf_AddDesc_*错误。

对于每个.proto文件,protoc都会尝试确定文件的"规范名称" - 该名称将其与可能进入系统的任何其他.proto文件区分开来。 事实上,理想情况下,规范名称与世界上所有其他.proto文件不同。 规范名称是从另一个.proto文件导入.proto文件时使用的名称。 它还用于决定将生成的文件输出到何处以及生成哪些#include

对于在命令行上指定的.proto文件,protoc通过尝试确定导入该文件的名称来确定规范名称。 因此,它通过导入路径(用 -I 指定)并查找作为文件名前缀的路径。 然后,它会删除该前缀以确定规范名称。

在您的情况下,如果指定 -I=. C/c.proto ,则规范名称为 C/c.proto 。 如果指定了 -I=C C/c.proto ,则规范名称将仅c.proto

重要的是,任何尝试导入.proto文件的文件都使用编译文件本身时确定的规范名称导入它。 否则,您会收到有关AddDesc的链接器错误。

通常,如果您将某个目录指定为源代码树的"根",并且所有代码都位于该目录的子目录中,并且具有指定项目的唯一名称,则一切正常。 您的"根"目录应该是您传递给-I--client_out的目录。 或者,可以为源文件和生成的文件使用单独的目录,但生成的文件目录应具有镜像源目录的内部结构。 然后,可以指定要--client_out的生成的文件目录,并在运行C++编译器时,在包含路径中指定源目录和生成的文件目录。

如果您有其他设置(例如,.proto文件位于与.pb.h文件不同的规范路径上),那么不幸的是,您将在制作protoc做您想做的事情时遇到一些麻烦。 虽然,鉴于您正在编写自定义代码生成器,您可以为其输出文件的组织方式发明任何您想要的规则,但是偏离标准代码生成器遵循的规则可能会导致许多小陷阱。