[ci skip] update generated files
[scons.git] / test / sconsign / script / SConsignFile.py
blob680eae54516bf9e01767668faff29b82dba6bf7b
1 #!/usr/bin/env python
3 # MIT License
5 # Copyright The SCons Foundation
7 # Permission is hereby granted, free of charge, to any person obtaining
8 # a copy of this software and associated documentation files (the
9 # "Software"), to deal in the Software without restriction, including
10 # without limitation the rights to use, copy, modify, merge, publish,
11 # distribute, sublicense, and/or sell copies of the Software, and to
12 # permit persons to whom the Software is furnished to do so, subject to
13 # the following conditions:
15 # The above copyright notice and this permission notice shall be included
16 # in all copies or substantial portions of the Software.
18 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
19 # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
20 # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 """
27 Verify that the sconsign script works with files generated when
28 using the signatures in an SConsignFile().
29 """
31 import TestSCons
32 import TestSConsign
34 from TestSCons import _python_
35 from TestCmd import NEED_HELPER
37 test = TestSConsign.TestSConsign(match = TestSConsign.match_re)
39 if NEED_HELPER:
40 test.skip_test("Test host cannot directly execute scripts, skipping test\n")
42 test.subdir('sub1', 'sub2')
44 fake_cc_py = test.workpath('fake_cc.py')
45 fake_link_py = test.workpath('fake_link.py')
47 test.write(
48 fake_cc_py,
49 fr"""#!{_python_}
50 import os
51 import re
52 import sys
54 path = sys.argv[1].split()
56 def find_file(f):
57 for dir in path:
58 p = dir + os.sep + f
59 if os.path.exists(p):
60 return open(p, 'r')
61 return None
63 def process(infp, outfp):
64 for line in infp.readlines():
65 m = re.match(r'#include <(.*)>', line)
66 if m:
67 file = m.group(1)
68 found = find_file(file)
69 process(found, outfp)
70 if found:
71 found.close()
72 else:
73 outfp.write(line)
75 with open(sys.argv[2], 'w') as outf, open(sys.argv[3], 'r') as ifp:
76 outf.write('fake_cc.py: %s\n' % sys.argv)
77 process(ifp, outf)
79 sys.exit(0)
80 """,
83 test.write(
84 fake_link_py,
85 fr"""#!{_python_}
86 import sys
88 with open(sys.argv[1], 'w') as outf, open(sys.argv[2], 'r') as ifp:
89 outf.write('fake_link.py: %s\n' % sys.argv)
90 outf.write(ifp.read())
92 sys.exit(0)
93 """,
96 test.chmod(fake_cc_py, 0o755)
97 test.chmod(fake_link_py, 0o755)
99 # Note: We don't use os.path.join() representations of the file names
100 # in the expected output because paths in the .sconsign files are
101 # canonicalized to use / as the separator.
103 sub1_hello_c = 'sub1/hello.c'
104 sub1_hello_obj = 'sub1/hello.obj'
105 sub2_hello_c = 'sub2/hello.c'
106 sub2_hello_obj = 'sub2/hello.obj'
107 sub2_inc1_h = 'sub2/inc1.h'
108 sub2_inc2_h = 'sub2/inc2.h'
110 test.write(
111 ['SConstruct'],
112 f"""\
113 SConsignFile()
114 _ = DefaultEnvironment(tools=[])
115 env1 = Environment(
116 PROGSUFFIX='.exe',
117 OBJSUFFIX='.obj',
118 CCCOM=[[r'{fake_cc_py}', 'sub2', '$TARGET', '$SOURCE']],
119 LINKCOM=[[r'{fake_link_py}', '$TARGET', '$SOURCE']],
121 env1.PrependENVPath('PATHEXT', '.PY')
122 env1.Program('sub1/hello.c')
123 env2 = env1.Clone(CPPPATH=['sub2'])
124 env2.Program('sub2/hello.c')
125 """,
127 # TODO in the above, we would normally want to run a python program
128 # using "our python" like this:
129 # CCCOM=[[r'{_python_}', r'{fake_cc_py}', 'sub2', '$TARGET', '$SOURCE']],
130 # LINKCOM=[[r'{_python_}', r'{fake_link_py}', '$TARGET', '$SOURCE']],
131 # however we're looking at dependencies with sconsign, so that breaks things.
132 # It still breaks things on Windows if something else is registered as the
133 # handler for .py files, as Visual Studio Code installs itself.
135 test.write(['sub1', 'hello.c'], r"""
136 sub1/hello.c
137 """)
139 test.write(['sub2', 'hello.c'], r"""
140 #include <inc1.h>
141 #include <inc2.h>
143 main(int argc, char *argv[])
145 argv[argc++] = "--";
146 printf("sub2/goodbye.c\n");
147 exit (0);
149 """)
151 test.write(['sub2', 'inc1.h'], r"""
152 #define STRING1 "inc1.h"
153 """)
155 test.write(['sub2', 'inc2.h'], r"""
156 #define STRING2 "inc2.h"
157 """)
159 test.run(arguments='--implicit-cache .')
161 sig_re = r'[0-9a-fA-F]{32,64}'
163 database_name = test.get_sconsignname()
165 test.run_sconsign(arguments=database_name,
166 stdout=r"""=== .:
167 SConstruct: None \d+ \d+
168 fake_cc\.py: %(sig_re)s \d+ \d+
169 fake_link\.py: %(sig_re)s \d+ \d+
170 === sub1:
171 hello.c: %(sig_re)s \d+ \d+
172 hello.exe: %(sig_re)s \d+ \d+
173 %(sub1_hello_obj)s: %(sig_re)s \d+ \d+
174 fake_link\.py: %(sig_re)s \d+ \d+
175 %(sig_re)s \[.*\]
176 hello.obj: %(sig_re)s \d+ \d+
177 %(sub1_hello_c)s: %(sig_re)s \d+ \d+
178 fake_cc\.py: %(sig_re)s \d+ \d+
179 %(sig_re)s \[.*\]
180 === sub2:
181 hello.c: %(sig_re)s \d+ \d+
182 hello.exe: %(sig_re)s \d+ \d+
183 %(sub2_hello_obj)s: %(sig_re)s \d+ \d+
184 fake_link\.py: %(sig_re)s \d+ \d+
185 %(sig_re)s \[.*\]
186 hello.obj: %(sig_re)s \d+ \d+
187 %(sub2_hello_c)s: %(sig_re)s \d+ \d+
188 %(sub2_inc1_h)s: %(sig_re)s \d+ \d+
189 %(sub2_inc2_h)s: %(sig_re)s \d+ \d+
190 fake_cc\.py: %(sig_re)s \d+ \d+
191 %(sig_re)s \[.*\]
192 inc1.h: %(sig_re)s \d+ \d+
193 inc2.h: %(sig_re)s \d+ \d+
194 """ % locals())
196 test.run_sconsign(arguments="--raw " + database_name,
197 stdout=r"""=== .:
198 SConstruct: {'csig': None, 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2}
199 fake_cc\.py: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2}
200 fake_link\.py: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2}
201 === sub1:
202 hello.c: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2}
203 hello.exe: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2}
204 %(sub1_hello_obj)s: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2}
205 fake_link\.py: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2}
206 %(sig_re)s \[.*\]
207 hello.obj: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2}
208 %(sub1_hello_c)s: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2}
209 fake_cc\.py: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2}
210 %(sig_re)s \[.*\]
211 === sub2:
212 hello.c: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2}
213 hello.exe: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2}
214 %(sub2_hello_obj)s: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2}
215 fake_link\.py: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2}
216 %(sig_re)s \[.*\]
217 hello.obj: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2}
218 %(sub2_hello_c)s: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2}
219 %(sub2_inc1_h)s: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2}
220 %(sub2_inc2_h)s: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2}
221 fake_cc\.py: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2}
222 %(sig_re)s \[.*\]
223 inc1.h: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2}
224 inc2.h: {'csig': '%(sig_re)s', 'timestamp': \d+L?, 'size': \d+L?, '_version_id': 2}
225 """ % locals())
227 expect = r"""=== .:
228 SConstruct:
229 csig: None
230 timestamp: \d+
231 size: \d+
232 fake_cc\.py:
233 csig: %(sig_re)s
234 timestamp: \d+
235 size: \d+
236 fake_link\.py:
237 csig: %(sig_re)s
238 timestamp: \d+
239 size: \d+
240 === sub1:
241 hello.c:
242 csig: %(sig_re)s
243 timestamp: \d+
244 size: \d+
245 hello.exe:
246 csig: %(sig_re)s
247 timestamp: \d+
248 size: \d+
249 implicit:
250 %(sub1_hello_obj)s:
251 csig: %(sig_re)s
252 timestamp: \d+
253 size: \d+
254 fake_link\.py:
255 csig: %(sig_re)s
256 timestamp: \d+
257 size: \d+
258 action: %(sig_re)s \[.*\]
259 hello.obj:
260 csig: %(sig_re)s
261 timestamp: \d+
262 size: \d+
263 implicit:
264 %(sub1_hello_c)s:
265 csig: %(sig_re)s
266 timestamp: \d+
267 size: \d+
268 fake_cc\.py:
269 csig: %(sig_re)s
270 timestamp: \d+
271 size: \d+
272 action: %(sig_re)s \[.*\]
273 === sub2:
274 hello.c:
275 csig: %(sig_re)s
276 timestamp: \d+
277 size: \d+
278 hello.exe:
279 csig: %(sig_re)s
280 timestamp: \d+
281 size: \d+
282 implicit:
283 %(sub2_hello_obj)s:
284 csig: %(sig_re)s
285 timestamp: \d+
286 size: \d+
287 fake_link\.py:
288 csig: %(sig_re)s
289 timestamp: \d+
290 size: \d+
291 action: %(sig_re)s \[.*\]
292 hello.obj:
293 csig: %(sig_re)s
294 timestamp: \d+
295 size: \d+
296 implicit:
297 %(sub2_hello_c)s:
298 csig: %(sig_re)s
299 timestamp: \d+
300 size: \d+
301 %(sub2_inc1_h)s:
302 csig: %(sig_re)s
303 timestamp: \d+
304 size: \d+
305 %(sub2_inc2_h)s:
306 csig: %(sig_re)s
307 timestamp: \d+
308 size: \d+
309 fake_cc\.py:
310 csig: %(sig_re)s
311 timestamp: \d+
312 size: \d+
313 action: %(sig_re)s \[.*\]
314 inc1.h:
315 csig: %(sig_re)s
316 timestamp: \d+
317 size: \d+
318 inc2.h:
319 csig: %(sig_re)s
320 timestamp: \d+
321 size: \d+
322 """ % locals()
324 test.run_sconsign(arguments="-v " + database_name, stdout=expect)
326 test.run_sconsign(arguments="-c -v " + database_name,
327 stdout=r"""=== .:
328 SConstruct:
329 csig: None
330 fake_cc\.py:
331 csig: %(sig_re)s
332 fake_link\.py:
333 csig: %(sig_re)s
334 === sub1:
335 hello.c:
336 csig: %(sig_re)s
337 hello.exe:
338 csig: %(sig_re)s
339 hello.obj:
340 csig: %(sig_re)s
341 === sub2:
342 hello.c:
343 csig: %(sig_re)s
344 hello.exe:
345 csig: %(sig_re)s
346 hello.obj:
347 csig: %(sig_re)s
348 inc1.h:
349 csig: %(sig_re)s
350 inc2.h:
351 csig: %(sig_re)s
352 """ % locals())
354 test.run_sconsign(arguments="-s -v " + database_name,
355 stdout=r"""=== .:
356 SConstruct:
357 size: \d+
358 fake_cc\.py:
359 size: \d+
360 fake_link\.py:
361 size: \d+
362 === sub1:
363 hello.c:
364 size: \d+
365 hello.exe:
366 size: \d+
367 hello.obj:
368 size: \d+
369 === sub2:
370 hello.c:
371 size: \d+
372 hello.exe:
373 size: \d+
374 hello.obj:
375 size: \d+
376 inc1.h:
377 size: \d+
378 inc2.h:
379 size: \d+
380 """)
382 test.run_sconsign(arguments="-t -v " + database_name,
383 stdout=r"""=== .:
384 SConstruct:
385 timestamp: \d+
386 fake_cc\.py:
387 timestamp: \d+
388 fake_link\.py:
389 timestamp: \d+
390 === sub1:
391 hello.c:
392 timestamp: \d+
393 hello.exe:
394 timestamp: \d+
395 hello.obj:
396 timestamp: \d+
397 === sub2:
398 hello.c:
399 timestamp: \d+
400 hello.exe:
401 timestamp: \d+
402 hello.obj:
403 timestamp: \d+
404 inc1.h:
405 timestamp: \d+
406 inc2.h:
407 timestamp: \d+
408 """)
410 test.run_sconsign(arguments="-e hello.obj " + database_name,
411 stdout=r"""=== .:
412 === sub1:
413 hello.obj: %(sig_re)s \d+ \d+
414 %(sub1_hello_c)s: %(sig_re)s \d+ \d+
415 fake_cc\.py: %(sig_re)s \d+ \d+
416 %(sig_re)s \[.*\]
417 === sub2:
418 hello.obj: %(sig_re)s \d+ \d+
419 %(sub2_hello_c)s: %(sig_re)s \d+ \d+
420 %(sub2_inc1_h)s: %(sig_re)s \d+ \d+
421 %(sub2_inc2_h)s: %(sig_re)s \d+ \d+
422 fake_cc\.py: %(sig_re)s \d+ \d+
423 %(sig_re)s \[.*\]
424 """ % locals(),
425 stderr=r"""sconsign: no entry `hello\.obj' in `\.'
426 """)
428 test.run_sconsign(arguments="-e hello.obj -e hello.exe -e hello.obj " + database_name,
429 stdout=r"""=== .:
430 === sub1:
431 hello.obj: %(sig_re)s \d+ \d+
432 %(sub1_hello_c)s: %(sig_re)s \d+ \d+
433 fake_cc\.py: %(sig_re)s \d+ \d+
434 %(sig_re)s \[.*\]
435 hello.exe: %(sig_re)s \d+ \d+
436 %(sub1_hello_obj)s: %(sig_re)s \d+ \d+
437 fake_link\.py: %(sig_re)s \d+ \d+
438 %(sig_re)s \[.*\]
439 hello.obj: %(sig_re)s \d+ \d+
440 %(sub1_hello_c)s: %(sig_re)s \d+ \d+
441 fake_cc\.py: %(sig_re)s \d+ \d+
442 %(sig_re)s \[.*\]
443 === sub2:
444 hello.obj: %(sig_re)s \d+ \d+
445 %(sub2_hello_c)s: %(sig_re)s \d+ \d+
446 %(sub2_inc1_h)s: %(sig_re)s \d+ \d+
447 %(sub2_inc2_h)s: %(sig_re)s \d+ \d+
448 fake_cc\.py: %(sig_re)s \d+ \d+
449 %(sig_re)s \[.*\]
450 hello.exe: %(sig_re)s \d+ \d+
451 %(sub2_hello_obj)s: %(sig_re)s \d+ \d+
452 fake_link\.py: %(sig_re)s \d+ \d+
453 %(sig_re)s \[.*\]
454 hello.obj: %(sig_re)s \d+ \d+
455 %(sub2_hello_c)s: %(sig_re)s \d+ \d+
456 %(sub2_inc1_h)s: %(sig_re)s \d+ \d+
457 %(sub2_inc2_h)s: %(sig_re)s \d+ \d+
458 fake_cc\.py: %(sig_re)s \d+ \d+
459 %(sig_re)s \[.*\]
460 """ % locals(),
461 stderr=r"""sconsign: no entry `hello\.obj' in `\.'
462 sconsign: no entry `hello\.exe' in `\.'
463 sconsign: no entry `hello\.obj' in `\.'
464 """)
466 #test.run_sconsign(arguments="-i -v " + database_name,
467 # stdout=r"""=== sub1:
468 #hello.exe:
469 # implicit:
470 # hello.obj: %(sig_re)s
471 #hello.obj:
472 # implicit:
473 # hello.c: %(sig_re)s
474 #=== sub2:
475 #hello.exe:
476 # implicit:
477 # hello.obj: %(sig_re)s
478 #hello.obj:
479 # implicit:
480 # hello.c: %(sig_re)s
481 # inc1.h: %(sig_re)s
482 # inc2.h: %(sig_re)s
483 #inc1.h: %(sig_re)s
484 #inc2.h: %(sig_re)s
485 #""" % locals())
487 test.pass_test()
489 # Local Variables:
490 # tab-width:4
491 # indent-tabs-mode:nil
492 # End:
493 # vim: set expandtab tabstop=4 shiftwidth=4: