2

I'm trying to compile C++ code into a single binary using .proto files. My current process has 2 steps;

  1. Generate C++ code from 3 .proto files using protoc.
  2. Compile the generated code and my own C++ code into a single .o file.

However, when I try to compile in step 2, the generated code specified outputs as 'com/company/B.pb.h', which fails to be found by the compiler, because the file is in the same directory.

I don't want to manually change the generated code imports as I feel that should be done by protoc, and we also use these proto files for other projects (including generating java code using the same .proto files, which works). Is there a way to specify the generated code's imports WITHOUT changing the proto imports?

EDIT: Is this an issue with protoc when generating multiple files at once? Should I be using a different command?

I know there are options for java like specifying the package or classname, but I can't find anything similar for C++.

option java_multiple_files = true;
option java_package = "com.company.B";
option java_outer_classname = "B";

Any help is much appreciated. More details below.

Directory structure:

.
├── com
│   └── company # generated code
│       ├── A.pb.cc
│       ├── A.pb.h
│       ├── B.pb.cc
│       ├── B.pb.h
│       ├── C.pb.cc
│       └── C.pb.h
├── Parser.cc
├── Parser.h
└── proto
    └── com
        └── company
            ├── A.proto
            ├── B.proto
            └── C.proto

Protoc command: (run from .)

protoc --cpp_out=. --proto_path=proto/ com/company/A.proto com/company/B.proto com/company/C.proto

A.proto snippet:

syntax = "proto3";
option optimize_for = SPEED;

package com.company;

import "com/company/B.proto"; # specified as full path re Google's documentation

...

Parser.cc:

#include "parser.h"
...

Parser.h:

#include "com/company/A.pb.h"
#include "com/company/B.pb.h"
#include "com/company/C.pb.h"
...

G++ command:

g++ -fPIC -Lprotoc -lprotobuf parser.cc -o parser.so

The Error:

fatal error: com/company/B.pb.h: No such file or directory
 #include "com/company/B.pb.h"
          ^~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.

1 Answer 1

0

I never found a way to specify the output for C++ generated code, but I found a way to compile the code correctly without doing janky workarounds, and I think this is the approach I should have taken at the start. Here goes:

Step 1, the generated C++ code stays the same, and it is generated with path includes, and are compiled in the same directory.

Step 2 becomes a make file (we are using Ruby Make/Rake but the concept is the same) The makefile specifies;

  • the parser.cc and all the generated .cc files as the sources.
  • the $LIBS flags -fPIC -lprotobuf (Note the lack of -Lprotoc here, I ran into errors further along the track. Usually about undefined symbols)
  • the $INCFLAGS ` -I$(srcdir)/com/company ```. (This is a directory for the make file to include in compilation)
  • the $VPATH $(srcdir)/com/company. (This is a directory for the make file to search.)

This resulted in a .o file being generated for each .proto file, and a .o file for the parser.cc. Then they are combined into a single .so file which can be used as we intended.

Feel free to ask questions if you run into similar issues.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.