I don't quite understand the path in protobuf. My file layout like this:
import "A/a.proto";
I have written an RPC system based on protobuf and I need generate two kinds of files(client and server code) from c.proto
. Client code should be placed in B and Server code still in C.
I can't write a correct command.
Top> protoc -I=. --client_out=./B/ C/c.proto
will generate client code in B/C
and the #include
in code will have a wrong path.
Top/C> protoc -I=../ -I=./ --client_out=./ ./c.proto
lead a protobuf_AddDesc_*
error.
For every .proto
file, protoc
tries to determine the file's "canonical name" -- a name which distinguishes it from any other .proto
file that may ever find its way into your system. In fact, ideally, the canonical name is different from every other .proto
file in the world. The canonical name is the name you use when you import the .proto
file from another .proto
file. It is also used to decide where to output the generated files and what #include
s to generate.
For .proto
files specified on the command line, protoc
determines the canonical name by trying to figure out what name you would use to import that file. So, it goes through the import paths (specified with -I
) and looks for one that is a prefix of the file name. It then removes that prefix to determine the canonical name.
In your case, if you specify -I=. C/c.proto
, then the canonical name is C/c.proto
. If you specified -I=C C/c.proto
, the canonical name would then simply be c.proto
.
It is important that any file which attempts to import your .proto
file imports it using exactly the canonical name determined when the file itself was compiled. Otherwise, you get the linker error regarding AddDesc
.
In general, everything works well if you designate some directory to be the "root" of your source tree, and all of your code lives in a subdirectory of that with a unique name designating your project. Your "root" directory should be the directory you pass to both -I
and --client_out
. Alternatively, you can have separate directories for source files vs. generated files, but the generated files directory should have an internal structure that mirrors your source directory. You can then specify the generated files directory to --client_out
, and when you run the C++ compiler, specify both the source and generated files directories in the include path.
If you have some other setup -- e.g. one where the .proto
files live at a different canonical path from the .pb.h
files -- then unfortunately you will have some trouble making protoc
do what you want. Though, given that you are writing a custom code generator, you could invent whatever rules you want for the way its output files are organized, but straying from the rules the standard code generator follows might lead to lots of little pitfalls.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With