Hello,
I'm new to nanopb, so I'm not sure if i'm doing something wrong here, or if this is just an issue on Windows systems.
When i try to run nanopb_generator.exe via CLI, I get the following error:
C:\nanopb\generator\nanopb_generator.py -D . -I ../proto ../proto/device.proto
C:\Users\netfi\AppData\Local\Temp\tmpvkpnrowb.pb: Permission denied
Traceback (most recent call last):
File "C:\nanopb\generator\nanopb_generator.py", line 2032, in <module>
main_cli()
File "C:\nanopb\generator\nanopb_generator.py", line 1912, in main_cli
invoke_protoc(["protoc"] + include_path + ['-o' + tmp.name, filename])
File "C:\nanopb\generator\proto\_utils.py", line 39, in invoke_protoc
return subprocess.check_call(argv)
File "C:\Python38\lib\subprocess.py", line 364, in check_call
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['protoc', '-I../proto', '-oC:\\Users\\netfi\\AppData\\Local\\Temp\\tmpvkpnrowb.pb', '../proto/device.proto']' returned non-zero exit status 1.
this happens regardless the .proto file and the build directory. The same happens when invoking the nanopb_generator python script instead of the executable.
The issue comes from this code:
# Load .pb files into memory and compile any .proto files.
fdescs = {}
include_path = ['-I%s' % p for p in options.options_path]
for filename in filenames:
if filename.endswith(".proto"):
with tempfile.NamedTemporaryFile(suffix = ".pb") as tmp:
invoke_protoc(["protoc"] + include_path + ['-o' + tmp.name, filename])
data = tmp.read()
else:
data = open(filename, 'rb').read()
# Load .pb files into memory and compile any .proto files.
fdescs = {}
include_path = ['-I%s' % p for p in options.options_path]
for filename in filenames:
if filename.endswith(".proto"):
with tempfile.NamedTemporaryFile(suffix = ".pb", delete = False) as tmp:
invoke_protoc(["protoc"] + include_path + ['-o' + tmp.name, filename])
data = tmp.read()
try:
tmp.close()
os.unlink(tmp.name)
except:
pass
else:
data = open(filename, 'rb').read()
I haven't tested it on non-windows platforms, but I guess it should work fine.
Another issue I found is that the generator fails if the output directory does not exist.
For instance, if you have the following tree:
build/
proto/
proto/file1.proto
proto/protobuf/any.proto
Now running the following command from inside the build directory
python <path_to_nanopb_gen>\nanopb_generator.py -D . -I ../proto ../proto/protobuf/any.proto
results in
Writing to .\protobuf/any.pb.h and .\protobuf/any.pb.c
Traceback (most recent call last):
File "nanopb\generator\nanopb_generator.py", line 2040, in <module>
main_cli()
File "nanopb\generator\nanopb_generator.py", line 1951, in main_cli
with open(path, 'w') as f:
FileNotFoundError: [Errno 2] No such file or directory: '.\\protobuf/any.pb.h'
Passing -I ../proto/protobuf fixes the issue but generates any.pb.h and any.pb.c files directly inside the build directory, instead of build/protobuf.
A simple fix was to modify the nanopb_generator.py script from this:
for path, data in to_write:
with open(path, 'w') as f:
f.write(data)
into this:
for path, data in to_write:
os.makedirs(os.path.dirname(path), exist_ok=True)
with open(path, 'w') as f:
f.write(data)
Let me know if these fixes are correct.