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

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