Невозможно скомпилировать прото c -генерированные (C ++) классы - PullRequest
1 голос
/ 09 января 2020

В настоящее время у меня возникают некоторые проблемы с компиляцией кода C ++, созданного с помощью protobuf. protoc работает правильно и не показывает никаких предупреждений, однако, когда я пытаюсь скомпилировать сгенерированный код C ++, чтобы я мог собрать библиотеку stati c, g ++ показывает мне следующее сообщение:

CanInfo.pb. cc: 107: 5: ошибка: ':: protobuf_BusType_2eproto' не объявлена ​​107 | :: protobuf_BusType_2eproto :: AddDescriptors ();

То, что я смог собрать до сих пор, это некоторая проблема с моим перечислением BusType, которая выглядит примерно так:

syntax = "proto3";

package MyPackage;

enum BusType {

    ProprietaryBus = 0;
    OpenBus = 1;
    UnknownBus = 2;

}

Это перечисление включено в сообщение CanInfo, которое выглядит примерно так:

syntax = "proto3";

package MyPackage;

import "BusType.proto";

message CanInfo {

    int32 interfaceId = 10;
    bool isConnected = 20;
    BusType busType = 30;

}

Как я уже говорил, protoc компилирует эти файлы "правильно" (без ошибок). Версия, используемая для компиляции протосов: proto c 3.6.0 . Это часть кода C ++, сгенерированная protoc:

::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
      descriptor, 248);
::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
    "data_containers/device_data/CanInfo.proto", &protobuf_RegisterTypes);
::protobuf_BusType_2eproto::AddDescriptors();
//           ^ error occurs here

При поиске в коде единственным упоминанием пространства имен protobuf_BusType_2eproto является строка выше. Версия компилятора, используемая для компиляции кода C ++: powerpc-linux-gnu-g++-6 (Ubuntu 6.4.0-17ubuntu1) 6.4.0 20180424. Изменение используемой версии G ++ на версию 8 или 9 не не меняет это поведение.

Я много раз пытался очистить каталог сборки и пытался переключиться на другой протобуф версии (3.4.0), однако это также приводило ко многим ошибкам компилятора, в основном из-за того, что версия protoc была слишком старой.

Сборка каждого файла по отдельности также не меняет поведения.

Что вызывает это поведение? У меня не было проблем с использованием Protobuf до сих пор. Кто-нибудь испытывал это раньше и знает удобный трюк?


EDIT Может ли это быть вызвано тем, как я звоню protoc?

###
# Re-compile protos
###
set(BUILD_PROTOS True)
set(PROTOBUF_COMPILER protoc)
if (BUILD_PROTOS)
    function(BUILD_PROTOS)
        foreach(PROTO ${PROTOS})
            message("Compiling ${PROTO}...")
            execute_process(
                COMMAND ${PROTOBUF_COMPILER} ${PROTO_DIRS} "--cpp_out=${CMAKE_CURRENT_BINARY_DIR}" ${PROTO}
                WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
            )
        endforeach()
    endfunction()

    ###
    # Compile all protos
    ###
    BUILD_PROTOS()
endif()

1 Ответ

1 голос
/ 09 января 2020

Кажется, я исправил проблему. Очевидно, есть ошибка в компиляторе protoc, когда импорт файлов в одном и том же каталоге вызывает такое странное поведение при компиляции отдельных файлов каждый раз. При компиляции нескольких файлов одновременно, protoc выдает ошибку, утверждающую, что значение перечисления уже определено в другом файле, и выдает следующее примечание:

device_data / BusType.proto: 15: 5: Обратите внимание, что значения enum используют правила области видимости C ++, что означает, что значения enum являются родственными элементами своего типа, а не его потомками. Поэтому «ProprietaryBus» должен быть уникальным в «MyPackage», а не только в «BusType».

Гугление усилилось, и я наткнулся на этот старый пост Google Code с 2012 года:

Для компилятора протокола "bar.proto" и "x / bar.proto" два файла прото
, хотя они указаны в одном физическом файле.
Использование 'import' x /bar.proto "'- правильное исправление.

Обходной путь (или исправление) - просто добавить весь путь относительно рабочего каталога protoc.

import "data_containers/device_data/BusType.proto";

В CMake теперь это выглядит следующим образом.

message("Compiling protos...")
execute_process(
  COMMAND ${PROTOBUF_COMPILER}
  ${PROTO_DIRS} "--cpp_out=${CMAKE_CURRENT_BINARY_DIR}" ${PROTOS}
  WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)

Это до сих пор решило мою проблему, я буду редактировать свой ответ, если появится какая-либо новая информация. Может быть, это будет полезно для кого-то еще.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...