Есть ли способ указать выходной импорт для сгенерированного кода C ++ при использовании ProtocolBuffers?

Я пытаюсь скомпилировать код C ++ в один двоичный файл, используя файлы .proto. Мой текущий процесс состоит из 2 шагов;

  1. Сгенерируйте код C ++ из 3 файлов .proto с помощью protoc.
  2. Скомпилируйте сгенерированный код и мой собственный код C ++ в один файл .o.

Однако, когда я пытаюсь скомпилировать на шаге 2, сгенерированный код указывает вывод как «com / company / B.pb.h», который не может быть найден компилятором, потому что файл находится в том же каталоге.

Я не хочу вручную изменять сгенерированный импорт кода, поскольку считаю, что это должно быть сделано с помощью протокола protoc, и мы также используем эти прото-файлы для других проектов (включая создание кода Java с использованием тех же файлов .proto, которые работают). Есть ли способ указать импорт сгенерированного кода БЕЗ изменения импорта прототипов?

РЕДАКТИРОВАТЬ: это проблема с протоколом при одновременном создании нескольких файлов? Должен ли я использовать другую команду?

Я знаю, что для java есть варианты, такие как указание пакета или имени класса, но я не могу найти ничего похожего для C ++.

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

Любая помощь очень ценится. Подробности ниже.

Структура каталогов:

.
├── 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: (запустить с.)

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

Фрагмент A.proto:

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 ++:

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

Ошибка:

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

person Tahmm    schedule 28.08.2020    source источник


Ответы (1)


Я так и не нашел способа указать вывод для кода, сгенерированного C ++, но я нашел способ правильно скомпилировать код, не прибегая к дурацким обходным путям, и я думаю, что это подход, который я должен был использовать с самого начала. Вот оно:

Шаг 1, сгенерированный код C ++ остается неизменным, он создается с включенным путем и компилируется в том же каталоге.

Шаг 2 становится файлом make (мы используем Ruby Make / Rake, но концепция та же). Makefile определяет;

  • parser.cc и все сгенерированные файлы .cc в качестве источников.
  • флаги $ LIBS -fPIC -lprotobuf (обратите внимание на отсутствие -Lprotoc здесь, дальше по треку я столкнулся с ошибками. Обычно о неопределенных символах)
  • $ INCFLAGS `-I $ (srcdir) / com / company ''. (Это каталог, в который файл make будет включен в компиляцию)
  • $ VPATH $(srcdir)/com/company. (Это каталог, в котором make-файл будет искать.)

Это привело к созданию файла .o для каждого файла .proto и файла .o для parser.cc. Затем они объединяются в один файл .so, который можно использовать по назначению.

Не стесняйтесь задавать вопросы, если у вас возникнут похожие проблемы.

person Tahmm    schedule 31.08.2020