6

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

  • 最佳
    • 一个
      • a.proto
    • C
      • c.proto //import "A/a.proto";

我已经编写了一个基于 protobuf 的 RPC 系统,我需要从c.proto. 客户端代码应该放在 B 中,而服务器代码仍然放在 C 中。

我无法编写正确的命令。

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

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

4

1 回答 1

18

对于每个.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按照自己的意愿行事。虽然,鉴于您正在编写自定义代码生成器,您可以为其输出文件的组织方式发明任何您想要的规则,但是偏离标准代码生成器遵循的规则可能会导致许多小陷阱。

于 2013-09-12T00:07:58.470 回答