blob: c675e093c5d27e275990aaf80cf3f4afdc3ca637 [file] [log] [blame]
Peter Collingbourned5395fb2012-01-08 22:09:58 +00001import ninja_syntax
2import os
3
4# Simple meta-build system.
5
6class Make(object):
7 def __init__(self):
8 self.output = open(self.output_filename(), 'w')
9 self.rules = {}
10 self.rule_text = ''
11 self.all_targets = []
Peter Collingbournebae68332012-06-01 17:29:59 +000012 self.default_targets = []
Peter Collingbourned5395fb2012-01-08 22:09:58 +000013 self.clean_files = []
14 self.distclean_files = []
15 self.output.write("""all::
16
17ifndef VERBOSE
18 Verb = @
19endif
20
21""")
22
23 def output_filename(self):
24 return 'Makefile'
25
26 def rule(self, name, command, description=None, depfile=None,
27 generator=False):
28 self.rules[name] = {'command': command, 'description': description,
29 'depfile': depfile, 'generator': generator}
30
31 def build(self, output, rule, inputs=[], implicit=[], order_only=[]):
32 inputs = self._as_list(inputs)
33 implicit = self._as_list(implicit)
34 order_only = self._as_list(order_only)
35
36 output_dir = os.path.dirname(output)
37 if output_dir != '' and not os.path.isdir(output_dir):
38 os.makedirs(output_dir)
39
40 dollar_in = ' '.join(inputs)
41 subst = lambda text: text.replace('$in', dollar_in).replace('$out', output)
42
43 deps = ' '.join(inputs + implicit)
44 if order_only:
45 deps += ' | '
46 deps += ' '.join(order_only)
47 self.output.write('%s: %s\n' % (output, deps))
48
49 r = self.rules[rule]
50 command = subst(r['command'])
51 if r['description']:
52 desc = subst(r['description'])
53 self.output.write('\t@echo %s\n\t$(Verb) %s\n' % (desc, command))
54 else:
55 self.output.write('\t%s\n' % command)
56 if r['depfile']:
57 depfile = subst(r['depfile'])
58 self.output.write('-include '+depfile+'\n')
59 self.output.write('\n')
60
61 self.all_targets.append(output)
62 if r['generator']:
63 self.distclean_files.append(output)
64 else:
65 self.clean_files.append(output)
66
67 def _as_list(self, input):
68 if isinstance(input, list):
69 return input
70 return [input]
71
Peter Collingbournebae68332012-06-01 17:29:59 +000072 def default(self, paths):
73 self.default_targets += self._as_list(paths)
74
Peter Collingbourned5395fb2012-01-08 22:09:58 +000075 def finish(self):
Peter Collingbournebae68332012-06-01 17:29:59 +000076 self.output.write('all:: %s\n\n' % ' '.join(self.default_targets or self.all_targets))
Peter Collingbourned5395fb2012-01-08 22:09:58 +000077 self.output.write('clean: \n\trm -f %s\n\n' % ' '.join(self.clean_files))
78 self.output.write('distclean: clean\n\trm -f %s\n' % ' '.join(self.distclean_files))
79
80class Ninja(ninja_syntax.Writer):
81 def __init__(self):
82 ninja_syntax.Writer.__init__(self, open(self.output_filename(), 'w'))
83
84 def output_filename(self):
85 return 'build.ninja'
86
87 def finish(self):
88 pass
89
90def from_name(name):
91 if name == 'make':
92 return Make()
93 if name == 'ninja':
94 return Ninja()
95 raise LookupError, 'unknown generator: %s; supported generators are make and ninja' % name