OILS / build / ninja_lib_test.py View on Github | oils.pub

260 lines, 176 significant
1#!/usr/bin/env python2
2"""
3ninja_lib_test.py: Tests for ninja_lib.py
4"""
5from __future__ import print_function
6
7import sys
8import unittest
9
10from build.ninja_lib import log
11from build import ninja_lib # module under test
12from vendor import ninja_syntax
13
14CONFIG = ('cxx', 'dbg', None)
15
16MATRIX1 = [CONFIG]
17
18MATRIX = [
19 ('cxx', 'dbg'),
20 ('cxx', 'opt'),
21]
22
23
24def CallFor(n, output_name):
25 for b in n.build_calls:
26 if b.outputs[0] == output_name:
27 return b
28 else:
29 raise RuntimeError('%s not found' % output_name)
30
31
32class NinjaTest(unittest.TestCase):
33
34 def _Rules(self):
35 n = ninja_syntax.Writer(sys.stdout)
36 n = ninja_syntax.FakeWriter(n)
37
38 ru = ninja_lib.Rules(n)
39 return n, ru
40
41 def test_cc_library_IsLazy(self):
42 n, ru = self._Rules()
43
44 ru.cc_library('//mycpp/ab', ['mycpp/a.cc', 'mycpp/b.cc'])
45 self.assertEqual(0, len(n.build_calls))
46
47 ru.cc_binary('mycpp/a_test.cc', deps=['//mycpp/ab'], matrix=MATRIX1)
48
49 deps = ninja_lib.Deps(ru)
50 deps.WriteRules()
51
52 actions = [b.rule for b in n.build_calls]
53 self.assertEqual(['compile_one', 'compile_one', 'compile_one', 'link'],
54 actions)
55
56 last = n.build_calls[-1]
57 self.assertEqual([
58 '_build/obj/cxx-dbg/mycpp/a_test.o',
59 '_build/obj/cxx-dbg/mycpp/a.o',
60 '_build/obj/cxx-dbg/mycpp/b.o',
61 ], last.inputs)
62
63 # It's NOT used in a binary, so not instantiated
64 ru.cc_library('//mycpp/z', ['mycpp/z.cc'])
65 self.assertEqual(4, len(n.build_calls))
66
67 self.assertEqual(4, n.num_build_targets())
68
69 def testDiamondDeps(self):
70 n, ru = self._Rules()
71
72 # e
73 # |
74 # d
75 # | \
76 # b c
77 # | /
78 # a
79
80 ru.cc_library('//mycpp/e', srcs=['mycpp/e.cc']) # leaf
81 ru.cc_library('//mycpp/d', srcs=['mycpp/d.cc'],
82 deps=['//mycpp/e']) # diamond
83 ru.cc_library('//mycpp/b', srcs=['mycpp/b.cc'], deps=['//mycpp/d'])
84 ru.cc_library('//mycpp/c', srcs=['mycpp/c.cc'], deps=['//mycpp/d'])
85 ru.cc_binary('mycpp/a.cc',
86 deps=['//mycpp/b', '//mycpp/c'],
87 matrix=MATRIX1)
88
89 deps = ninja_lib.Deps(ru)
90 deps.WriteRules()
91
92 actions = [b.rule for b in n.build_calls]
93 self.assertEqual(
94 [
95 'compile_one', # e
96 'compile_one', # d
97 'compile_one', # c
98 'compile_one', # b
99 'compile_one', # a
100 'link'
101 ],
102 actions)
103
104 b = CallFor(n, '_bin/cxx-dbg/mycpp/a')
105 print(b)
106 self.assertEqual([
107 '_build/obj/cxx-dbg/mycpp/a.o',
108 '_build/obj/cxx-dbg/mycpp/b.o',
109 '_build/obj/cxx-dbg/mycpp/c.o',
110 '_build/obj/cxx-dbg/mycpp/d.o',
111 '_build/obj/cxx-dbg/mycpp/e.o',
112 ], sorted(b.inputs))
113
114 def testCircularDeps(self):
115 # Should be disallowed I think
116 pass
117
118 def testSourcesForBinary(self):
119 n, ru = self._Rules()
120
121 ru.cc_library('//mycpp/y', srcs=['mycpp/y.cc', 'mycpp/y2.cc'])
122 ru.cc_library('//mycpp/z', srcs=['mycpp/z.cc'], deps=['//mycpp/y'])
123
124 # cc_library() is lazy
125 self.assertEqual(0, len(n.build_calls))
126
127 ru.cc_binary('mycpp/a_test.cc', deps=['//mycpp/z'], matrix=MATRIX)
128
129 deps = ninja_lib.Deps(ru)
130 deps.WriteRules()
131
132 self.assertEqual(11, len(n.build_calls))
133
134 srcs = deps.SourcesForBinary('mycpp/a_test.cc')
135 self.assertEqual(
136 ['mycpp/a_test.cc', 'mycpp/y.cc', 'mycpp/y2.cc', 'mycpp/z.cc'],
137 srcs)
138
139 log('generated %d targets', n.num_build_targets())
140
141 def test_asdl(self):
142 n, ru = self._Rules()
143 ru.asdl_library('mycpp/examples/foo.asdl')
144
145 self.assertEqual(1, len(n.build_calls))
146
147 first = n.build_calls[0]
148 self.assertEqual('asdl-cpp', first.rule)
149
150 # ru.asdl_library('mycpp/examples/foo.asdl', pretty_print_methods=False)
151
152 def test_cc_binary_to_asdl(self):
153 n, ru = self._Rules()
154
155 ru.asdl_library('asdl/hnode.asdl',
156 pretty_print_methods=False) # REQUIRED
157 ru.asdl_library('display/pretty.asdl')
158
159 ru.asdl_library('mycpp/examples/expr.asdl')
160
161 ru.cc_binary('_gen/mycpp/examples/parse.mycpp.cc',
162 deps=['//mycpp/examples/expr.asdl'],
163 matrix=MATRIX1)
164
165 deps = ninja_lib.Deps(ru)
166 deps.WriteRules()
167
168 actions = [b.rule for b in n.build_calls]
169 print(actions)
170 self.assertEqual([
171 'asdl-cpp', 'asdl-cpp', 'asdl-cpp', 'compile_one', 'compile_one',
172 'compile_one', 'link'
173 ], actions)
174
175 compile_parse = CallFor(
176 n, '_build/obj/cxx-dbg/_gen/mycpp/examples/parse.mycpp.o')
177
178 # Important implicit dependencies on generated headers!
179 self.assertEqual([
180 '_gen/asdl/hnode.asdl.h',
181 '_gen/display/pretty.asdl.h',
182 '_gen/mycpp/examples/expr.asdl.h',
183 ], compile_parse.implicit)
184
185 last = n.build_calls[-1]
186
187 self.assertEqual([
188 '_build/obj/cxx-dbg/_gen/mycpp/examples/parse.mycpp.o',
189 '_build/obj/cxx-dbg/_gen/display/pretty.asdl.o',
190 '_build/obj/cxx-dbg/_gen/mycpp/examples/expr.asdl.o',
191 ], last.inputs)
192
193 def test_asdl_to_asdl(self):
194 n, ru = self._Rules()
195
196 ru.asdl_library('asdl/hnode.asdl',
197 pretty_print_methods=False) # REQUIRED
198 ru.asdl_library('display/pretty.asdl')
199
200 ru.asdl_library('asdl/examples/demo_lib.asdl')
201
202 # 'use' in ASDL creates this dependency
203 ru.asdl_library('asdl/examples/typed_demo.asdl',
204 deps=['//asdl/examples/demo_lib.asdl'])
205
206 actions = [call.rule for call in n.build_calls]
207 self.assertEqual(['asdl-cpp', 'asdl-cpp', 'asdl-cpp', 'asdl-cpp'],
208 actions)
209
210 ru.cc_binary('asdl/gen_cpp_test.cc',
211 deps=['//asdl/examples/typed_demo.asdl'],
212 matrix=MATRIX1)
213
214 deps = ninja_lib.Deps(ru)
215 deps.WriteRules()
216
217 actions = [call.rule for call in n.build_calls]
218 print(actions)
219 self.assertEqual(
220 [
221 'asdl-cpp',
222 'asdl-cpp',
223 'asdl-cpp',
224 'asdl-cpp',
225 'compile_one',
226 'compile_one', # compile demo_lib
227 'compile_one', # compile typed_demo
228 'compile_one', # compile gen_cpp_test
229 'link',
230 ],
231 actions)
232
233 c = CallFor(n,
234 '_build/obj/cxx-dbg/_gen/asdl/examples/typed_demo.asdl.o')
235 print(c)
236
237 # typed_demo depends on demo_lib, so compiling typed_demo.asdl.c depends on
238 # the header demo_lib.asdl.h
239 self.assertEqual([
240 '_gen/asdl/examples/demo_lib.asdl.h', '_gen/asdl/hnode.asdl.h',
241 '_gen/display/pretty.asdl.h'
242 ], sorted(c.implicit))
243
244 c = CallFor(n, '_build/obj/cxx-dbg/asdl/gen_cpp_test.o')
245 print(c)
246 print(c.implicit)
247 self.assertEqual([
248 '_gen/asdl/examples/demo_lib.asdl.h',
249 '_gen/asdl/examples/typed_demo.asdl.h',
250 '_gen/asdl/hnode.asdl.h',
251 '_gen/display/pretty.asdl.h',
252 ], sorted(c.implicit))
253
254 def testShWrap(self):
255 # TODO: Rename to py_binary or py_tool
256 pass
257
258
259if __name__ == '__main__':
260 unittest.main()