jack2 codebase
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

96 lines
2.3KB

  1. #!/usr/bin/env python
  2. # encoding: utf-8
  3. # Philipp Bender, 2012
  4. # Matt Clarkson, 2012
  5. import re
  6. from waflib.Task import Task
  7. from waflib.TaskGen import extension
  8. """
  9. A simple tool to integrate protocol buffers into your build system.
  10. Example::
  11. def configure(conf):
  12. conf.load('compiler_cxx cxx protoc')
  13. def build(bld):
  14. bld(
  15. features = 'cxx cxxprogram'
  16. source = 'main.cpp file1.proto proto/file2.proto',
  17. include = '. proto',
  18. target = 'executable')
  19. Notes when using this tool:
  20. - protoc command line parsing is tricky.
  21. The generated files can be put in subfolders which depend on
  22. the order of the include paths.
  23. Try to be simple when creating task generators
  24. containing protoc stuff.
  25. """
  26. class protoc(Task):
  27. # protoc expects the input proto file to be an absolute path.
  28. run_str = '${PROTOC} ${PROTOC_FLAGS} ${PROTOC_ST:INCPATHS} ${SRC[0].abspath()}'
  29. color = 'BLUE'
  30. ext_out = ['.h', 'pb.cc']
  31. def scan(self):
  32. """
  33. Scan .proto dependencies
  34. """
  35. node = self.inputs[0]
  36. nodes = []
  37. names = []
  38. seen = []
  39. if not node: return (nodes, names)
  40. search_paths = [self.generator.path.find_node(x) for x in self.generator.includes]
  41. def parse_node(node):
  42. if node in seen:
  43. return
  44. seen.append(node)
  45. code = node.read().splitlines()
  46. for line in code:
  47. m = re.search(r'^import\s+"(.*)";.*(//)?.*', line)
  48. if m:
  49. dep = m.groups()[0]
  50. for incpath in search_paths:
  51. found = incpath.find_resource(dep)
  52. if found:
  53. nodes.append(found)
  54. parse_node(found)
  55. else:
  56. names.append(dep)
  57. parse_node(node)
  58. return (nodes, names)
  59. @extension('.proto')
  60. def process_protoc(self, node):
  61. cpp_node = node.change_ext('.pb.cc')
  62. hpp_node = node.change_ext('.pb.h')
  63. self.create_task('protoc', node, [cpp_node, hpp_node])
  64. self.source.append(cpp_node)
  65. if 'cxx' in self.features and not self.env.PROTOC_FLAGS:
  66. #self.env.PROTOC_FLAGS = '--cpp_out=%s' % node.parent.get_bld().abspath() # <- this does not work
  67. self.env.PROTOC_FLAGS = '--cpp_out=.'
  68. use = getattr(self, 'use', '')
  69. if not 'PROTOBUF' in use:
  70. self.use = self.to_list(use) + ['PROTOBUF']
  71. def configure(conf):
  72. conf.check_cfg(package="protobuf", uselib_store="PROTOBUF", args=['--cflags', '--libs'])
  73. conf.find_program('protoc', var='PROTOC')
  74. conf.env.PROTOC_ST = '-I%s'