import "<package name>/<file name>"
using this style yields compile errors for protobuf. Here's example
code
--- A.proto ---
package P;
message A { }
--- B.proto ---
import "P/A.proto";
package P;
message B { optional A a = 1; }
--- compile commands, in folder P ---
$ protoc --cpp_out=. -I../P -I../P/.. ../P/a.proto
$ protoc --cpp_out=. -I../P -I../P/.. ../P/b.proto
$ g++ -I../P -I../P/.. -c b.pb.cc -o b.pb.o
b.pb.cc: In function ‘void P::protobuf_AddDesc_b_2eproto()’:
b.pb.cc:74: error: ‘protobuf_AddDesc_P_2fa_2eproto’ is not a member of
‘P’
why all the dots? it's an automake build using $(srcdir) for the -I's.
--- workaround ---
Remove the <package name> from the import statement.
--- problem ---
The method in question can be seen in a.pb.h as;
a.pb.h: friend void protobuf_AddDesc_a_2eproto();
which lacks the 'P_2f' package specifier that gets folded into the
method name in b.pb.cc.
What's even more fun, is putting message A in foo.proto, and changing
the import in b to;
import "P/foo.proto";
which yields;
foo.pb.h: friend void protobuf_AddDesc_foo_2eproto();
b.pb.cc:74: error: ‘protobuf_AddDesc_P_2ffoo_2eproto’ is not a member
of ‘P’
This all seems to rely on the Java path=package and filename=classname
paradigms, which don't hold for C/CPP.
--
You received this message because you are subscribed to the Google Groups "Protocol Buffers" group.
To post to this group, send email to prot...@googlegroups.com.
To unsubscribe from this group, send email to protobuf+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/protobuf?hl=en.
If you wish to argue that the .proto files or the -I options I passed
to proto are invalid, then protoc should have declared an error.
If you wish to argue that the .proto files and the -I options I passed
to proto are valid, then the c++ code emitted by protoc should have
compiled without error.
If the error was simply an issue of -I options passed to protoc/g++
that would be one thing, but in this case, protoc generated a call to
a function that doesn't even exist in the generated code set. That's
a major bug.
Providing a patch that does what you think it should do instead is
probably a good way to start the discussion and get it fixed.
-h
If you have an issue tracking database, you might want to enter it
there, in case someone else can get to it before I can.
--
$(PROTOC) --cpp_out=$(top_srcdir) -I$(top_srcdir) $(PROTOC_FLAGS) $<
which seems to handle it.
However, there is still one point we're not connecting on, which is
this. It seems that when a.proto compiles, the name for
'protobuf_AddDesc_foo_2eproto' is derived from the canonical name for
a.proto, but when b.proto compiles, the name of that function is
derived not from the canonical name for a.proto, but from the import
statement in b.proto - because protoc assumes the two will be the same
thing.
In a Java world, the assumption that these two things will be the same
holds because the javac enforces it with strict package name and
folder name checking relative to the CLASSPATH. protoc doesn't do
this, and so it shouldn't make the same assumptions. When compiling
b.proto, it should use the canonical name for a.proto to cook the
method name. If you search the -I paths, and find two a.proto files,
then by all means, flag an error and exit.
Peace.
I understand your explanation, and have changed my automake to;
$(PROTOC) --cpp_out=$(top_srcdir) -I$(top_srcdir) $(PROTOC_FLAGS) $<
which seems to handle it.
However, there is still one point we're not connecting on, which is
this. It seems that when a.proto compiles, the name for
'protobuf_AddDesc_foo_2eproto' is derived from the canonical name for
a.proto, but when b.proto compiles, the name of that function is
derived not from the canonical name for a.proto, but from the import
statement in b.proto - because protoc assumes the two will be the same
thing.
In a Java world, the assumption that these two things will be the same
holds because the javac enforces it with strict package name and
folder name checking relative to the CLASSPATH. protoc doesn't do
this, and so it shouldn't make the same assumptions.
When compiling
b.proto, it should use the canonical name for a.proto to cook the
method name. If you search the -I paths, and find two a.proto files,
then by all means, flag an error and exit.