我不太了解protobuf中的路径。我的文件布局如下:
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_*
错误。
答案 0 :(得分:7)
对于每个.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
执行您想要的操作时,您会遇到一些麻烦。虽然,鉴于您正在编写自定义代码生成器,您可以发明您想要的输出文件组织方式,但是偏离标准代码生成器遵循的规则可能会导致很多小陷阱。