generate_protobuf.py 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. import os
  2. import sys
  3. if __name__ == '__main__':
  4. if 'PIPENV_ACTIVE' not in os.environ:
  5. sys.exit(f'This script should be run in a Pipenv.\n\nRun it as:\npipenv run python {os.path.basename(__file__)}')
  6. from pathlib import Path
  7. import shutil
  8. import subprocess
  9. def run():
  10. SCRIPT_PATH = Path(__file__).absolute().parent
  11. REPO_ROOT = SCRIPT_PATH.parent
  12. proto_path = REPO_ROOT / 'proto'
  13. nanopb_path = REPO_ROOT / 'thirdparty' / 'nanopb'
  14. # Make sure nanopb submodule is available
  15. if not os.path.isdir(nanopb_path):
  16. print(f'Nanopb checkout not found! Make sure you have inited/updated the submodule located at {nanopb_path}', file=sys.stderr)
  17. exit(1)
  18. nanopb_generator_path = nanopb_path / 'generator' / 'nanopb_generator.py'
  19. c_generated_output_path = REPO_ROOT / 'firmware' / 'src' / 'proto_gen'
  20. proto_files = [f for f in os.listdir(proto_path) if f.endswith('.proto')]
  21. assert len(proto_files) > 0, 'No proto files found!'
  22. # Generate C files via nanopb
  23. subprocess.check_call(['python3', nanopb_generator_path, '-D', c_generated_output_path] + proto_files, cwd=proto_path)
  24. # Use nanopb's packaged protoc to generate python bindings
  25. protoc_path = nanopb_path / 'generator' / 'protoc'
  26. python_generated_output_path = REPO_ROOT / 'software' / 'python' / 'proto_gen'
  27. python_generated_output_path.mkdir(parents=True, exist_ok=True)
  28. subprocess.check_call([protoc_path, '--version'])
  29. subprocess.check_call([
  30. protoc_path,
  31. '--python_out',
  32. python_generated_output_path,
  33. ] + proto_files, cwd=proto_path)
  34. # Copy nanopb's compiled options proto
  35. shutil.copy2(nanopb_path / 'generator' / 'proto' / 'nanopb_pb2.py', python_generated_output_path)
  36. if __name__ == '__main__':
  37. run()