Old title: How to compile nanopb/examples/simple/simple.proto file into simple.h and simple.c using nanopb and protobuf
Regarding this library: https://github.com/nanopb/nanopb
My goal is to follow this tutorial: https://jpa.kapsi.fi/nanopb/docs/concepts.html to convert nanopb/examples/simple/simple.proto into a .h and .c source file. I need simple instructions to do this on Ubuntu. I've been attempting it for days and am unable to get it to work.
The commands the tutorial says to do are:
protoc -omessage.pb message.proto
python ../generator/nanopb_generator.py message.pb
I cloned the nanopb repo, cd'ed into nanopb/examples/simple, and then substituting in simple.proto
instead of message.proto
in the commands above, I ran the following:
protoc -osimple.pb simple.proto
It worked fine, producing a simple.pb file.
The 2nd part, however, fails. When running from inside the nanopb/examples/simple folder, I get:
$ 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
Running make
does nothing (says it's already done):
nanopb/generator/proto $ make
make: Nothing to be done for `all'.
Note that I am running the latest version of protoc
, built from the Google protobuf repo from source: https://github.com/protocolbuffers/protobuf.
I have also sought help from nanopb here, but am unable to figure it out, and feel like there's something basic here I'm missing because I just don't know enough: https://github.com/nanopb/nanopb/issues/417. Feels like I'm beating my head into the wall on something that should be simple and has already been done by at least 1448+ people before me (the number of stars on nanopb).
Solved. @PetteriAimonen had given me the missing clue:
the protoc version needs to match with the python library version
Then it occurred to me: originally, when compiling protobuf from scratch, I followed only the C++ installation instructions, as shown here: https://github.com/protocolbuffers/protobuf/tree/master/src. But, what if I follow the Python installation instructions too? https://github.com/protocolbuffers/protobuf/tree/master/python
So, that's what I did.
protobuf
library too (not just the C++ installation):Protobuf Python installation steps I followed:
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
That all worked, so now lets go back and try compiling our simple.proto file again.
cd
into nanopb/examples/simple. We already ran the first command to produce the simple.pb file, so now just run the 2nd command that previously would fail, and it works!
2nd Command only:
nanopb/examples/simple $ python ../../generator/nanopb_generator.py simple.pb
Output:
nanopb/examples/simple $ python ../../generator/nanopb_generator.py simple.pb Writing to simple.pb.h and simple.pb.c
2-commands shown together again for completeness:
protoc -osimple.pb simple.proto
nanopb/examples/simple $ python ../../generator/nanopb_generator.py simple.pb
Beautiful! IT WORKED! simple.pb.h and simple.pb.c are now created!
Now build the "simple" project:
make
And run it:
./simple
And the output is:
nanopb/examples/simple $ ./simple Your lucky number was 13!
Now I can study the project to see how simple.proto was turned into simple.pb.h and simple.pb.c, and I can study simple.c (which contains the main()
function) to see a full usage of these auto-generated .h and .c files, including looking at the following header files which it includes:
#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
Instead of doing the two-line command to build .proto files:
# 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
we can do a one-line command to build .proto files which just uses the protoc
executable plus the protoc-gen-nanopb
plugin:
protoc --plugin=protoc-gen-nanopb=/home/gabriels/GS/dev/Protocol_Buffers/Nanopb/source/nanopb/generator/protoc-gen-nanopb --nanopb_out=. simple.proto
And then, of course, we still need to make and run the main C project:
# From inside folder "/home/gabriels/GS/dev/Protocol_Buffers/Nanopb/source/nanopb/examples/simple":
make && ./simple