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