import string
import sys
import traceback
-from types import *
+import types
import SCons.Action
import SCons.Builder
return (target[0].get_path() + ' <- \n |' +
string.replace( env['SCONF_TEXT'], "\n", "\n |" ) )
+BooleanTypes = [types.IntType]
+if hasattr(types, 'BooleanType'): BooleanTypes.append(types.BooleanType)
class SConf:
"""This is simply a class to represent a configure context. After
Note also the conf_dir and log_file arguments (you may want to
build tests in the BuildDir, not in the SourceDir)
"""
+ import SCons.Script.SConscript
+ if not SCons.Script.SConscript.sconscript_reading:
+ raise SCons.Errors.UserError, "Calling Configure from Builders is not supported."
global SConfFS
if not SConfFS:
SConfFS = SCons.Node.FS.FS(SCons.Node.FS.default_fs.pathTop)
suff = self.env.subst( builder.builder.suffix )
target = self.confdir.File(pref + f + suff)
self.env['SCONF_TEXT'] = text
+ self.env['PIPE_BUILD'] = 1
+ self.env['PSTDOUT'] = self.logstream
+ self.env['PSTDERR'] = self.logstream
if text != None:
source = self.confdir.File(f + extension)
sourceNode = self.env.SConfSourceBuilder(target=source,
nodesToBeBuilt.extend(nodes)
ret = self.BuildNodes(nodesToBeBuilt)
+ # clean up environment
+ del self.env['PIPE_BUILD']
+ del self.env['PSTDOUT']
+ del self.env['PSTDERR']
del self.env['SCONF_TEXT']
_ac_build_counter = _ac_build_counter + 1
# the build system not to override it with a eventually
# existing file with the same name in the source directory
self.logfile.dir.add_ignore( [self.logfile] )
- self.env['PIPE_BUILD'] = 1
- self.env['PSTDOUT'] = self.logstream
- self.env['PSTDERR'] = self.logstream
tb = traceback.extract_stack()[-3]
if self.logstream != None:
self.logstream.close()
self.logstream = None
- # clean up environment
- del self.env['PIPE_BUILD']
- del self.env['PSTDOUT']
- del self.env['PSTDERR']
# remove the SConfSourceBuilder from the environment
blds = self.env['BUILDERS']
del blds['SConfSourceBuilder']
'failed'.
The result is only displayed when self.did_show_result is not set.
"""
- if type(res) == IntType:
+ if type(res) in BooleanTypes:
if res:
text = "ok"
else:
text = "failed"
- elif type(res) == StringType:
+ elif type(res) == types.StringType:
text = res
else:
- raise TypeError, "Expected string or int"
+ raise TypeError, "Expected string, int or bool, got " + str(type(res))
if self.did_show_result == 0:
if self.cached:
def BuildProg(self, text, ext):
# TODO: should use self.vardict for $CC, $CPPFLAGS, etc.
res = self.TryBuild(self.env.Program, text, ext)
- if type(res) == IntType:
+ if type(res) in BooleanTypes:
if res:
ret = ""
else:
ret = "failed to build test program"
- elif type(res) == StringType:
+ elif type(res) == types.StringType:
ret = res
else:
raise TypeError, "Expected string or int"
def CompileProg(self, text, ext):
# TODO: should use self.vardict for $CC, $CPPFLAGS, etc.
res = self.TryBuild(self.env.Object, text, ext)
- if type(res) == IntType:
+ if type(res) in BooleanTypes:
if res:
ret = ""
else:
ret = "failed to compile test program"
- elif type(res) == StringType:
+ elif type(res) == types.StringType:
ret = res
else:
raise TypeError, "Expected string or int"
# to use cygwin compilers on cmd.exe -> uncomment following line
#lib = 'm'
-oldPwd = os.getcwd()
+work_cnt = 0
+work_dir = None
python = TestSCons.python
-test = None
-
-def reset(dot = 1):
- global test, oldPwd
- os.chdir( oldPwd )
- TestSCons.scons = None
- test = TestSCons.TestSCons()
- if dot == 1:
+test = TestSCons.TestSCons()
+
+
+def reset(match = 1):
+ global test, work_dir, work_cnt
+ work_cnt = work_cnt + 1
+ work_dir='test%d' % work_cnt
+ test.subdir(work_dir)
+ if match == 0:
+ test.match_func = TestCmd.match_re
+ elif match == 1:
test.match_func = TestCmd.match_re_dotall
-
+ elif match == 2:
+ test.match_func = TestCmd.match_exact
def checkFiles(test, files):
+ global work_dir
for f in files:
- test.fail_test( not os.path.isfile( test.workpath(f) ) )
+ test.fail_test( not os.path.isfile( test.workpath(work_dir,f) ) )
def checkLog( test, logfile, numUpToDate, numCache ):
- test.fail_test(not os.path.exists(test.workpath(logfile)))
- log = test.read(test.workpath(logfile))
+ test.fail_test(not os.path.exists(test.workpath(work_dir, logfile)))
+ log = test.read(test.workpath(work_dir, logfile))
try:
test.fail_test( len( re.findall( "is up to date", log ) ) != numUpToDate )
test.fail_test( len( re.findall( "\(cached\): Building \S+ failed in a previous run.", log ) ) != numCache )
except:
- print "contents of log ", test.workpath(logfile), "\n", log
+ print "contents of log ", test.workpath(work_dir, logfile), "\n", log
raise
# 1.1 if checks are ok, the cache mechanism should work
- reset(dot=0)
+ reset(match=2)
- test.write( 'SConstruct', """
+ test.write([work_dir, 'SConstruct'], """
env = Environment()
import os
env['ENV']['PATH'] = os.environ['PATH']
""" % (lib, lib))
- test.run(stdout = required_stdout)
+ test.run(chdir=work_dir, stdout = required_stdout)
checkLog(test,'config.log', 0, 0 )
- test.run(stdout = required_stdout)
+ test.run(chdir=work_dir, stdout = required_stdout)
checkLog(test,'config.log',12, 0 )
# 1.2 if checks are not ok, the cache mechanism should work as well
# (via explicit cache)
- reset(dot = 0) # match exactly, "()" is a regexp thing
+ reset(match=2) # match exactly, "()" is a regexp thing
- test.write( 'SConstruct', """
+ test.write([work_dir, 'SConstruct'], """
env = Environment()
import os
env['ENV']['PATH'] = os.environ['PATH']
""")
- test.run(stdout = required_stdout)
+ test.run(chdir=work_dir, stdout = required_stdout)
checkLog(test, 'config.log', 0, 0 )
- test.run(stdout = required_stdout)
+ test.run(chdir=work_dir, stdout = required_stdout)
checkLog(test, 'config.log', 2, 2 )
reset()
- test.write( 'SConstruct', """
+ test.write([work_dir, 'SConstruct'], """
env = Environment()
import os
env['ENV']['PATH'] = os.environ['PATH']
Export( 'env' )
SConscript( 'SConscript' )
""")
- test.write( 'SConscript', """
+ test.write([work_dir, 'SConscript'], """
Import( 'env' )
env.Program( 'TestProgram', 'TestProgram.c' )
""")
- test.write( 'TestProgram.c', """
+ test.write([work_dir, 'TestProgram.c'], """
#include <stdio.h>
int main() {
"""Checking for C header file math.h... yes
Checking for C header file no_std_c_header.h... no
""")
- test.run( stdout = required_stdout )
+ test.run(chdir=work_dir, stdout = required_stdout )
checkLog( test, 'config.log', 0, 0 )
- test.run( stdout = required_stdout )
+ test.run(chdir=work_dir, stdout = required_stdout )
checkLog( test, 'config.log', 3, 1 )
reset()
- test.write( 'SConstruct', """
+ test.write([work_dir, 'SConstruct'], """
env = Environment(LOGFILE='build/config.log')
import os
env['ENV']['PATH'] = os.environ['PATH']
# print open( 'build/config.log' ).readlines()
SConscript( 'build/SConscript' )
""")
- test.write( 'SConscript', """
+ test.write([work_dir, 'SConscript'], """
Import( 'env' )
env.Program( 'TestProgram', 'TestProgram.c' )
""")
- test.write( 'TestProgram.c', """
+ test.write([work_dir, 'TestProgram.c'], """
#include <stdio.h>
int main() {
"""Checking for C header file math.h... yes
Checking for C header file no_std_c_header.h... no
""")
- test.run( stdout = required_stdout )
+ test.run(chdir=work_dir, stdout = required_stdout )
checkLog( test, 'build/config.log', 0, 0 )
- test.run( stdout = required_stdout )
+ test.run(chdir=work_dir, stdout = required_stdout )
checkLog( test, 'build/config.log', 3, 1 )
# 2.3 test that Configure calls in SConscript files work
# even if BuildDir is set
reset()
- test.subdir( 'sub', ['sub', 'local'] )
- test.write( 'SConstruct', """
+ test.subdir( [work_dir, 'sub'], [work_dir, 'sub', 'local'] )
+ test.write([work_dir, 'SConstruct'], """
opts = Options()
opts.Add('chdir')
env = Environment(options=opts)
BuildDir( 'build', '.' )
SConscript( 'build/SConscript' )
""")
- test.write( 'sub/local/local_header.h', "/* Hello World */" )
- test.write( 'SConscript', """
+ test.write([work_dir, 'sub', 'local', 'local_header.h'],
+ "/* Hello World */" )
+ test.write([work_dir, 'SConscript'], """
SConscript( 'sub/SConscript' )
""")
- test.write( 'sub/SConscript', """
+ test.write([work_dir, 'sub', 'SConscript'], """
def CustomTest(context):
context.Message('Executing Custom Test ... ')
ret = context.TryCompile('#include "local_header.h"', '.c')
env = conf.Finish()
env.Program( 'TestProgram', 'TestProgram.c' )
""")
- test.write( 'sub/TestProgram.h', """
+ test.write([work_dir, 'sub', 'TestProgram.h'], """
/* Just a test header */
""")
- test.write( 'sub/TestProgram.c', """
+ test.write([work_dir, 'sub', 'TestProgram.c'], """
#include "TestProgram.h"
#include <stdio.h>
Executing Custom Test ... ok
""")
# first with SConscriptChdir(0)
- test.run(stdout = required_stdout, arguments='chdir=no')
+ test.run(chdir=work_dir, stdout = required_stdout, arguments='chdir=no')
checkFiles( test, [".sconf_temp/.cache", "config.log"] )
checkLog( test, 'config.log', 0, 0 )
- test.run(stdout = required_stdout, arguments='chdir=no')
+ test.run(chdir=work_dir, stdout = required_stdout, arguments='chdir=no')
checkFiles( test, [".sconf_temp/.cache", "config.log"] )
checkLog( test, 'config.log', 5, 1 )
- shutil.rmtree(test.workpath(".sconf_temp"))
+ shutil.rmtree(test.workpath(work_dir, ".sconf_temp"))
# now with SConscriptChdir(1)
- test.run(stdout = required_stdout, arguments='chdir=yes')
+ test.run(chdir=work_dir, stdout = required_stdout, arguments='chdir=yes')
checkFiles( test, [".sconf_temp/.cache", "config.log"] )
checkLog( test, 'config.log', 0, 0 )
- test.run(stdout = required_stdout, arguments='chdir=yes')
+ test.run(chdir=work_dir, stdout = required_stdout, arguments='chdir=yes')
checkFiles( test, [".sconf_temp/.cache", "config.log"] )
checkLog( test, 'config.log', 5, 1 )
linkFAIL = "void myFunc(); int main() { myFunc(); }"
runOK = compileOK
runFAIL = "int main() { return 1; }"
- test.write('pyAct.py', 'import sys\nprint sys.argv[1]\nsys.exit(int(sys.argv[1]))\n')
- test.write('SConstruct', """
+ test.write([work_dir, 'pyAct.py'], 'import sys\nprint sys.argv[1]\nsys.exit(int(sys.argv[1]))\n')
+ test.write([work_dir, 'SConstruct'], """
def CheckCustom(test):
test.Message( 'Executing MyTest ... ' )
retCompileOK = test.TryCompile( '%s', '.c' )
python, python ) )
required_stdout = test.wrap_stdout(build_str='.*',
read_str="Executing MyTest ... ok\n")
- test.run(stdout = required_stdout)
+ test.run(chdir=work_dir, stdout = required_stdout)
checkLog( test, 'config.log', 0, 0 )
- test.run(stdout = required_stdout)
+ test.run(chdir=work_dir, stdout = required_stdout)
checkLog( test, 'config.log', 12, 4 )
+ # 4.1 test that calling normal builders from an actual configuring
+ # environment works
+ reset()
+
+ test.write([work_dir, 'cmd.py'], r"""
+import sys
+sys.stderr.write( 'Hello World on stderr\n' )
+sys.stdout.write( 'Hello World on stdout\n' )
+open(sys.argv[1], 'w').write( 'Hello World\n' )
+""")
+
+ test.write([work_dir, 'SConstruct'], """
+env = Environment()
+def CustomTest(*args):
+ return 0
+conf = env.Configure(custom_tests = {'MyTest' : CustomTest})
+if not conf.MyTest():
+ env.Command("hello", [], "%s cmd.py $TARGET")
+env = conf.Finish()
+""" % python)
+ test.run(chdir=work_dir, stderr="Hello World on stderr\n")
+
+ # 4.2 test that calling Configure from a builder results in a
+ # readable Error
+ reset(match=2)
+
+ test.write([work_dir, 'SConstruct'], """
+def ConfigureAction(target, source, env):
+ env.Configure()
+ return 0
+env = Environment(BUILDERS = {'MyAction' :
+ Builder(action=Action(ConfigureAction))})
+env.MyAction('target', [])
+""")
+ test.run(chdir=work_dir, status=2,
+ stderr="scons: *** Calling Configure from Builders is not supported.\n")
+
test.pass_test()
finally: