5 # Permission is hereby granted, free of charge, to any person obtaining
6 # a copy of this software and associated documentation files (the
7 # "Software"), to deal in the Software without restriction, including
8 # without limitation the rights to use, copy, modify, merge, publish,
9 # distribute, sublicense, and/or sell copies of the Software, and to
10 # permit persons to whom the Software is furnished to do so, subject to
11 # the following conditions:
13 # The above copyright notice and this permission notice shall be included
14 # in all copies or substantial portions of the Software.
16 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
17 # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
18 # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
36 except AttributeError:
39 for i in xrange(len(lists[0])):
40 result.append(tuple(map(lambda l, i=i: l[i], lists)))
47 if sys.platform == 'win32':
52 # to use cygwin compilers on cmd.exe -> uncomment following line
57 python = TestSCons.python
58 test = TestSCons.TestSCons()
66 global test, work_dir, work_cnt
67 work_cnt = work_cnt + 1
68 work_dir='test%d' % work_cnt
71 test.match_func = TestCmd.match_re
72 elif match == RE_DOTALL:
73 test.match_func = TestCmd.match_re_dotall
75 test.match_func = TestCmd.match_exact
77 def checkFiles(test, files):
80 test.fail_test( not os.path.isfile( test.workpath(work_dir,f) ) )
82 def checklib(lang, name, up_to_date):
84 return (".c", _obj, _exe)
86 return (".cc", _obj, _exe)
89 def __init__(self, p):
92 NCR = 0 # non-cached rebuild
93 CR = 1 # cached rebuild (up to date)
94 NCF = 2 # non-cached build failure
95 CF = 3 # cached build failure
97 def checkLogAndStdout(checks, results, cached,
98 test, logfile, sconf_dir, sconstruct,
99 doCheckLog=1, doCheckStdout=1):
100 def matchPart(log, logfile, lastEnd):
101 m = re.match(log, logfile[lastEnd:])
103 raise NoMatch, lastEnd
104 return m.end() + lastEnd
106 #print len(os.linesep)
109 for i in range(len(ls)):
113 nols = nols + "[^" + ls[i] + "])"
118 logfile = test.read(test.workpath(work_dir, logfile))
120 string.find( logfile, "scons: warning: The stored build "
121 "information has an unexpected class." ) >= 0):
123 sconf_dir = sconf_dir
124 sconstruct = sconstruct
126 log = re.escape("file " + sconstruct + ",line ") + r"\d+:" + ls
127 if doCheckLog: lastEnd = matchPart(log, logfile, lastEnd)
128 log = "\t" + re.escape("Configure(confdir = %s)" % sconf_dir) + ls
129 if doCheckLog: lastEnd = matchPart(log, logfile, lastEnd)
132 for check,result,cache_desc in zip(checks, results, cached):
133 log = re.escape("scons: Configure: " + check) + ls
134 if doCheckLog: lastEnd = matchPart(log, logfile, lastEnd)
137 for bld_desc in cache_desc: # each TryXXX
138 for ext, flag in bld_desc: # each file in TryBuild
139 file = os.path.join(sconf_dir,"conftest_%d%s" % (cnt, ext))
142 if ext in ['.c', '.cpp']:
143 log=log + re.escape(file + " <-") + ls
144 log=log + r"( \|" + nols + "*" + ls + ")+?"
146 log=log + "(" + nols + "*" + ls +")*?"
151 re.escape("scons: Configure: \"%s\" is up to date."
153 log=log+re.escape("scons: Configure: The original builder "
155 log=log+r"( \|.*"+ls+")+"
157 # non-cached rebuild failure
158 log=log + "(" + nols + "*" + ls + ")*?"
161 # cached rebuild failure
163 re.escape("scons: Configure: Building \"%s\" failed "
164 "in a previous run and all its sources are"
165 " up to date." % file) + ls
166 log=log+re.escape("scons: Configure: The original builder "
168 log=log+r"( \|.*"+ls+")+"
171 result = "(cached) " + result
172 rdstr = rdstr + re.escape(check) + re.escape(result) + "\n"
173 log=log + re.escape("scons: Configure: " + result) + ls + ls
174 if doCheckLog: lastEnd = matchPart(log, logfile, lastEnd)
176 if doCheckLog: lastEnd = matchPart(ls, logfile, lastEnd)
177 if doCheckLog and lastEnd != len(logfile):
178 raise NoMatch, lastEnd
181 print "Cannot match log file against log regexp."
183 print "------------------------------------------------------"
184 print logfile[m.pos:]
185 print "------------------------------------------------------"
187 print "------------------------------------------------------"
189 print "------------------------------------------------------"
193 exp_stdout = test.wrap_stdout(".*", rdstr)
194 if not test.match_re_dotall(test.stdout(), exp_stdout):
195 print "Unexpected stdout: "
196 print "-----------------------------------------------------"
197 print repr(test.stdout())
198 print "-----------------------------------------------------"
199 print repr(exp_stdout)
200 print "-----------------------------------------------------"
204 # 1.1 if checks are ok, the cache mechanism should work
208 test.write([work_dir, 'SConstruct'], """
209 if int(ARGUMENTS.get('target_signatures_content', 0)):
210 TargetSignatures('content')
213 env.AppendENVPath('PATH', os.environ['PATH'])
214 conf = Configure(env)
215 r1 = conf.CheckLibWithHeader( '%s', 'math.h', 'c' )
216 r2 = conf.CheckLibWithHeader( None, 'math.h', 'c' )
217 r3 = conf.CheckLib( '%s', autoadd=0 )
218 r4 = conf.CheckLib( None, autoadd=0 )
219 r5 = conf.CheckCHeader( 'math.h' )
220 r6 = conf.CheckCXXHeader( 'vector' )
222 if not (r1 and r2 and r3 and r4 and r5 and r6):
226 test.run(chdir=work_dir)
227 checkLogAndStdout(["Checking for main() in C library %s... " % lib,
228 "Checking for main() in C library None... ",
229 "Checking for main() in C library %s... " % lib,
230 "Checking for main() in C library None... ",
231 "Checking for C header file math.h... ",
232 "Checking for C++ header file vector... "],
234 [[((".c", NCR), (_obj, NCR), (_exe, NCR))]]*4 +
235 [[((".c", NCR), (_obj, NCR))]] +
236 [[((".cpp", NCR), (_obj, NCR))]],
237 test, "config.log", ".sconf_temp", "SConstruct")
240 test.run(chdir=work_dir)
241 checkLogAndStdout(["Checking for main() in C library %s... " % lib,
242 "Checking for main() in C library None... ",
243 "Checking for main() in C library %s... " % lib,
244 "Checking for main() in C library None... ",
245 "Checking for C header file math.h... ",
246 "Checking for C++ header file vector... "],
248 [[((".c", CR), (_obj, CR), (_exe, CR))]]*4 +
249 [[((".c", CR), (_obj, CR))]] +
250 [[((".cpp", CR), (_obj, CR))]],
251 test, "config.log", ".sconf_temp", "SConstruct")
253 # same should be true for TargetSignatures('content')
255 test.run(chdir=work_dir, arguments='target_signatures_content=1 --config=force')
256 checkLogAndStdout(["Checking for main() in C library %s... " % lib,
257 "Checking for main() in C library None... ",
258 "Checking for main() in C library %s... " % lib,
259 "Checking for main() in C library None... ",
260 "Checking for C header file math.h... ",
261 "Checking for C++ header file vector... "],
263 [[((".c", NCR), (_obj, NCR), (_exe, NCR))]]*4 +
264 [[((".c", NCR), (_obj, NCR))]] +
265 [[((".cpp", NCR), (_obj, NCR))]],
266 test, "config.log", ".sconf_temp", "SConstruct")
268 test.run(chdir=work_dir, arguments='target_signatures_content=1')
269 checkLogAndStdout(["Checking for main() in C library %s... " % lib,
270 "Checking for main() in C library None... ",
271 "Checking for main() in C library %s... " % lib,
272 "Checking for main() in C library None... ",
273 "Checking for C header file math.h... ",
274 "Checking for C++ header file vector... "],
276 [[((".c", CR), (_obj, CR), (_exe, CR))]]*4 +
277 [[((".c", CR), (_obj, CR))]] +
278 [[((".cpp", CR), (_obj, CR))]],
279 test, "config.log", ".sconf_temp", "SConstruct")
281 # 1.2 if checks are not ok, the cache mechanism should work as well
282 # (via explicit cache)
283 reset(EXACT) # match exactly, "()" is a regexp thing
285 test.write([work_dir, 'SConstruct'], """
286 if int(ARGUMENTS.get('target_signatures_content', 0)):
287 TargetSignatures('content')
290 env.AppendENVPath('PATH', os.environ['PATH'])
291 conf = env.Configure()
292 r1 = conf.CheckCHeader( 'no_std_c_header.h' ) # leads to compile error
293 r2 = conf.CheckLib( 'no_c_library_SAFFDG' ) # leads to link error
295 if not (not r1 and not r2):
296 print "FAIL: ", r1, r2
300 test.run(chdir=work_dir)
301 checkLogAndStdout(["Checking for C header file no_std_c_header.h... ",
302 "Checking for main() in C library no_c_library_SAFFDG... "],
304 [[((".c", NCR), (_obj, NCF))],
305 [((".c", NCR), (_obj, NCR), (_exe, NCF))]],
306 test, "config.log", ".sconf_temp", "SConstruct")
308 test.run(chdir=work_dir)
309 checkLogAndStdout(["Checking for C header file no_std_c_header.h... ",
310 "Checking for main() in C library no_c_library_SAFFDG... "],
312 [[((".c", CR), (_obj, CF))],
313 [((".c", CR), (_obj, CR), (_exe, CF))]],
314 test, "config.log", ".sconf_temp", "SConstruct")
316 # 1.3 same should be true for TargetSignatures('content')
317 test.run(chdir=work_dir, arguments='--config=force target_signatures_content=1')
318 checkLogAndStdout(["Checking for C header file no_std_c_header.h... ",
319 "Checking for main() in C library no_c_library_SAFFDG... "],
321 [[((".c", NCR), (_obj, NCF))],
322 [((".c", NCR), (_obj, NCR), (_exe, NCF))]],
323 test, "config.log", ".sconf_temp", "SConstruct")
325 test.run(chdir=work_dir, arguments='target_signatures_content=1')
326 checkLogAndStdout(["Checking for C header file no_std_c_header.h... ",
327 "Checking for main() in C library no_c_library_SAFFDG... "],
329 [[((".c", CR), (_obj, CF))],
330 [((".c", CR), (_obj, CR), (_exe, CF))]],
331 test, "config.log", ".sconf_temp", "SConstruct")
335 # 2.1 test that normal builds work together with Sconf
339 test.write([work_dir, 'SConstruct'], """
342 env.AppendENVPath('PATH', os.environ['PATH'])
343 conf = Configure(env)
344 r1 = conf.CheckCHeader( 'math.h' )
345 r2 = conf.CheckCHeader( 'no_std_c_header.h' ) # leads to compile error
348 SConscript( 'SConscript' )
350 test.write([work_dir, 'SConscript'], """
352 env.Program( 'TestProgram', 'TestProgram.c' )
354 test.write([work_dir, 'TestProgram.c'], """
358 printf( "Hello\\n" );
361 test.run(chdir=work_dir)
362 checkLogAndStdout(["Checking for C header file math.h... ",
363 "Checking for C header file no_std_c_header.h... "],
365 [[((".c", NCR), (_obj, NCR))],
366 [((".c", NCR), (_obj, NCF))]],
367 test, "config.log", ".sconf_temp", "SConstruct")
369 test.run(chdir=work_dir)
370 checkLogAndStdout(["Checking for C header file math.h... ",
371 "Checking for C header file no_std_c_header.h... "],
373 [[((".c", CR), (_obj, CR))],
374 [((".c", CR), (_obj, CF))]],
375 test, "config.log", ".sconf_temp", "SConstruct")
377 # 2.2 test that BuildDir builds work together with Sconf
381 test.write([work_dir, 'SConstruct'], """
382 env = Environment(LOGFILE='build/config.log')
384 env.AppendENVPath('PATH', os.environ['PATH'])
385 BuildDir( 'build', '.' )
386 conf = env.Configure(conf_dir='build/config.tests', log_file='$LOGFILE')
387 r1 = conf.CheckCHeader( 'math.h' )
388 r2 = conf.CheckCHeader( 'no_std_c_header.h' ) # leads to compile error
391 # print open( 'build/config.log' ).readlines()
392 SConscript( 'build/SConscript' )
394 test.write([work_dir, 'SConscript'], """
396 env.Program( 'TestProgram', 'TestProgram.c' )
398 test.write([work_dir, 'TestProgram.c'], """
402 printf( "Hello\\n" );
406 test.run(chdir=work_dir)
407 checkLogAndStdout(["Checking for C header file math.h... ",
408 "Checking for C header file no_std_c_header.h... "],
410 [[((".c", NCR), (_obj, NCR))],
411 [((".c", NCR), (_obj, NCF))]],
413 os.path.join("build", "config.log"),
414 os.path.join("build", "config.tests"),
417 test.run(chdir=work_dir)
418 checkLogAndStdout(["Checking for C header file math.h... ",
419 "Checking for C header file no_std_c_header.h... "],
421 [[((".c", CR), (_obj, CR))],
422 [((".c", CR), (_obj, CF))]],
424 os.path.join("build", "config.log"),
425 os.path.join("build", "config.tests"),
428 # 2.3 test that Configure calls in SConscript files work
429 # even if BuildDir is set
432 test.subdir( [work_dir, 'sub'], [work_dir, 'sub', 'local'] )
433 test.write([work_dir, 'SConstruct'], """
436 env = Environment(options=opts)
437 if env['chdir'] == 'yes':
441 BuildDir( 'build', '.' )
442 SConscript( 'build/SConscript' )
444 test.write([work_dir, 'sub', 'local', 'local_header.h'],
445 "/* Hello World */" )
446 test.write([work_dir, 'SConscript'], """
447 SConscript( 'sub/SConscript' )
449 test.write([work_dir, 'sub', 'SConscript'], """
450 def CustomTest(context):
451 context.Message('Executing Custom Test ... ')
452 ret = context.TryCompile('#include "local_header.h"', '.c')
456 env = Environment(FOO='fff')
457 env.Append( CPPPATH='local' )
459 env.AppendENVPath('PATH', os.environ['PATH'])
460 conf = Configure( env, custom_tests = {'CustomTest' : CustomTest,
461 '$FOO' : CustomTest} )
462 if hasattr(conf, 'fff'):
463 conf.Message('$FOO should not have been expanded!')
465 if not conf.CheckCHeader( 'math.h' ):
467 if conf.CheckCHeader( 'no_std_c_header.h' ):
469 if not conf.CustomTest():
472 env.Program( 'TestProgram', 'TestProgram.c' )
474 test.write([work_dir, 'sub', 'TestProgram.h'], """
475 /* Just a test header */
477 test.write([work_dir, 'sub', 'TestProgram.c'], """
478 #include "TestProgram.h"
482 printf( "Hello\\n" );
486 # first with SConscriptChdir(0)
487 test.run(chdir=work_dir, arguments='chdir=no')
488 checkLogAndStdout( ["Checking for C header file math.h... ",
489 "Checking for C header file no_std_c_header.h... ",
490 "Executing Custom Test ... "],
491 ["yes", "no", "yes"],
492 [[((".c", NCR), (_obj, NCR))],
493 [((".c", NCR), (_obj, NCF))],
494 [((".c", NCR), (_obj, NCR))]],
497 os.path.join("build", "sub", "SConscript"))
499 test.run(chdir=work_dir, arguments='chdir=no')
500 checkLogAndStdout( ["Checking for C header file math.h... ",
501 "Checking for C header file no_std_c_header.h... ",
502 "Executing Custom Test ... "],
503 ["yes", "no", "yes"],
504 [[((".c", CR), (_obj, CR))],
505 [((".c", CR), (_obj, CF))],
506 [((".c", CR), (_obj, CR))]],
509 os.path.join("build", "sub", "SConscript"))
511 shutil.rmtree(test.workpath(work_dir, ".sconf_temp"))
512 os.unlink(test.workpath(work_dir, ".sconsign.dblite"))
514 # now with SConscriptChdir(1)
515 test.run(chdir=work_dir, arguments='chdir=yes')
516 checkLogAndStdout( ["Checking for C header file math.h... ",
517 "Checking for C header file no_std_c_header.h... ",
518 "Executing Custom Test ... "],
519 ["yes", "no", "yes"],
520 [[((".c", NCR), (_obj, NCR))],
521 [((".c", NCR), (_obj, NCF))],
522 [((".c", NCR), (_obj, NCR))]],
525 os.path.join("build", "sub", "SConscript"))
527 test.run(chdir=work_dir, arguments='chdir=yes')
528 checkLogAndStdout( ["Checking for C header file math.h... ",
529 "Checking for C header file no_std_c_header.h... ",
530 "Executing Custom Test ... "],
531 ["yes", "no", "yes"],
532 [[((".c", CR), (_obj, CR))],
533 [((".c", CR), (_obj, CF))],
534 [((".c", CR), (_obj, CR))]],
537 os.path.join("build", "sub", "SConscript"))
539 # 3.1 test custom tests
542 compileOK = '#include <stdio.h>\\nint main() {printf("Hello");return 0;}'
543 compileFAIL = "syntax error"
545 linkFAIL = "void myFunc(); int main() { myFunc(); }"
547 runFAIL = "int main() { return 1; }"
548 test.write([work_dir, 'pyAct.py'], 'import sys\nprint sys.argv[1]\nsys.exit(int(sys.argv[1]))\n')
549 test.write([work_dir, 'SConstruct'], """
550 def CheckCustom(test):
551 test.Message( 'Executing MyTest ... ' )
552 retCompileOK = test.TryCompile( '%s', '.c' )
553 retCompileFAIL = test.TryCompile( '%s', '.c' )
554 retLinkOK = test.TryLink( '%s', '.c' )
555 retLinkFAIL = test.TryLink( '%s', '.c' )
556 (retRunOK, outputRunOK) = test.TryRun( '%s', '.c' )
557 (retRunFAIL, outputRunFAIL) = test.TryRun( '%s', '.c' )
558 (retActOK, outputActOK) = test.TryAction( '%s pyAct.py 0 > $TARGET' )
559 (retActFAIL, outputActFAIL) = test.TryAction( '%s pyAct.py 1 > $TARGET' )
560 resOK = retCompileOK and retLinkOK and retRunOK and outputRunOK=="Hello"
561 resOK = resOK and retActOK and int(outputActOK)==0
562 resFAIL = retCompileFAIL or retLinkFAIL or retRunFAIL or outputRunFAIL!=""
563 resFAIL = resFAIL or retActFAIL or outputActFAIL!=""
564 test.Result( int(resOK and not resFAIL) )
565 return resOK and not resFAIL
569 env.AppendENVPath('PATH', os.environ['PATH'])
570 conf = Configure( env, custom_tests={'CheckCustom' : CheckCustom} )
573 """ % (compileOK, compileFAIL, linkOK, linkFAIL, runOK, runFAIL,
575 test.run(chdir=work_dir)
576 checkLogAndStdout(["Executing MyTest ... "],
578 [[(('.c', NCR), (_obj, NCR)),
579 (('.c', NCR), (_obj, NCF)),
580 (('.c', NCR), (_obj, NCR), (_exe, NCR)),
581 (('.c', NCR), (_obj, NCR), (_exe, NCF)),
582 (('.c', NCR), (_obj, NCR), (_exe, NCR), (_exe + '.out', NCR)),
583 (('.c', NCR), (_obj, NCR), (_exe, NCR), (_exe + '.out', NCF)),
586 test, "config.log", ".sconf_temp", "SConstruct")
588 test.run(chdir=work_dir)
589 checkLogAndStdout(["Executing MyTest ... "],
591 [[(('.c', CR), (_obj, CR)),
592 (('.c', CR), (_obj, CF)),
593 (('.c', CR), (_obj, CR), (_exe, CR)),
594 (('.c', CR), (_obj, CR), (_exe, CF)),
595 (('.c', CR), (_obj, CR), (_exe, CR), (_exe + '.out', CR)),
596 (('.c', CR), (_obj, CR), (_exe, CR), (_exe + '.out', CF)),
599 test, "config.log", ".sconf_temp", "SConstruct")
601 # 4.1 test that calling normal builders from an actual configuring
605 test.write([work_dir, 'cmd.py'], r"""
607 sys.stderr.write( 'Hello World on stderr\n' )
608 sys.stdout.write( 'Hello World on stdout\n' )
609 open(sys.argv[1], 'w').write( 'Hello World\n' )
612 test.write([work_dir, 'SConstruct'], """
614 def CustomTest(*args):
616 conf = env.Configure(custom_tests = {'MyTest' : CustomTest})
617 if not conf.MyTest():
618 env.Command("hello", [], "%s cmd.py $TARGET")
621 test.run(chdir=work_dir, stderr="Hello World on stderr\n")
623 # 4.2 test that calling Configure from a builder results in a
627 test.write([work_dir, 'SConstruct'], """
628 def ConfigureAction(target, source, env):
631 env = Environment(BUILDERS = {'MyAction' :
632 Builder(action=Action(ConfigureAction))})
633 env.MyAction('target', [])
635 test.run(chdir=work_dir, status=2,
636 stderr="scons: *** Calling Configure from Builders is not supported.\n")
638 # 4.3 test the calling Configure from multiple subsidiary,
639 # nested SConscript files does *not* result in an error.
641 test.subdir([work_dir, 'dir1'],
643 [work_dir, 'dir2', 'sub1'],
644 [work_dir, 'dir2', 'sub1', 'sub2'])
645 test.write([work_dir, 'SConstruct'], """
647 SConscript(dirs=['dir1', 'dir2'], exports="env")
649 test.write([work_dir, 'dir1', 'SConscript'], """
651 conf = env.Configure()
654 test.write([work_dir, 'dir2', 'SConscript'], """
656 conf = env.Configure()
658 SConscript(dirs=['sub1'], exports="env")
660 test.write([work_dir, 'dir2', 'sub1', 'SConscript'], """
662 conf = env.Configure()
664 SConscript(dirs=['sub2'], exports="env")
666 test.write([work_dir, 'dir2', 'sub1', 'sub2', 'SConscript'], """
668 conf = env.Configure()
671 test.run(chdir=work_dir)
673 # 5.1 test the ConfigureDryRunError
675 reset(EXACT) # exact match
676 test.write([work_dir, 'SConstruct'], """
679 env.AppendENVPath('PATH', os.environ['PATH'])
680 conf = Configure(env)
681 r1 = conf.CheckLib('%s') # will pass
682 r2 = conf.CheckLib('hopefullynolib') # will fail
684 if not (r1 and not r2):
688 test.run(chdir=work_dir, arguments='-n', status=2, stderr="""
689 scons: *** Cannot create configure directory ".sconf_temp" within a dry-run.
690 File "SConstruct", line 5, in ?
692 test.must_not_exist([work_dir, 'config.log'])
693 test.subdir([work_dir, '.sconf_temp'])
695 test.run(chdir=work_dir, arguments='-n', status=2, stderr="""
696 scons: *** Cannot update configure test "%s" within a dry-run.
697 File "SConstruct", line 6, in ?
698 """ % os.path.join(".sconf_temp", "conftest_0.c"))
700 test.run(chdir=work_dir)
701 checkLogAndStdout( ["Checking for main() in C library %s... " % lib,
702 "Checking for main() in C library hopefullynolib... "],
704 [[((".c", NCR), (_obj, NCR))],
705 [((".c", NCR), (_obj, NCF))]],
706 test, "config.log", ".sconf_temp", "SConstruct")
707 oldLog = test.read(test.workpath(work_dir, 'config.log'))
709 test.run(chdir=work_dir, arguments='-n')
710 checkLogAndStdout( ["Checking for main() in C library %s... " % lib,
711 "Checking for main() in C library hopefullynolib... "],
713 [[((".c", CR), (_obj, CR))],
714 [((".c", CR), (_obj, CF))]],
715 test, "config.log", ".sconf_temp", "SConstruct",
717 newLog = test.read(test.workpath(work_dir, 'config.log'))
719 print "Unexpected update of log file within a dry run"
722 # 5.2 test the --config=<auto|force|cache> option
723 reset(EXACT) # exact match
725 test.write([work_dir, 'SConstruct'], """
726 env = Environment(CPPPATH='#/include')
728 env.AppendENVPath('PATH', os.environ['PATH'])
729 conf = Configure(env)
730 r1 = conf.CheckCHeader('non_system_header1.h')
731 r2 = conf.CheckCHeader('non_system_header2.h')
734 test.subdir([work_dir, 'include'])
735 test.write([work_dir, 'include', 'non_system_header1.h'], """
739 test.run(chdir=work_dir, arguments='--config=cache', status=2, stderr="""
740 scons: *** "%s" is not yet built and cache is forced.
741 File "SConstruct", line 6, in ?
742 """ % os.path.join(".sconf_temp", "conftest_0.c"))
744 test.run(chdir=work_dir, arguments='--config=auto')
745 checkLogAndStdout( ["Checking for C header file non_system_header1.h... ",
746 "Checking for C header file non_system_header2.h... "],
748 [[((".c", NCR), (_obj, NCR))],
749 [((".c", NCR), (_obj, NCF))]],
750 test, "config.log", ".sconf_temp", "SConstruct")
751 test.run(chdir=work_dir, arguments='--config=auto')
752 checkLogAndStdout( ["Checking for C header file non_system_header1.h... ",
753 "Checking for C header file non_system_header2.h... "],
755 [[((".c", CR), (_obj, CR))],
756 [((".c", CR), (_obj, CF))]],
757 test, "config.log", ".sconf_temp", "SConstruct")
759 test.run(chdir=work_dir, arguments='--config=force')
760 checkLogAndStdout( ["Checking for C header file non_system_header1.h... ",
761 "Checking for C header file non_system_header2.h... "],
763 [[((".c", NCR), (_obj, NCR))],
764 [((".c", NCR), (_obj, NCF))]],
765 test, "config.log", ".sconf_temp", "SConstruct")
767 test.run(chdir=work_dir, arguments='--config=cache')
768 checkLogAndStdout( ["Checking for C header file non_system_header1.h... ",
769 "Checking for C header file non_system_header2.h... "],
771 [[((".c", CR), (_obj, CR))],
772 [((".c", CR), (_obj, CF))]],
773 test, "config.log", ".sconf_temp", "SConstruct")
775 test.write([work_dir, 'include', 'non_system_header2.h'], """
778 test.unlink([work_dir, 'include', 'non_system_header1.h'])
779 test.run(chdir=work_dir, arguments='--config=cache')
780 checkLogAndStdout( ["Checking for C header file non_system_header1.h... ",
781 "Checking for C header file non_system_header2.h... "],
783 [[((".c", CR), (_obj, CR))],
784 [((".c", CR), (_obj, CF))]],
785 test, "config.log", ".sconf_temp", "SConstruct")
787 test.run(chdir=work_dir, arguments='--config=auto')
788 checkLogAndStdout( ["Checking for C header file non_system_header1.h... ",
789 "Checking for C header file non_system_header2.h... "],
791 [[((".c", CR), (_obj, NCF))],
792 [((".c", CR), (_obj, NCR))]],
793 test, "config.log", ".sconf_temp", "SConstruct")
797 test.write([work_dir, 'SConstruct'], """
800 env.AppendENVPath('PATH', os.environ['PATH'])
801 conf = Configure(env)
802 r1 = conf.CheckCHeader('stdio.h')
805 test.run(chdir=work_dir, arguments='-Q',
806 stdout="scons: `.' is up to date.\n", stderr="")
809 # 6. check config.h support
811 test.write([work_dir, 'SConstruct'], """
814 env.AppendENVPath('PATH', os.environ['PATH'])
815 conf = Configure(env, config_h = 'config.h')
816 r1 = conf.CheckFunc('printf')
817 r2 = conf.CheckFunc('noFunctionCall')
818 r3 = conf.CheckType('int')
819 r4 = conf.CheckType('noType')
820 r5 = conf.CheckCHeader('stdio.h', '<>')
821 r6 = conf.CheckCHeader('hopefullynoc-header.h')
822 r7 = conf.CheckCXXHeader('vector', '<>')
823 r8 = conf.CheckCXXHeader('hopefullynocxx-header.h')
825 conf = Configure(env, config_h = 'config.h')
826 r9 = conf.CheckLib('%s', 'sin')
827 r10 = conf.CheckLib('hopefullynolib', 'sin')
828 r11 = conf.CheckLibWithHeader('%s', 'math.h', 'c')
829 r12 = conf.CheckLibWithHeader('%s', 'hopefullynoheader2.h', 'c')
830 r13 = conf.CheckLibWithHeader('hopefullynolib2', 'math.h', 'c')
832 """ % (lib, lib, lib))
834 expected_read_str = """\
835 Checking for C function printf()... yes
836 Checking for C function noFunctionCall()... no
837 Checking for C type int... yes
838 Checking for C type noType... no
839 Checking for C header file stdio.h... yes
840 Checking for C header file hopefullynoc-header.h... no
841 Checking for C++ header file vector... yes
842 Checking for C++ header file hopefullynocxx-header.h... no
843 Checking for sin() in C library %(lib)s... yes
844 Checking for sin() in C library hopefullynolib... no
845 Checking for main() in C library %(lib)s... yes
846 Checking for main() in C library %(lib)s... no
847 Checking for main() in C library hopefullynolib2... no
850 expected_build_str = """\
851 scons: Configure: creating config.h
854 expected_stdout = test.wrap_stdout(build_str=expected_build_str,
855 read_str=expected_read_str)
857 expected_config_h = string.replace("""#ifndef CONFIG_H_SEEN
858 #define CONFIG_H_SEEN
861 /* #undef HAVE_NOFUNCTIONCALL */
863 /* #undef HAVE_NOTYPE */
865 /* #undef HAVE_HOPEFULLYNOC_HEADER_H */
867 /* #undef HAVE_HOPEFULLYNOCXX_HEADER_H */
869 /* #undef HAVE_LIBHOPEFULLYNOLIB */
871 /* #undef HAVE_%(LIB)s */
872 /* #undef HAVE_LIBHOPEFULLYNOLIB2 */
874 #endif /* CONFIG_H_SEEN */
875 """ % {'LIB' : "LIB" + string.upper(lib) }, "\n", os.linesep)
877 test.run(chdir=work_dir, stdout=expected_stdout)
878 config_h = test.read(test.workpath(work_dir, 'config.h'))
879 if expected_config_h != config_h:
880 print "Unexpected config.h"
882 print "---------------------------------------------------------"
883 print repr(expected_config_h)
884 print "---------------------------------------------------------"
886 print "---------------------------------------------------------"
888 print "---------------------------------------------------------"
890 print "---------------------------------------------------------"
892 print "---------------------------------------------------------"
895 expected_read_str = re.sub(r'\b((yes)|(no))\b',
898 expected_build_str = "scons: `.' is up to date.\n"
899 expected_stdout = test.wrap_stdout(build_str=expected_build_str,
900 read_str=expected_read_str)
901 #expected_stdout = string.replace(expected_stdout, "\n", os.linesep)
902 test.run(chdir=work_dir, stdout=expected_stdout)
903 config_h = test.read(test.workpath(work_dir, 'config.h'))
904 if expected_config_h != config_h:
905 print "Unexpected config.h"
907 print "---------------------------------------------------------"
908 print repr(expected_config_h)
909 print "---------------------------------------------------------"
911 print "---------------------------------------------------------"
913 print "---------------------------------------------------------"
915 print "---------------------------------------------------------"
917 print "---------------------------------------------------------"
922 #os.system( 'find . -type f -exec ls -l {} \;' )
923 #print "-------------config.log------------------"
924 #print test.read( test.workpath(work_dir, 'config.log'))
925 #print "-------------build/config.log------------"
926 #print test.read( test.workpath('build/config.log' ))