Как скомпилировать файл .proto nanopb в файлы .h и .c с помощью nanopb и protobuf (вопрос о компиляции `protoc`)

Старый заголовок: Как скомпилировать файл nanopb / examples / simple / simple.proto в simple.h и simple.c с помощью nanopb и protobuf

Относительно этой библиотеки: https://github.com/nanopb/nanopb

Моя цель - следовать этому руководству: https://jpa.kapsi.fi/nanopb/docs/concepts.html, чтобы преобразовать nanopb / examples / simple / simple.proto в исходный файл .h и .c. Мне нужны простые инструкции, чтобы сделать это в Ubuntu. Я пытался это сделать несколько дней и не могу заставить его работать.

В учебном пособии говорится о следующих командах:

protoc -omessage.pb message.proto
python ../generator/nanopb_generator.py message.pb

Я клонировал репозиторий nanopb, записал его в nanopb / examples / simple, а затем заменил simple.proto вместо message.proto в приведенных выше командах, я выполнил следующее:

protoc -osimple.pb simple.proto

Он работал нормально, создавая файл simple.pb.

Вторая часть, однако, не удалась. При запуске из папки nanopb / examples / simple я получаю:

$ python ../../generator/nanopb_generator.py simple.pb

         ********************************************************************
         *** Failed to import the protocol definitions for generator.     ***
         *** You have to run 'make' in the nanopb/generator/proto folder. ***
         ********************************************************************

Traceback (most recent call last):
  File "../../generator/nanopb_generator.py", line 39, in <module>
    import proto.nanopb_pb2 as nanopb_pb2
  File "/home/gabriels/GS/dev/Protocol_Buffers/Nanopb/source/nanopb/generator/proto/nanopb_pb2.py", line 11, in <module>
    from google.protobuf import symbol_database as _symbol_database
ImportError: cannot import name symbol_database

Запуск make ничего не делает (говорит, что уже сделано):

nanopb/generator/proto $ make
make: Nothing to be done for `all'.

Обратите внимание, что я использую последнюю версию protoc, созданную из репозитория Google protobuf из источника: https://github.com/protocolbuffers/protobuf.

Я также обратился за помощью к nanopb здесь, но не могу понять это и чувствую, что здесь есть что-то базовое, что мне не хватает, потому что я просто недостаточно знаю: https://github.com/nanopb/nanopb/issues/417. Такое ощущение, что я бью головой о стену о чем-то, что должно быть простым и уже было сделано как минимум 1448+ людьми до меня (количество звезд на nanopb).


person Gabriel Staples    schedule 05.08.2019    source источник


Ответы (1)


Решено. @PetteriAimonen дал мне недостающую подсказку:

версия протокола должна соответствовать версии библиотеки Python

Потом мне пришло в голову: изначально при компиляции protobuf с нуля я следовал только инструкциям по установке C ++, как показано здесь: https://github.com/protocolbuffers/protobuf/tree/master/src. Но что, если я тоже буду следовать инструкциям по установке Python? https://github.com/protocolbuffers/protobuf/tree/master/python

Итак, вот что я сделал.

TL; DR; Выполните установку Python библиотеки protobuf (а не только установку C ++):

Шаги установки Protobuf Python, которые я выполнил:

python -V # See if I have Python 2.7 or newer (I must to continue)
cd protobuf/python # cd into Python source directory
python setup.py build
python setup.py test
(cd .. && make)
(cd .. && sudo make install)
python setup.py build --cpp_implementation
python setup.py test --cpp_implementation  # look to see all tests pass
sudo python setup.py install

Двухэтапная компиляция файлов .proto:

Все это сработало, так что теперь давайте вернемся и снова попробуем скомпилировать наш файл simple.proto.

cd в nanopb / examples / simple. Мы уже выполнили первую команду для создания файла simple.pb, поэтому теперь просто запустите вторую команду, которая раньше не выполнялась, и она работает!

Только 2-я команда:

nanopb/examples/simple $ python ../../generator/nanopb_generator.py simple.pb

Выход:

nanopb/examples/simple $ python ../../generator/nanopb_generator.py simple.pb  
Writing to simple.pb.h and simple.pb.c

Две команды снова показаны вместе для полноты:

protoc -osimple.pb simple.proto
nanopb/examples/simple $ python ../../generator/nanopb_generator.py simple.pb

Красивый! ЭТО СРАБОТАЛО! simple.pb.h и simple.pb.c созданы!

Теперь создадим «простой» проект:

make

И запускаем его:

./simple

И результат:

nanopb/examples/simple $ ./simple  
Your lucky number was 13!

Теперь я могу изучить проект, чтобы увидеть, как simple.proto был преобразован в simple.pb.h и simple.pb.c, и я можно изучить simple.c (который содержит функцию main()), чтобы увидеть полное использование этих автоматически сгенерированных файлов .h и .c, включая просмотр следующих файлов заголовков, которые он включает:

#include <pb_encode.h> # found up 2 levels, in "nanopb" folder
#include <pb_decode.h> # found up 2 levels, in "nanopb" folder
#include "simple.pb.h" # just generated right here in "nanopb/examples/simple" folder

Однострочная команда для создания файлов .proto:

Вместо выполнения двухстрочной команды для создания файлов .proto:

# From inside folder "/home/gabriels/GS/dev/Protocol_Buffers/Nanopb/source/nanopb/examples/simple":
protoc -osimple.pb simple.proto
python ../../generator/nanopb_generator.py simple.pb

мы можем выполнить однострочную команду для создания файлов .proto, в которой просто используется protoc исполняемый файл плюс protoc-gen-nanopb плагин:

protoc --plugin=protoc-gen-nanopb=/home/gabriels/GS/dev/Protocol_Buffers/Nanopb/source/nanopb/generator/protoc-gen-nanopb --nanopb_out=. simple.proto

И затем, конечно, нам все еще нужно создать и запустить основной проект C:

# From inside folder "/home/gabriels/GS/dev/Protocol_Buffers/Nanopb/source/nanopb/examples/simple":
make && ./simple
person Gabriel Staples    schedule 06.08.2019