Reverted to correct commit this time.
[lldb.git] / libclc / build / metabuild.py
1 import ninja_syntax
2 import os
3
4 # Simple meta-build system.
5
6 class 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 = []
12     self.default_targets = []
13     self.clean_files = []
14     self.distclean_files = []
15     self.output.write("""all::
16
17 ifndef VERBOSE
18   Verb = @
19 endif
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
72   def default(self, paths):
73     self.default_targets += self._as_list(paths)
74
75   def finish(self):
76     self.output.write('all:: %s\n\n' % ' '.join(self.default_targets or self.all_targets))
77     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
80 class 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
90 def 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