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