OILS / build / ninja_lib_test.py View on Github | oilshell.org

255 lines, 171 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 ru.WriteRules()
50
51 actions = [b.rule for b in n.build_calls]
52 self.assertEqual(['compile_one', 'compile_one', 'compile_one', 'link'],
53 actions)
54
55 last = n.build_calls[-1]
56 self.assertEqual([
57 '_build/obj/cxx-dbg/mycpp/a_test.o',
58 '_build/obj/cxx-dbg/mycpp/a.o',
59 '_build/obj/cxx-dbg/mycpp/b.o',
60 ], last.inputs)
61
62 # It's NOT used in a binary, so not instantiated
63 ru.cc_library('//mycpp/z', ['mycpp/z.cc'])
64 self.assertEqual(4, len(n.build_calls))
65
66 self.assertEqual(4, n.num_build_targets())
67
68 def testDiamondDeps(self):
69 n, ru = self._Rules()
70
71 # e
72 # |
73 # d
74 # | \
75 # b c
76 # | /
77 # a
78
79 ru.cc_library('//mycpp/e', srcs=['mycpp/e.cc']) # leaf
80 ru.cc_library('//mycpp/d', srcs=['mycpp/d.cc'],
81 deps=['//mycpp/e']) # diamond
82 ru.cc_library('//mycpp/b', srcs=['mycpp/b.cc'], deps=['//mycpp/d'])
83 ru.cc_library('//mycpp/c', srcs=['mycpp/c.cc'], deps=['//mycpp/d'])
84 ru.cc_binary('mycpp/a.cc',
85 deps=['//mycpp/b', '//mycpp/c'],
86 matrix=MATRIX1)
87
88 ru.WriteRules()
89
90 actions = [b.rule for b in n.build_calls]
91 self.assertEqual(
92 [
93 'compile_one', # e
94 'compile_one', # d
95 'compile_one', # c
96 'compile_one', # b
97 'compile_one', # a
98 'link'
99 ],
100 actions)
101
102 b = CallFor(n, '_bin/cxx-dbg/mycpp/a')
103 print(b)
104 self.assertEqual([
105 '_build/obj/cxx-dbg/mycpp/a.o',
106 '_build/obj/cxx-dbg/mycpp/b.o',
107 '_build/obj/cxx-dbg/mycpp/c.o',
108 '_build/obj/cxx-dbg/mycpp/d.o',
109 '_build/obj/cxx-dbg/mycpp/e.o',
110 ], sorted(b.inputs))
111
112 def testCircularDeps(self):
113 # Should be disallowed I think
114 pass
115
116 def testSourcesForBinary(self):
117 n, ru = self._Rules()
118
119 ru.cc_library('//mycpp/y', srcs=['mycpp/y.cc', 'mycpp/y2.cc'])
120 ru.cc_library('//mycpp/z', srcs=['mycpp/z.cc'], deps=['//mycpp/y'])
121
122 # cc_library() is lazy
123 self.assertEqual(0, len(n.build_calls))
124
125 ru.cc_binary('mycpp/a_test.cc', deps=['//mycpp/z'], matrix=MATRIX)
126
127 ru.WriteRules()
128
129 self.assertEqual(11, len(n.build_calls))
130
131 srcs = ru.SourcesForBinary('mycpp/a_test.cc')
132 self.assertEqual(
133 ['mycpp/a_test.cc', 'mycpp/y.cc', 'mycpp/y2.cc', 'mycpp/z.cc'],
134 srcs)
135
136 log('generated %d targets', n.num_build_targets())
137
138 def test_asdl(self):
139 n, ru = self._Rules()
140 ru.asdl_library('mycpp/examples/foo.asdl')
141
142 self.assertEqual(1, len(n.build_calls))
143
144 first = n.build_calls[0]
145 self.assertEqual('asdl-cpp', first.rule)
146
147 # ru.asdl_library('mycpp/examples/foo.asdl', pretty_print_methods=False)
148
149 def test_cc_binary_to_asdl(self):
150 n, ru = self._Rules()
151
152 ru.asdl_library('asdl/hnode.asdl',
153 pretty_print_methods=False) # REQUIRED
154 ru.asdl_library('display/pretty.asdl')
155
156 ru.asdl_library('mycpp/examples/expr.asdl')
157
158 ru.cc_binary('_gen/mycpp/examples/parse.mycpp.cc',
159 deps=['//mycpp/examples/expr.asdl'],
160 matrix=MATRIX1)
161
162 ru.WriteRules()
163
164 actions = [b.rule for b in n.build_calls]
165 print(actions)
166 self.assertEqual([
167 'asdl-cpp', 'asdl-cpp', 'asdl-cpp', 'compile_one', 'compile_one',
168 'compile_one', 'link'
169 ], actions)
170
171 compile_parse = CallFor(
172 n, '_build/obj/cxx-dbg/_gen/mycpp/examples/parse.mycpp.o')
173
174 # Important implicit dependencies on generated headers!
175 self.assertEqual([
176 '_gen/asdl/hnode.asdl.h',
177 '_gen/display/pretty.asdl.h',
178 '_gen/mycpp/examples/expr.asdl.h',
179 ], compile_parse.implicit)
180
181 last = n.build_calls[-1]
182
183 self.assertEqual([
184 '_build/obj/cxx-dbg/_gen/mycpp/examples/parse.mycpp.o',
185 '_build/obj/cxx-dbg/_gen/display/pretty.asdl.o',
186 '_build/obj/cxx-dbg/_gen/mycpp/examples/expr.asdl.o',
187 ], last.inputs)
188
189 def test_asdl_to_asdl(self):
190 n, ru = self._Rules()
191
192 ru.asdl_library('asdl/hnode.asdl',
193 pretty_print_methods=False) # REQUIRED
194 ru.asdl_library('display/pretty.asdl')
195
196 ru.asdl_library('asdl/examples/demo_lib.asdl')
197
198 # 'use' in ASDL creates this dependency
199 ru.asdl_library('asdl/examples/typed_demo.asdl',
200 deps=['//asdl/examples/demo_lib.asdl'])
201
202 actions = [call.rule for call in n.build_calls]
203 self.assertEqual(['asdl-cpp', 'asdl-cpp', 'asdl-cpp', 'asdl-cpp'],
204 actions)
205
206 ru.cc_binary('asdl/gen_cpp_test.cc',
207 deps=['//asdl/examples/typed_demo.asdl'],
208 matrix=MATRIX1)
209
210 ru.WriteRules()
211
212 actions = [call.rule for call in n.build_calls]
213 print(actions)
214 self.assertEqual(
215 [
216 'asdl-cpp',
217 'asdl-cpp',
218 'asdl-cpp',
219 'asdl-cpp',
220 'compile_one',
221 'compile_one', # compile demo_lib
222 'compile_one', # compile typed_demo
223 'compile_one', # compile gen_cpp_test
224 'link',
225 ],
226 actions)
227
228 c = CallFor(n,
229 '_build/obj/cxx-dbg/_gen/asdl/examples/typed_demo.asdl.o')
230 print(c)
231
232 # typed_demo depends on demo_lib, so compiling typed_demo.asdl.c depends on
233 # the header demo_lib.asdl.h
234 self.assertEqual([
235 '_gen/asdl/examples/demo_lib.asdl.h', '_gen/asdl/hnode.asdl.h',
236 '_gen/display/pretty.asdl.h'
237 ], sorted(c.implicit))
238
239 c = CallFor(n, '_build/obj/cxx-dbg/asdl/gen_cpp_test.o')
240 print(c)
241 print(c.implicit)
242 self.assertEqual([
243 '_gen/asdl/examples/demo_lib.asdl.h',
244 '_gen/asdl/examples/typed_demo.asdl.h',
245 '_gen/asdl/hnode.asdl.h',
246 '_gen/display/pretty.asdl.h',
247 ], sorted(c.implicit))
248
249 def testShWrap(self):
250 # TODO: Rename to py_binary or py_tool
251 pass
252
253
254if __name__ == '__main__':
255 unittest.main()