aecp rpm/scons.spec.in
vi rpm/scons.spec.in
- aecp src/test_setup.py
- vi src/test_setup.py
+ aecp QMTest/TestSCons.py
+ vi QMTest/TestSCons.py
# Read through and update the README files if necessary
[optional] aecp README
aecp src/setup.py
vi src/setup.py
- aecp src/test_setup.py
- vi src/test_setup.py
+ aecp QMTest/TestSCons.py
+ vi QMTest/TestSCons.py
# Read through and update the README files if necessary
[optional] aecp README
__all__.extend([ 'TestRuntest',
'python',
+ '_python_',
])
python = python_executable
+_python_ = '"' + python_executable + '"'
failing_test_template = """\
sys.exit(0)
"""
+fake_scons_py = """
+__version__ = '1.2.3'
+__build__ = 'D123'
+__buildsys__ = 'fake_system'
+__date__ = 'Jan 1 1970'
+__developer__ = 'Anonymous'
+"""
+
+fake___init___py = """
+__version__ = '4.5.6'
+__build__ = 'D456'
+__buildsys__ = 'another_fake_system'
+__date__ = 'Dec 31 1999'
+__developer__ = 'John Doe'
+"""
+
class TestRuntest(TestCommon):
"""Class for testing the runtest.py script.
kw['match'] = match_exact
if not kw.has_key('workdir'):
kw['workdir'] = ''
+
+ try:
+ noqmtest = kw['noqmtest']
+ except KeyError:
+ noqmtest = 0
+ else:
+ del kw['noqmtest']
+
orig_cwd = os.getcwd()
apply(TestCommon.__init__, [self], kw)
+
+ if not noqmtest:
+ qmtest_py = self.where_is('qmtest.py')
+ if not qmtest_py:
+ self.skip_test("Could not find 'qmtest.py'; skipping test(s).\n")
things_to_copy = [
'runtest.py',
'QMTest',
]
- dirs = [orig_cwd]
+ dirs = [os.environ.get('SCONS_RUNTEST_DIR', orig_cwd)]
spe = os.environ.get('SCONS_SOURCE_PATH_EXECUTABLE', orig_cwd)
for d in string.split(spe, os.pathsep):
os.environ['PYTHONPATH'] = ''
os.environ['SCONS_SOURCE_PATH_EXECUTABLE'] = ''
+ def skip_test(self, message="Skipping test.\n"):
+ """Skips a test.
+
+ Proper test-skipping behavior is dependent on whether we're being
+ executed as part of development of a change under Aegis.
+
+ Technically, skipping a test is a NO RESULT, but Aegis will
+ treat that as a test failure and prevent the change from going
+ to the next step. We don't want to force anyone using Aegis
+ to have to install absolutely every tool used by the tests,
+ so we actually report to Aegis that a skipped test has PASSED
+ so that the workflow isn't held up.
+ """
+ if message:
+ sys.stdout.write(message)
+ sys.stdout.flush()
+ devdir = os.popen("aesub '$dd' 2>/dev/null", "r").read()[:-1]
+ intdir = os.popen("aesub '$intd' 2>/dev/null", "r").read()[:-1]
+ if devdir and self._cwd[:len(devdir)] == devdir or \
+ intdir and self._cwd[:len(intdir)] == intdir:
+ # We're under the development directory for this change,
+ # so this is an Aegis invocation; pass the test (exit 0).
+ self.pass_test()
+ else:
+ # skip=1 means skip this function when showing where this
+ # result came from. They only care about the line where the
+ # script called test.skip_test(), not the line number where
+ # we call test.no_result().
+ self.no_result(skip=1)
+
+ def write_fake_scons_source_tree(self):
+ os.mkdir('src')
+ os.mkdir('src/script')
+ self.write('src/script/scons.py', fake_scons_py)
+
+ os.mkdir('src/engine')
+ os.mkdir('src/engine/SCons')
+ self.write('src/engine/SCons/__init__.py', fake___init___py)
+ os.mkdir('src/engine/SCons/Script')
+ self.write('src/engine/SCons/Script/__init__.py', fake___init___py)
+
def write_failing_test(self, name):
self.write(name, failing_test_template)
from TestCommon import *
from TestCommon import __all__
+# Some tests which verify that SCons has been packaged properly need to
+# look for specific version file names. Replicating the version number
+# here provides independent verification that what we packaged conforms
+# to what we expect. (If we derived the version number from the same
+# data driving the build we might miss errors if the logic breaks.)
+
+SConsVersion = '0.96.92'
+
__all__.extend([ 'TestSCons',
'python',
'_exe',
])
python = python_executable
+_python_ = '"' + python_executable + '"'
_exe = exe_suffix
_obj = obj_suffix
_shobj = shobj_suffix
initializations.
"""
+ scons_version = SConsVersion
+
def __init__(self, **kw):
"""Initialize an SCons testing object.
}
""")
- self.write(['qt', 'lib', 'SConstruct'], r"""
+ self.write([dir, 'lib', 'SConstruct'], r"""
env = Environment()
-env.StaticLibrary( 'myqt', 'my_qobject.cpp' )
+env.SharedLibrary( 'myqt', 'my_qobject.cpp' )
""")
- self.run(chdir = self.workpath('qt', 'lib'),
+ self.run(chdir = self.workpath(dir, 'lib'),
arguments = '.',
stderr = noisy_ar,
match = self.match_re_dotall)
self.QT_LIB = 'myqt'
self.QT_MOC = '%s %s' % (python, self.workpath(dir, 'bin', 'mymoc.py'))
self.QT_UIC = '%s %s' % (python, self.workpath(dir, 'bin', 'myuic.py'))
+ self.QT_LIB_DIR = self.workpath(dir, 'lib')
def Qt_create_SConstruct(self, place):
if type(place) is type([]):
<class kind="result_stream" name="scons_tdb.AegisChangeStream"/>
<class kind="result_stream" name="scons_tdb.AegisBaselineStream"/>
<class kind="result_stream" name="scons_tdb.AegisBatchStream"/>
+ <class kind="result_stream" name="scons_tdb.SConsXMLResultStream"/>
</class-directory>
from qm.test.result import Result
from qm.test.file_result_stream import FileResultStream
from qm.test.classes.text_result_stream import TextResultStream
+from qm.test.classes.xml_result_stream import XMLResultStream
from qm.test.directory_suite import DirectorySuite
from qm.extension import get_extension_class_name, get_class_arguments_as_dictionary
-import os, dircache
+
+import dircache
+import os
+import imp
if sys.platform == 'win32':
console = 'con'
return True
-# XXX I'd like to annotate the overall test run with the following
-# information about the Python version, SCons version, and environment.
-# Not sure how to do that yet; ask Stefan.
-#
-# sys_keys = ['byteorder', 'exec_prefix', 'executable', 'maxint', 'maxunicode', 'platform', 'prefix', 'version', 'version_info']
-
-# " <%s>" % tag
-# " <version>%s</version>" % module.__version__
-# " <build>%s</build>" % module.__build__
-# " <buildsys>%s</buildsys>" % module.__buildsys__
-# " <date>%s</date>" % module.__date__
-# " <developer>%s</developer>" % module.__developer__
-# " </%s>" % tag
-
-# " <scons>"
-# print_version_info("script", scons)
-# print_version_info("engine", SCons)
-# " </scons>"
-
-# environ_keys = [
-# 'PATH',
-# 'SCONSFLAGS',
-# 'SCONS_LIB_DIR',
-# 'PYTHON_ROOT',
-# 'QTDIR',
-#
-# 'COMSPEC',
-# 'INTEL_LICENSE_FILE',
-# 'INCLUDE',
-# 'LIB',
-# 'MSDEVDIR',
-# 'OS',
-# 'PATHEXT',
-# 'SYSTEMROOT',
-# 'TEMP',
-# 'TMP',
-# 'USERNAME',
-# 'VXDOMNTOOLS',
-# 'WINDIR',
-# 'XYZZY'
-#
-# 'ENV',
-# 'HOME',
-# 'LANG',
-# 'LANGUAGE',
-# 'LOGNAME',
-# 'MACHINE',
-# 'OLDPWD',
-# 'PWD',
-# 'OPSYS',
-# 'SHELL',
-# 'TMPDIR',
-# 'USER',
-# ]
+
+
+class Null:
+ pass
+
+_null = Null()
+
+sys_attributes = [
+ 'byteorder',
+ 'exec_prefix',
+ 'executable',
+ 'maxint',
+ 'maxunicode',
+ 'platform',
+ 'prefix',
+ 'version',
+ 'version_info',
+]
+
+def get_sys_values():
+ sys_attributes.sort()
+ result = map(lambda k: (k, getattr(sys, k, _null)), sys_attributes)
+ result = filter(lambda t: not t[1] is _null, result)
+ result = map(lambda t: t[0] + '=' + repr(t[1]), result)
+ return string.join(result, '\n ')
+
+module_attributes = [
+ '__version__',
+ '__build__',
+ '__buildsys__',
+ '__date__',
+ '__developer__',
+]
+
+def get_module_info(module):
+ module_attributes.sort()
+ result = map(lambda k: (k, getattr(module, k, _null)), module_attributes)
+ result = filter(lambda t: not t[1] is _null, result)
+ result = map(lambda t: t[0] + '=' + repr(t[1]), result)
+ return string.join(result, '\n ')
+
+environ_keys = [
+ 'PATH',
+ 'SCONS',
+ 'SCONSFLAGS',
+ 'SCONS_LIB_DIR',
+ 'PYTHON_ROOT',
+ 'QTDIR',
+
+ 'COMSPEC',
+ 'INTEL_LICENSE_FILE',
+ 'INCLUDE',
+ 'LIB',
+ 'MSDEVDIR',
+ 'OS',
+ 'PATHEXT',
+ 'SYSTEMROOT',
+ 'TEMP',
+ 'TMP',
+ 'USERNAME',
+ 'VXDOMNTOOLS',
+ 'WINDIR',
+ 'XYZZY'
+
+ 'ENV',
+ 'HOME',
+ 'LANG',
+ 'LANGUAGE',
+ 'LC_ALL',
+ 'LC_MESSAGES',
+ 'LOGNAME',
+ 'MACHINE',
+ 'OLDPWD',
+ 'PWD',
+ 'OPSYS',
+ 'SHELL',
+ 'TMPDIR',
+ 'USER',
+]
+
+def get_environment():
+ environ_keys.sort()
+ result = map(lambda k: (k, os.environ.get(k, _null)), environ_keys)
+ result = filter(lambda t: not t[1] is _null, result)
+ result = map(lambda t: t[0] + '-' + t[1], result)
+ return string.join(result, '\n ')
+
+class SConsXMLResultStream(XMLResultStream):
+ def __init__(self, *args, **kw):
+ super(SConsXMLResultStream, self).__init__(*args, **kw)
+ def WriteAllAnnotations(self, context):
+ # Load (by hand) the SCons modules we just unwrapped so we can
+ # extract their version information. Note that we have to override
+ # SCons.Script.main() with a do_nothing() function, because loading up
+ # the 'scons' script will actually try to execute SCons...
+
+ src_engine = os.environ.get('SCONS_LIB_DIR')
+ if not src_engine:
+ src_engine = os.path.join('src', 'engine')
+ fp, pname, desc = imp.find_module('SCons', [src_engine])
+ SCons = imp.load_module('SCons', fp, pname, desc)
+
+ # Override SCons.Script.main() with a do-nothing function, because
+ # loading the 'scons' script will actually try to execute SCons...
+
+ src_engine_SCons = os.path.join(src_engine, 'SCons')
+ fp, pname, desc = imp.find_module('Script', [src_engine_SCons])
+ SCons.Script = imp.load_module('Script', fp, pname, desc)
+ def do_nothing():
+ pass
+ SCons.Script.main = do_nothing
+
+ scons_file = os.environ.get('SCONS')
+ if scons_file:
+ src_script, scons_py = os.path.split(scons_file)
+ scons = os.path.splitext(scons_py)[0]
+ else:
+ src_script = os.path.join('src', 'script')
+ scons = 'scons'
+ fp, pname, desc = imp.find_module(scons, [src_script])
+ scons = imp.load_module('scons', fp, pname, desc)
+ fp.close()
+
+ self.WriteAnnotation("scons_test.engine", get_module_info(SCons))
+ self.WriteAnnotation("scons_test.script", get_module_info(scons))
+
+ self.WriteAnnotation("scons_test.sys", get_sys_values())
+ self.WriteAnnotation("scons_test.os.environ", get_environment())
class AegisStream(TextResultStream):
+ arguments = [
+ qm.fields.IntegerField(
+ name = "print_time",
+ title = "print individual test times",
+ description = """
+ """,
+ default_value = 0,
+ ),
+ ]
def __init__(self, *args, **kw):
super(AegisStream, self).__init__(*args, **kw)
self._num_tests = 0
self._DisplayText(result["Test.stderr"])
except KeyError:
pass
- if result["Test.print_time"] != "0":
+ if self.print_time:
start = float(result['qmtest.start_time'])
end = float(result['qmtest.end_time'])
fmt = " Total execution time: %.1f seconds\n\n"
)
class AegisBatchStream(FileResultStream):
- arguments = [
- qm.fields.TextField(
- name = "results_file",
- title = "Aegis Results File",
- description = """
- """,
- verbatim = "true",
- default_value = "aegis-results.txt",
- ),
- ]
def __init__(self, arguments):
- self.filename = arguments['results_file']
super(AegisBatchStream, self).__init__(arguments)
self._outcomes = {}
def WriteResult(self, result):
self._outcomes[test_id] = exit_status
def Summarize(self):
self.file.write('test_result = [\n')
- for file_name, exit_status in self._outcomes.items():
+ file_names = self._outcomes.keys()
+ file_names.sort()
+ for file_name in file_names:
+ exit_status = self._outcomes[file_name]
+ file_name = string.replace(file_name, '\\', '/')
self.file.write(' { file_name = "%s";\n' % file_name)
self.file.write(' exit_status = %s; },\n' % exit_status)
self.file.write('];\n')
and fails otherwise. The program output is logged, but not validated."""
command = RedirectedExecutable()
- args = [context.get('python', 'python'), self.script]
+ args = [context.get('python', sys.executable), self.script]
status = command.Run(args, os.environ)
- result["Test.print_time"] = context.get('print_time', '0')
if not check_exit_status(result, 'Test.', self.script, status):
# In case of failure record exit code, stdout, and stderr.
result.Fail("Non-zero exit_code.")
env.Command(local_targets, build_src_files, commands)
scons_LICENSE = os.path.join(local, 'scons-LICENSE')
- env.SCons_revision(scons_LICENSE, 'LICENSE-local')
- local_targets.append(scons_LICENSE)
+ l = env.SCons_revision(scons_LICENSE, 'LICENSE-local')
+ local_targets.append(l)
+ Local(l)
scons_README = os.path.join(local, 'scons-README')
- env.SCons_revision(scons_README, 'README-local')
- local_targets.append(scons_README)
+ l = env.SCons_revision(scons_README, 'README-local')
+ local_targets.append(l)
+ Local(l)
if gzip:
env.Command(local_tar_gz,
--- /dev/null
+#
+# aegis - project change supervisor
+# Copyright (C) 2004 Peter Miller;
+# All rights reserved.
+#
+# As a specific exception to the GPL, you are allowed to copy
+# this source file into your own project and modify it, without
+# releasing your project under the GPL, unless there is some other
+# file or condition which would require it.
+#
+# MANIFEST: shell script to commit changes to CVS
+#
+# It is assumed that your CVSROOT and CVS_RSH environment variables have
+# already been set appropriately.
+#
+# This script is expected to be run as by integrate_pass_notify_command
+# and as such the baseline has already assumed the shape asked for by
+# the change.
+#
+# integrate_pass_notify_command =
+# "$bin/ae-cvs-ci $project $change";
+#
+# Alternatively, you may wish to tailor this script to the individual
+# needs of your project. Make it a source file, e.g. "etc/ae-cvs-ci.sh"
+# and then use the following:
+#
+# integrate_pass_notify_command =
+# "$sh ${s etc/ae-cvs-ci} $project $change";
+#
+
+USAGE="Usage: $0 <project> <change>"
+
+PRINT="echo"
+EXECUTE="eval"
+
+while getopts "hnq" FLAG
+do
+ case ${FLAG} in
+ h )
+ echo "${USAGE}"
+ exit 0
+ ;;
+ n )
+ EXECUTE=":"
+ ;;
+ q )
+ PRINT=":"
+ ;;
+ * )
+ echo "$0: unknown option ${FLAG}" >&2
+ exit 1
+ ;;
+ esac
+done
+
+shift `expr ${OPTIND} - 1`
+
+case $# in
+2)
+ project=$1
+ change=$2
+ ;;
+*)
+ echo "${USAGE}" 1>&2
+ exit 1
+ ;;
+esac
+
+here=`pwd`
+
+AEGIS_PROJECT=$project
+export AEGIS_PROJECT
+AEGIS_CHANGE=$change
+export AEGIS_CHANGE
+
+module=`echo $project | sed 's|[.].*||'`
+
+baseline=`aegis -cd -bl`
+
+if test X${TMPDIR} = X; then TMPDIR=/var/tmp; fi
+
+TMP=${TMPDIR}/ae-cvs-ci.$$
+mkdir ${TMP}
+cd ${TMP}
+
+PWD=`pwd`
+if test X${PWD} != X${TMP}; then
+ echo "$0: ended up in ${PWD}, not ${TMP}" >&2
+ exit 1
+fi
+
+fail()
+{
+ set +x
+ cd $here
+ rm -rf ${TMP}
+ echo "FAILED" 1>&2
+ exit 1
+}
+trap "fail" 1 2 3 15
+
+Command()
+{
+ ${PRINT} "$*"
+ ${EXECUTE} "$*"
+}
+
+#
+# Create a new CVS work area.
+#
+# Note: this assumes the module is checked-out into a directory of the
+# same name. Is there a way to ask CVS where is is going to put a
+# modules, so we can always get the "cd" right?
+#
+${PRINT} cvs co $module
+${EXECUTE} cvs co $module > LOG 2>&1
+if test $? -ne 0; then cat LOG; fail; fi
+${EXECUTE} cd $module
+
+#
+# Now we need to extract the sources from Aegis and drop them into the
+# CVS work area. There are two ways to do this.
+#
+# The first way is to use the generated tarball.
+# This has the advantage that it has the Makefile.in file in it, and
+# will work immediately.
+#
+# The second way is to use aetar, which will give exact sources, and
+# omit all derived files. This will *not* include the Makefile.in,
+# and so will not be readily compilable.
+#
+# gunzip < $baseline/export/${project}.tar.gz | tardy -rp ${project} | tar xf -
+aetar -send -o - | tar xzf -
+
+#
+# If any new directories have been created we will need to add them
+# to CVS before we can add the new files which we know are in them,
+# or they would not have been created. Do this only if the -n option
+# isn't used, because if it is, we won't have actually checked out the
+# source and we'd erroneously report that all of them need to be added.
+#
+if test "X${EXECUTE}" != "X:"
+then
+ find . \( -name CVS -o -name Attic \) -prune -o -type d -print |
+ xargs --max-args=1 |
+ while read dir
+ do
+ if [ ! -d $dir/CVS ]
+ then
+ Command cvs add $dir
+ fi
+ done
+fi
+
+#
+# Use the Aegis meta-data to perform some CVS commands that CVS can't
+# figure out for itself.
+#
+aegis -l cf -unf | sed 's| -> [0-9][0-9.]*||' |
+while read usage action rev filename
+do
+ if test "x$filename" = "x"
+ then
+ filename="$rev"
+ fi
+ case $action in
+ create)
+ Command cvs add $filename
+ ;;
+ remove)
+ Command rm -f $filename
+ Command cvs remove $filename
+ ;;
+ *)
+ ;;
+ esac
+done
+
+#
+# Now commit all the changes.
+#
+message=`aesub '${version} - ${change description}'`
+Command cvs -q commit -m \"$message\"
+
+#
+# All done. Clean up and go home.
+#
+cd $here
+rm -rf ${TMP}
+exit 0
--- /dev/null
+#
+# aegis - project change supervisor
+# Copyright (C) 2004 Peter Miller;
+# All rights reserved.
+#
+# As a specific exception to the GPL, you are allowed to copy
+# this source file into your own project and modify it, without
+# releasing your project under the GPL, unless there is some other
+# file or condition which would require it.
+#
+# MANIFEST: shell script to commit changes to Subversion
+#
+# This script is expected to be run by the integrate_pass_notify_command
+# and as such the baseline has already assumed the shape asked for by
+# the change.
+#
+# integrate_pass_notify_command =
+# "$bin/ae-svn-ci $project $change http://svn.site.com/svn/trunk --username svn_user";
+#
+# Alternatively, you may wish to tailor this script to the individual
+# needs of your project. Make it a source file, e.g. "etc/ae-svn-ci.sh"
+# and then use the following:
+#
+# integrate_pass_notify_command =
+# "$sh ${s etc/ae-svn-ci} $project $change http://svn.site.com/svn/trunk --username svn_user";
+#
+
+USAGE="Usage: $0 [-hnq] <project> <change> <url> [<co_options>]"
+
+PRINT="echo"
+EXECUTE="eval"
+
+while getopts "hnq" FLAG
+do
+ case ${FLAG} in
+ h )
+ echo "${USAGE}"
+ exit 0
+ ;;
+ n )
+ EXECUTE=":"
+ ;;
+ q )
+ PRINT=":"
+ ;;
+ * )
+ echo "$0: unknown option ${FLAG}" >&2
+ exit 1
+ ;;
+ esac
+done
+
+shift `expr ${OPTIND} - 1`
+
+case $# in
+[012])
+ echo "${USAGE}" 1>&2
+ exit 1
+ ;;
+*)
+ project=$1
+ change=$2
+ svn_url=$3
+ shift 3
+ svn_co_flags=$*
+ ;;
+esac
+
+here=`pwd`
+
+AEGIS_PROJECT=$project
+export AEGIS_PROJECT
+AEGIS_CHANGE=$change
+export AEGIS_CHANGE
+
+module=`echo $project | sed 's|[.].*||'`
+
+baseline=`aegis -cd -bl`
+
+if test X${TMPDIR} = X; then TMPDIR=/var/tmp; fi
+
+TMP=${TMPDIR}/ae-svn-ci.$$
+mkdir ${TMP}
+cd ${TMP}
+
+PWD=`pwd`
+if test X${PWD} != X${TMP}; then
+ echo "$0: ended up in ${PWD}, not ${TMP}" >&2
+ exit 1
+fi
+
+fail()
+{
+ set +x
+ cd $here
+ rm -rf ${TMP}
+ echo "FAILED" 1>&2
+ exit 1
+}
+trap "fail" 1 2 3 15
+
+Command()
+{
+ ${PRINT} "$*"
+ ${EXECUTE} "$*"
+}
+
+#
+# Create a new Subversion work area.
+#
+# Note: this assumes the module is checked-out into a directory of the
+# same name. Is there a way to ask Subversion where it is going to put a
+# module, so we can always get the "cd" right?
+#
+${PRINT} svn co $svn_url $module $svn_co_flags
+${EXECUTE} svn co $svn_url $module $svn_co_flags > LOG 2>&1
+if test $? -ne 0; then cat LOG; fail; fi
+${EXECUTE} cd $module
+
+#
+# Now we need to extract the sources from Aegis and drop them into the
+# Subversion work area. There are two ways to do this.
+#
+# The first way is to use the generated tarball.
+# This has the advantage that it has the Makefile.in file in it, and
+# will work immediately.
+#
+# The second way is to use aetar, which will give exact sources, and
+# omit all derived files. This will *not* include the Makefile.in,
+# and so will not be readily compilable.
+#
+# gunzip < $baseline/export/${project}.tar.gz | tardy -rp ${project} | tar xf -
+aetar -send -o - | tar xzf -
+
+#
+# If any new directories have been created we will need to add them
+# to Subversion before we can add the new files which we know are in them,
+# or they would not have been created. Do this only if the -n option
+# isn't used, because if it is, we won't have actually checked out the
+# source and we'd erroneously report that all of them need to be added.
+#
+if test "X${EXECUTE}" != "X:"
+then
+ find . -name .svn -prune -o -type d -print |
+ xargs --max-args=1 |
+ while read dir
+ do
+ if [ ! -d $dir/.svn ]
+ then
+ Command svn add -N $dir
+ fi
+ done
+fi
+
+#
+# Use the Aegis meta-data to perform some commands that Subversion can't
+# figure out for itself. We use an inline "aer" report script to identify
+# when a remove-create pair are actually due to a move.
+#
+aegis -rpt -nph -f - <<_EOF_ |
+auto cs;
+cs = project[project_name()].state.branch.change[change_number()];
+
+columns({width = 1000;});
+
+auto file, moved;
+for (file in cs.src)
+{
+ if (file.move != "")
+ moved[file.move] = 1;
+}
+
+auto action;
+for (file in cs.src)
+{
+ if (file.action == "remove" && file.move != "")
+ action = "move";
+ else
+ action = file.action;
+ /*
+ * Suppress printing of any files created as the result of a move.
+ * These are printed as the destination when printing the line for
+ * the file that was *removed* as a result of the move.
+ */
+ if (action != "create" || ! moved[file.file_name])
+ print(sprintf("%s %s \\"%s\\" \\"%s\\"", file.usage, action, file.file_name, file.move));
+}
+_EOF_
+while read line
+do
+ eval set -- "$line"
+ usage="$1"
+ action="$2"
+ srcfile="$3"
+ dstfile="$4"
+ case $action in
+ create)
+ Command svn add $srcfile
+ ;;
+ remove)
+ Command rm -f $srcfile
+ Command svn remove $srcfile
+ ;;
+ move)
+ Command mv $dstfile $dstfile.move
+ Command svn move $srcfile $dstfile
+ Command cp $dstfile.move $dstfile
+ Command rm -f $dstfile.move
+ ;;
+ *)
+ ;;
+ esac
+done
+
+#
+# Now commit all the changes.
+#
+message=`aesub '${version} - ${change description}'`
+Command svn commit -m \"$message\"
+
+#
+# All done. Clean up and go home.
+#
+cd $here
+rm -rf ${TMP}
+exit 0
--- /dev/null
+#!/usr/bin/env python
+#
+# Quick script to process the *summary* output from SCons.Debug.caller()
+# and print indented calling trees with call counts.
+#
+# The way to use this is to add something like the following to a function
+# for which you want information about who calls it and how many times:
+#
+# from SCons.Debug import caller
+# caller(0, 1, 2, 3, 4, 5)
+#
+# Each integer represents how many stack frames back SCons will go
+# and capture the calling information, so in the above example it will
+# capture the calls six levels up the stack in a central dictionary.
+#
+# At the end of any run where SCons.Debug.caller() is used, SCons will
+# print a summary of the calls and counts that looks like the following:
+#
+# Callers of Node/__init__.py:629(calc_signature):
+# 1 Node/__init__.py:683(calc_signature)
+# Callers of Node/__init__.py:676(gen_binfo):
+# 6 Node/FS.py:2035(current)
+# 1 Node/__init__.py:722(get_bsig)
+#
+# If you cut-and-paste that summary output and feed it to this script
+# on standard input, it will figure out how these entries hook up and
+# print a calling tree for each one looking something like:
+#
+# Node/__init__.py:676(gen_binfo)
+# Node/FS.py:2035(current) 6
+# Taskmaster.py:253(make_ready_current) 18
+# Script/Main.py:201(make_ready) 18
+#
+# Note that you should *not* look at the call-count numbers in the right
+# hand column as the actual number of times each line *was called by*
+# the function on the next line. Rather, it's the *total* number
+# of times each function was found in the call chain for any of the
+# calls to SCons.Debug.caller(). If you're looking at more than one
+# function at the same time, for example, their counts will intermix.
+# So use this to get a *general* idea of who's calling what, not for
+# fine-grained performance tuning.
+
+import sys
+
+class Entry:
+ def __init__(self, file_line_func):
+ self.file_line_func = file_line_func
+ self.called_by = []
+ self.calls = []
+
+AllCalls = {}
+
+def get_call(flf):
+ try:
+ e = AllCalls[flf]
+ except KeyError:
+ e = AllCalls[flf] = Entry(flf)
+ return e
+
+prefix = 'Callers of '
+
+c = None
+for line in sys.stdin.readlines():
+ if line[0] == '#':
+ pass
+ elif line[:len(prefix)] == prefix:
+ c = get_call(line[len(prefix):-2])
+ else:
+ num_calls, flf = line.strip().split()
+ e = get_call(flf)
+ c.called_by.append((e, num_calls))
+ e.calls.append(c)
+
+stack = []
+
+def print_entry(e, level, calls):
+ print '%-72s%6s' % ((' '*2*level) + e.file_line_func, calls)
+ if e in stack:
+ print (' '*2*(level+1))+'RECURSION'
+ print
+ elif e.called_by:
+ stack.append(e)
+ for c in e.called_by:
+ print_entry(c[0], level+1, c[1])
+ stack.pop()
+ else:
+ print
+
+for e in [ e for e in AllCalls.values() if not e.calls ]:
+ print_entry(e, 0, '')
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
PROG=`basename $0`
-FLAGS="ahnqrstz"
-USAGE="Usage: ${PROG} [-${FLAGS}] change"
+NOARGFLAGS="afhlnqrstz"
+ARGFLAGS="p:"
+ALLFLAGS="${NOARGFLAGS}${ARGFLAGS}"
+USAGE="Usage: ${PROG} [-${NOARGFLAGS}] [-p project] change"
HELP="$USAGE
- -a Update the latest Aegis baseline (aedist) file.
- -h Print this help message and exit.
- -n Don't execute, just echo commands.
- -q Quiet, don't print commands before executing them.
- -r Rsync the Aegis repository to SourceForge.
- -s Update the sourceforge.net CVS repository.
- -t Update the tigris.org CVS repository.
- -z Update the latest .zip file.
+ -a Update the latest Aegis baseline (aedist) file.
+ -f Force update, skipping up-front sanity check.
+ -h Print this help message and exit.
+ -l Update the local CVS repository.
+ -n Don't execute, just echo commands.
+ -p project Set the Aegis project.
+ -q Quiet, don't print commands before executing them.
+ -r Rsync the Aegis repository to SourceForge.
+ -s Update the sourceforge.net CVS repository.
+ -t Update the tigris.org CVS repository.
+ -z Update the latest .tar.gz and .zip files.
"
DO=""
PRINT="echo"
EXECUTE="eval"
+SANITY_CHECK="yes"
-while getopts $FLAGS FLAG; do
- case $FLAG in
- a | r | s | t | z )
- DO="${DO}${FLAG}"
- ;;
- h )
- echo "${HELP}"
- exit 0
- ;;
- n )
- EXECUTE=":"
- ;;
- q )
- PRINT=":"
- ;;
- * )
- echo "${USAGE}" >&2
- exit 1
- ;;
- esac
+while getopts $ALLFLAGS FLAG; do
+ case $FLAG in
+ a | l | r | s | t | z )
+ DO="${DO}${FLAG}"
+ ;;
+ f )
+ SANITY_CHECK="no"
+ ;;
+ h )
+ echo "${HELP}"
+ exit 0
+ ;;
+ n )
+ EXECUTE=":"
+ ;;
+ p )
+ AEGIS_PROJECT="${OPTARG}"
+ ;;
+ q )
+ PRINT=":"
+ ;;
+ * )
+ echo "FLAG = ${FLAG}" >&2
+ echo "${USAGE}" >&2
+ exit 1
+ ;;
+ esac
done
shift `expr ${OPTIND} - 1`
exit 1
fi
+if test "X${AEGIS_PROJECT}" = "X"; then
+ echo "$PROG: No AEGIS_PROJECT set." >&2
+ echo "${USAGE}" >&2
+ exit 1
+fi
+
if test "X$DO" = "X"; then
- DO="arstz"
+ DO="alrstz"
fi
cmd()
CHANGE=$1
+if test "X${SANITY_CHECK}" = "Xyes"; then
+ SCM="cvs"
+ SCMROOT="/home/scons/CVSROOT/scons"
+ DELTA=`aegis -l -ter cd ${CHANGE} | sed -n 's/.*, Delta \([0-9]*\)\./\1/p'`
+ if test "x${DELTA}" = "x"; then
+ echo "${PROG}: Could not find delta for change ${CHANGE}." >&2
+ echo "Has this finished integrating? Change ${CHANGE} not distributed." >&2
+ exit 1
+ fi
+ PREV_DELTA=`expr ${DELTA} - 1`
+ COMMAND="scons-scmcheck -D ${PREV_DELTA} -d q -p ${AEGIS_PROJECT} -s ${SCM} ${SCMROOT}"
+ $PRINT "${COMMAND}"
+ OUTPUT=`${COMMAND}`
+ if test "X${OUTPUT}" != "X"; then
+ echo "${PROG}: ${SCMROOT} is not up to date:" >&2
+ echo "${OUTPUT}" >& 2
+ echo "Did you skip any changes? Change ${CHANGE} not distributed." >&2
+ exit 1
+ fi
+fi
+
if test X$EXECUTE != "X:" -a "X$SSH_AGENT_PID" = "X"; then
eval `ssh-agent`
ssh-add
TMPBLAE="/tmp/${BASELINE}.ae"
TMPCAE="/tmp/${AEGIS_PROJECT}.C${CHANGE}.ae"
-SFLOGIN="stevenknight"
-SFHOST="scons.sourceforge.net"
-SFDEST="/home/groups/s/sc/scons/htdocs"
+# Original values for SourceForge.
+#SFLOGIN="stevenknight"
+#SFHOST="scons.sourceforge.net"
+#SFDEST="/home/groups/s/sc/scons/htdocs"
+
+SCONSLOGIN="scons"
+SCONSHOST="manam.pair.com"
+#SCONSDEST="public_html/production"
+SCONSDEST="public_ftp"
#
# Copy the baseline .ae to the constant location on SourceForge.
#
case "${DO}" in
- *a* )
- cmd "aedist -s -bl -p ${AEGIS_PROJECT} > ${TMPBLAE}"
- cmd "scp ${TMPBLAE} ${SFLOGIN}@${SFHOST}:${SFDEST}/${BASELINE}.ae"
- cmd "rm ${TMPBLAE}"
- ;;
+*a* )
+ cmd "aedist -s -bl -p ${AEGIS_PROJECT} > ${TMPBLAE}"
+ cmd "scp ${TMPBLAE} ${SCONSLOGIN}@${SCONSHOST}:${SCONSDEST}/${BASELINE}.ae"
+ cmd "rm ${TMPBLAE}"
+ ;;
esac
#
-# Copy the latest .zip file to the constant location on SourceForge.
+# Copy the latest .tar.gz and .zip files to the constant location on
+# SourceForge.
#
case "${DO}" in
- *z* )
- BUILD_DIST=`aegis -p ${AEGIS_PROJECT} -cd -bl`/build/dist
- SCONS_SRC=`echo ${AEGIS_PROJECT} | sed 's/scons./scons-src-/'`.zip
- cmd "scp ${BUILD_DIST}/${SCONS_SRC} ${SFLOGIN}@${SFHOST}:${SFDEST}/scons-src-latest.zip"
+*z* )
+ BUILD_DIST=`aegis -p ${AEGIS_PROJECT} -cd -bl`/build/dist
+ SCONS_SRC_TAR_GZ=`echo ${AEGIS_PROJECT} | sed 's/scons./scons-src-/'`*.tar.gz
+ SCONS_SRC_ZIP=`echo ${AEGIS_PROJECT} | sed 's/scons./scons-src-/'`*.zip
+ cmd "scp ${BUILD_DIST}/${SCONS_SRC_TAR_GZ} ${SCONSLOGIN}@${SCONSHOST}:${SCONSDEST}/scons-src-latest.tar.gz"
+ cmd "scp ${BUILD_DIST}/${SCONS_SRC_ZIP} ${SCONSLOGIN}@${SCONSHOST}:${SCONSDEST}/scons-src-latest.zip"
esac
#
# We no longer use the --stats option.
#
case "${DO}" in
- *r* )
- LOCAL=/home/scons/scons
- REMOTE=/home/groups/s/sc/scons/scons
- cmd "/usr/bin/rsync --rsh=ssh -l -p -r -t -z \
- --exclude build \
- --exclude '*,D' \
- --exclude '*.pyc' \
- --exclude aegis.log \
- --exclude '.sconsign*' \
- --delete --delete-excluded \
- --progress -v \
- ${LOCAL}/. scons.sourceforge.net:${REMOTE}/."
- ;;
+*r* )
+ LOCAL=/home/scons/scons
+ REMOTE=/home/groups/s/sc/scons/scons
+ cmd "/usr/bin/rsync --rsh='ssh -l stevenknight' \
+ -l -p -r -t -z \
+ --exclude build \
+ --exclude '*,D' \
+ --exclude '*.pyc' \
+ --exclude aegis.log \
+ --exclude '.sconsign*' \
+ --delete --delete-excluded \
+ --progress -v \
+ ${LOCAL}/. scons.sourceforge.net:${REMOTE}/."
+ ;;
esac
#
-# Sync the CVS tree with Tigris.org.
+# Sync the CVS tree with the local repository.
#
case "${DO}" in
- *t* )
- cmd "ae2cvs -X -aegis -p ${AEGIS_PROJECT} -c ${CHANGE} -u $HOME/SCons/tigris.org/scons"
- ;;
+*l* )
+ (
+ export CVSROOT=/home/scons/CVSROOT/scons
+ #cmd "ae2cvs -X -aegis -p ${AEGIS_PROJECT} -c ${CHANGE} -u $HOME/SCons/baldmt.com/scons"
+ cmd "ae-cvs-ci ${AEGIS_PROJECT} ${CHANGE}"
+ )
+ ;;
+esac
+
+#
+# Sync the Subversion tree with Tigris.org.
+#
+case "${DO}" in
+*t* )
+ (
+ SVN=http://scons.tigris.org/svn/scons
+ case ${AEGIS_PROJECT} in
+ scons.0.96 )
+ SVN_URL=${SVN}/branches/core
+ ;;
+ scons.0.96.513 )
+ SVN_URL=${SVN}/branches/sigrefactor
+ ;;
+ * )
+ echo "$PROG: Don't know SVN branch for '${AEGIS_PROJECT}'" >&2
+ exit 1
+ ;;
+ esac
+ SVN_CO_FLAGS="--username stevenknight"
+ #cmd "ae2cvs -X -aegis -p ${AEGIS_PROJECT} -c ${CHANGE} -u $HOME/SCons/tigris.org/scons"
+ cmd "ae-svn-ci ${AEGIS_PROJECT} ${CHANGE} ${SVN_URL} ${SVN_CO_FLAGS}"
+ )
+ ;;
esac
#
# Sync the CVS tree with SourceForge.
#
case "${DO}" in
- *s* )
+*s* )
+ (
export CVS_RSH=ssh
- cmd "ae2cvs -X -aegis -p ${AEGIS_PROJECT} -c ${CHANGE} -u $HOME/SCons/sourceforge.net/scons"
- ;;
+ export CVSROOT=:ext:stevenknight@scons.cvs.sourceforge.net:/cvsroot/scons
+ #cmd "ae2cvs -X -aegis -p ${AEGIS_PROJECT} -c ${CHANGE} -u $HOME/SCons/sourceforge.net/scons"
+ cmd "ae-cvs-ci ${AEGIS_PROJECT} ${CHANGE}"
+ )
+ ;;
esac
#
#
#aedist -s -p ${AEGIS_PROJECT} ${CHANGE} > ${TMPCAE}
#aegis -l -p ${AEGIS_PROJECT} -c ${CHANGE} cd |
-# pine -attach_and_delete ${TMPCAE} scons-aedist@lists.sourceforge.net
+# pine -attach_and_delete ${TMPCAE} scons-aedist@lists.sourceforge.net
--- /dev/null
+#!/usr/bin/env python
+#
+# scons-diff.py - diff-like utility for comparing SCons trees
+#
+# This supports most common diff options (with some quirks, like you can't
+# just say -c and have it use a default value), but canonicalizes the
+# various version strings within the file like __revision__, __build__,
+# etc. so that you can diff trees without having to ignore changes in
+# version lines.
+#
+
+import difflib
+import getopt
+import os.path
+import re
+import sys
+
+Usage = """\
+Usage: scons-diff.py [OPTIONS] dir1 dir2
+Options:
+ -c NUM, --context=NUM Print NUM lines of copied context.
+ -h, --help Print this message and exit.
+ -n Don't canonicalize SCons lines.
+ -q, --quiet Print only whether files differ.
+ -r, --recursive Recursively compare found subdirectories.
+ -s Report when two files are the same.
+ -u NUM, --unified=NUM Print NUM lines of unified context.
+"""
+
+opts, args = getopt.getopt(sys.argv[1:],
+ 'c:dhnqrsu:',
+ ['context=', 'help', 'recursive', 'unified='])
+
+diff_type = None
+edit_type = None
+context = 2
+recursive = False
+report_same = False
+diff_options = []
+
+def diff_line(left, right):
+ if diff_options:
+ opts = ' ' + ' '.join(diff_options)
+ else:
+ opts = ''
+ print 'diff%s %s %s' % (opts, left, right)
+
+for o, a in opts:
+ if o in ('-c', '-u'):
+ diff_type = o
+ context = int(a)
+ diff_options.append(o)
+ elif o in ('-h', '--help'):
+ print Usage
+ sys.exit(0)
+ elif o in ('-n'):
+ diff_options.append(o)
+ edit_type = o
+ elif o in ('-q'):
+ diff_type = o
+ diff_line = lambda l, r: None
+ elif o in ('-r', '--recursive'):
+ recursive = True
+ diff_options.append(o)
+ elif o in ('-s'):
+ report_same = True
+
+try:
+ left, right = args
+except ValueError:
+ sys.stderr.write(Usage)
+ sys.exit(1)
+
+def quiet_diff(a, b, fromfile='', tofile='',
+ fromfiledate='', tofiledate='', n=3, lineterm='\n'):
+ """
+ A function with the same calling signature as difflib.context_diff
+ (diff -c) and difflib.unified_diff (diff -u) but which prints
+ output like the simple, unadorned 'diff" command.
+ """
+ if a == b:
+ return []
+ else:
+ return ['Files %s and %s differ\n' % (fromfile, tofile)]
+
+def simple_diff(a, b, fromfile='', tofile='',
+ fromfiledate='', tofiledate='', n=3, lineterm='\n'):
+ """
+ A function with the same calling signature as difflib.context_diff
+ (diff -c) and difflib.unified_diff (diff -u) but which prints
+ output like the simple, unadorned 'diff" command.
+ """
+ sm = difflib.SequenceMatcher(None, a, b)
+ def comma(x1, x2):
+ return x1+1 == x2 and str(x2) or '%s,%s' % (x1+1, x2)
+ result = []
+ for op, a1, a2, b1, b2 in sm.get_opcodes():
+ if op == 'delete':
+ result.append("%sd%d\n" % (comma(a1, a2), b1))
+ result.extend(map(lambda l: '< ' + l, a[a1:a2]))
+ elif op == 'insert':
+ result.append("%da%s\n" % (a1, comma(b1, b2)))
+ result.extend(map(lambda l: '> ' + l, b[b1:b2]))
+ elif op == 'replace':
+ result.append("%sc%s\n" % (comma(a1, a2), comma(b1, b2)))
+ result.extend(map(lambda l: '< ' + l, a[a1:a2]))
+ result.append('---\n')
+ result.extend(map(lambda l: '> ' + l, b[b1:b2]))
+ return result
+
+diff_map = {
+ '-c' : difflib.context_diff,
+ '-q' : quiet_diff,
+ '-u' : difflib.unified_diff,
+}
+
+diff_function = diff_map.get(diff_type, simple_diff)
+
+baseline_re = re.compile('(# |@REM )/home/\S+/baseline/')
+comment_rev_re = re.compile('(# |@REM )(\S+) 0.96.[CD]\d+ \S+ \S+( knight)')
+revision_re = re.compile('__revision__ = "[^"]*"')
+build_re = re.compile('__build__ = "[^"]*"')
+date_re = re.compile('__date__ = "[^"]*"')
+
+def lines_read(file):
+ return open(file).readlines()
+
+def lines_massage(file):
+ text = open(file).read()
+ text = baseline_re.sub('\\1', text)
+ text = comment_rev_re.sub('\\1\\2\\3', text)
+ text = revision_re.sub('__revision__ = "__FILE__"', text)
+ text = build_re.sub('__build__ = "0.96.92.DXXX"', text)
+ text = date_re.sub('__date__ = "2006/08/25 02:59:00"', text)
+ return text.splitlines(1)
+
+lines_map = {
+ '-n' : lines_read,
+}
+
+lines_function = lines_map.get(edit_type, lines_massage)
+
+def do_diff(left, right, diff_subdirs):
+ if os.path.isfile(left) and os.path.isfile(right):
+ diff_file(left, right)
+ elif not os.path.isdir(left):
+ diff_file(left, os.path.join(right, os.path.split(left)[1]))
+ elif not os.path.isdir(right):
+ diff_file(os.path.join(left, os.path.split(right)[1]), right)
+ elif diff_subdirs:
+ diff_dir(left, right)
+
+def diff_file(left, right):
+ l = lines_function(left)
+ r = lines_function(right)
+ d = diff_function(l, r, left, right, context)
+ try:
+ text = ''.join(d)
+ except IndexError:
+ sys.stderr.write('IndexError diffing %s and %s\n' % (left, right))
+ else:
+ if text:
+ diff_line(left, right)
+ print text,
+ elif report_same:
+ print 'Files %s and %s are identical' % (left, right)
+
+def diff_dir(left, right):
+ llist = os.listdir(left)
+ rlist = os.listdir(right)
+ u = {}
+ for l in llist:
+ u[l] = 1
+ for r in rlist:
+ u[r] = 1
+ clist = [ x for x in u.keys() if x[-4:] != '.pyc' ]
+ clist.sort()
+ for x in clist:
+ if x in llist:
+ if x in rlist:
+ do_diff(os.path.join(left, x),
+ os.path.join(right, x),
+ recursive)
+ else:
+ print 'Only in %s: %s' % (left, x)
+ else:
+ print 'Only in %s: %s' % (right, x)
+
+do_diff(left, right, True)
*
* Look in aesub(5) for more information about command substitutions.
*/
-build_command = "python1.5 ${Source bootstrap.py} -Y${SUBSTitute : \\ -Y $Search_Path} date='${DAte %Y/%m/%d %H:%M:%S}' developer=${DEVeloper} version=${VERsion} change=${Change}";
+build_command = "python2.1 ${Source bootstrap.py} -Y${SUBSTitute : \\ -Y $Search_Path} date='${DAte %Y/%m/%d %H:%M:%S}' developer=${DEVeloper} version=${VERsion} change=${Change}";
/*
* SCons removes its targets before constructing them, which qualifies it
* is set appropriately during a baseline test. So we just use the
* proper aesub variable to comment out the expanded $spe.
*/
-test_command = "python1.5 ${Source runtest.py Absolute} -p tar-gz -t -v ${SUBSTitute '\\.[CD][0-9]+$' '' ${VERsion}} -q --sp ${Search_Path} --spe ${Search_Path_Executable} ${File_Name}";
+test_command = "python1.5 ${Source runtest.py Absolute} --noqmtest -p tar-gz -t -v ${SUBSTitute '\\.[CD][0-9]+$' '' ${VERsion}} -q --sp ${Search_Path} --spe ${Search_Path_Executable} ${File_Name}";
-batch_test_command = "python1.5 ${Source runtest.py Absolute} -p tar-gz -t -v ${SUBSTitute '\\.[CD][0-9]+$' '' ${VERsion}} -o ${Output} --aegis --sp ${Search_Path} --spe ${Search_Path_Executable} ${File_Names}";
+batch_test_command = "python1.5 ${Source runtest.py Absolute} --noqmtest -p tar-gz -t -v ${SUBSTitute '\\.[CD][0-9]+$' '' ${VERsion}} -o ${Output} --aegis --sp ${Search_Path} --spe ${Search_Path_Executable} ${File_Names}";
new_test_filename = "test/CHANGETHIS.py";
body = "${read_file ${source template/test.py abs}}";
},
];
+
+/*
+ * Command for distributing changes from Aegis to all of the repositories
+ * we want to mirror the information.
+ *
+ * XXX Uncomment after upgrading to an Aegis version that supports this.
+
+integrate_pass_notify_command =
+ "$sh ${s bin/scons-cdist} -p $project $change";
+ *
+ */
variables_gen, variables_mod]
b = env.Command(doc_output_files,
scons_doc_files,
- "python $SCONS_PROC_PY --sgml -b ${TARGETS[0]},${TARGETS[1]} -t ${TARGETS[2]},${TARGETS[3]} -v ${TARGETS[4]},${TARGETS[5]} $( $SOURCES $)")
+ "$PYTHON $SCONS_PROC_PY --sgml -b ${TARGETS[0]},${TARGETS[1]} -t ${TARGETS[2]},${TARGETS[3]} -v ${TARGETS[4]},${TARGETS[5]} $( $SOURCES $)")
env.Depends(b, "$SCONS_PROC_PY")
env.Local(b)
if build_doc and ext == '.sgml':
env.Command(doc_s,
base + '.in',
- "python $SCONSOUTPUT_PY $SOURCE > $TARGET")
+ "$PYTHON $SCONSOUTPUT_PY $SOURCE > $TARGET")
orig_env.SCons_revision(build_s, doc_s)
Local(build_s)
man_intermediate_files = map(lambda x: os.path.join(build, 'man', x),
man_i_files)
-cmd = "python $SCONS_PROC_PY --man -b ${TARGETS[0]} -t ${TARGETS[1]} -v ${TARGETS[2]} $( $SOURCES $)"
+cmd = "$PYTHON $SCONS_PROC_PY --man -b ${TARGETS[0]} -t ${TARGETS[1]} -v ${TARGETS[2]} $( $SOURCES $)"
man_intermediate_files = env.Command(man_intermediate_files,
scons_doc_files,
cmd)
.BR NoClean ()
function.
+.TP
+.RI --cache-debug= file
+Print debug information about the
+.BR CacheDir ()
+derived-file caching
+to the specified
+.IR file .
+If
+.I file
+is
+.B \-
+(a hyphen),
+the debug information are printed to the standard output.
+The printed messages describe what signature file names are
+being looked for in, retrieved from, or written to the
+.BR CacheDir ()
+directory tree.
+
.TP
--cache-disable, --no-cache
Disable the derived-file caching specified by
See the section "Action Objects,"
below, for a complete explanation of the arguments and behavior.
+Note that the
+.BR env.Action ()
+form of the invocation will expand
+construction variables in any arguments strings,
+including the
+.I action
+argument,
+at the time it is called
+using the construction variables in the
+.B env
+construction environment through which
+.BR env.Action ()
+was called.
+The
+.BR Action ()
+form delays all variable expansion
+until the Action object is actually used.
+
'\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
.TP
.RI AddPostAction( target ", " action )
See the section "Builder Objects,"
below, for a complete explanation of the arguments and behavior.
+Note that the
+.BR env.Builder ()
+form of the invocation will expand
+construction variables in any arguments strings,
+including the
+.I action
+argument,
+at the time it is called
+using the construction variables in the
+.B env
+construction environment through which
+.BR env.Builder ()
+was called.
+The
+.BR Builder ()
+form delays all variable expansion
+until after the Builder object is actually called.
+
'\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
.TP
.RI CacheDir( cache_dir )
.RI Install( dir ", " source )
.TP
.RI env.Install( dir ", " source )
-Installs one or more files in a destination directory.
-The file names remain the same.
+Installs one or more source files or directories
+in a destination directory
+.IR dir .
+The names of the specified source files or directories
+remain the same within the destination directory.
.ES
env.Install(dir = '/usr/local/bin', source = ['foo', 'bar'])
.RI InstallAs( target ", " source )
.TP
.RI env.InstallAs( target ", " source )
-Installs one or more files as specific file names,
-allowing changing a file name as part of the
-installation.
-It is an error if the target and source
-list different numbers of files.
+Installs one or more source files or directories
+to specific names,
+allowing changing a file or directory name
+as part of the installation.
+It is an error if the
+.I target
+and
+.I source
+arguments list different numbers of files or directories.
.ES
env.InstallAs(target = '/usr/local/bin/foo',
'\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
.TP
-.RI Value( value )
+.RI Value( value ", [" built_value ])
.TP
-.RI env.Value( value )
+.RI env.Value( value ", [" built_value ])
Returns a Node object representing the specified Python value. Value
-nodes can be used as dependencies of targets. If the result of
+Nodes can be used as dependencies of targets. If the result of
calling
.BR str( value )
changes between SCons runs, any targets depending on
.BR Value( value )
-will be rebuilt. When using timestamp source signatures, Value nodes'
-timestamps are equal to the system time when the node is created.
+will be rebuilt. When using timestamp source signatures, Value Nodes'
+timestamps are equal to the system time when the Node is created.
+
+The returned Value Node object has a
+.BR write ()
+method that can be used to "build" a Value Node
+by setting a new value.
+The optional
+.I built_value
+argument can be specified
+when the Value Node is created
+to indicate the Node should already be considered
+"built."
+There is a corresponding
+.BR read ()
+method that will return the built value of the Node.
.ES
def create(target, source, env):
env = Environment()
env['BUILDERS']['Config'] = Builder(action = create)
env.Config(target = 'package-config', source = Value(prefix))
+
+def build_value(target, source, env):
+ target[0].write(source[0].get_contents())
+
+output = env.Value('before')
+input = env.Value('after')
+
+env['BUILDERS']['UpdateValue'] = Builder(action = build_value)
+env.UpdateValue(target = Value(output), source = Value(input))
.EE
'\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
#!/usr/bin/env python
#
-# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
+# __COPYRIGHT__
#
# runtest.py - wrapper script for running SCons tests
#
import sys
import time
+if not hasattr(os, 'WEXITSTATUS'):
+ os.WEXITSTATUS = lambda x: x
+
all = 0
baseline = 0
debug = ''
execute_tests = 1
format = None
list_only = None
-tests = []
printcommand = 1
package = None
print_passed_summary = None
scons = None
scons_exec = None
outputfile = None
-qmtest = None
testlistfile = None
version = ''
print_times = None
cwd = os.getcwd()
-if sys.platform == 'win32' or os.name == 'java':
- lib_dir = os.path.join(sys.exec_prefix, "Lib")
-else:
- # The hard-coded "python" here is the directory name,
- # not an executable, so it's all right.
- lib_dir = os.path.join(sys.exec_prefix, "lib", "python" + sys.version[0:3])
-
helpstr = """\
Usage: runtest.py [OPTIONS] [TEST ...]
Options:
-h, --help Print this message and exit.
-l, --list List available tests and exit.
-n, --no-exec No execute, just print command lines.
+ --noqmtest Execute tests directly, not using QMTest.
-o FILE, --output FILE Print test results to FILE.
-P Python Use the specified Python interpreter.
-p PACKAGE, --package PACKAGE
opts, args = getopt.getopt(sys.argv[1:], "ab:df:hlno:P:p:qv:Xx:t",
['all', 'aegis', 'baseline=',
'debug', 'file=', 'help',
- 'list', 'no-exec', 'output=',
+ 'list', 'no-exec', 'noqmtest', 'output=',
'package=', 'passed', 'python=',
'qmtest', 'quiet', 'spe=',
'version=', 'exec=', 'time',
elif o in ['-b', '--baseline']:
baseline = a
elif o in ['-d', '--debug']:
- debug = os.path.join(lib_dir, "pdb.py")
+ for dir in sys.path:
+ pdb = os.path.join(dir, 'pdb.py')
+ if os.path.exists(pdb):
+ debug = pdb
+ break
elif o in ['-f', '--file']:
if not os.path.isabs(a):
a = os.path.join(cwd, a)
list_only = 1
elif o in ['-n', '--no-exec']:
execute_tests = None
+ elif o in ['--noqmtest']:
+ qmtest = None
elif o in ['-o', '--output']:
if a != '-' and not os.path.isabs(a):
a = os.path.join(cwd, a)
elif o in ['-P', '--python']:
python = a
elif o in ['--qmtest']:
- qmtest = 1
+ qmtest = 'qmtest.py'
elif o in ['-q', '--quiet']:
printcommand = 0
elif o in ['--sp']:
elif o in ['--aegis', '--xml']:
format = o
+if not args and not all and not testlistfile:
+ sys.stderr.write("""\
+runtest.py: No tests were specified.
+ List one or more tests on the command line, use the
+ -f option to specify a file containing a list of tests,
+ or use the -a option to find and run all tests.
+
+""")
+ sys.exit(1)
+
+
def whereis(file):
for dir in string.split(os.environ['PATH'], os.pathsep):
f = os.path.join(dir, file)
return f
return None
+try:
+ qmtest
+except NameError:
+ q = 'qmtest.py'
+ qmtest = whereis(q)
+ if qmtest:
+ qmtest = q
+ else:
+ sys.stderr.write('Warning: %s not found on $PATH, assuming --noqmtest option.\n' % q)
+
aegis = whereis('aegis')
if format == '--aegis' and aegis:
return status >> 8
else:
def spawn_it(command_args):
+ command = command_args[0]
command_args = map(escape, command_args)
- command_args = map(lambda s: string.replace(s, '\\','\\\\'), command_args)
- return os.spawnv(os.P_WAIT, command_args[0], command_args)
+ return os.spawnv(os.P_WAIT, command, command_args)
class Base:
def __init__(self, path, spe=None):
'--aegis' : Aegis,
'--xml' : XML,
}
-Test = format_class[format]
-
-if qmtest:
- pass
-elif args:
- if spe:
- for a in args:
- if os.path.isabs(a):
- for g in glob.glob(a):
- tests.append(Test(g))
- else:
- for dir in spe:
- x = os.path.join(dir, a)
- globs = glob.glob(x)
- if globs:
- for g in globs:
- tests.append(Test(g))
- break
- else:
- for a in args:
- for g in glob.glob(a):
- tests.append(Test(g))
-elif all:
- # Find all of the SCons functional tests in the local directory
- # tree. This is anything under the 'src' subdirectory that ends
- # with 'Tests.py', or any Python script (*.py) under the 'test'
- # subdirectory.
- #
- # Note that there are some tests under 'src' that *begin* with
- # 'test_', but they're packaging and installation tests, not
- # functional tests, so we don't execute them by default. (They can
- # still be executed by hand, though, and are routinely executed
- # by the Aegis packaging build to make sure that we're building
- # things correctly.)
- tdict = {}
-
- def find_Tests_py(arg, dirname, names, tdict=tdict):
- for n in filter(lambda n: n[-8:] == "Tests.py", names):
- t = os.path.join(dirname, n)
- if not tdict.has_key(t):
- tdict[t] = Test(t)
- os.path.walk('src', find_Tests_py, 0)
-
- def find_py(arg, dirname, names, tdict=tdict):
- for n in filter(lambda n: n[-3:] == ".py", names):
- t = os.path.join(dirname, n)
- if not tdict.has_key(t):
- tdict[t] = Test(t)
- os.path.walk('test', find_py, 0)
-
- if format == '--aegis' and aegis:
- cmd = "aegis -list -unf pf 2>/dev/null"
- for line in os.popen(cmd, "r").readlines():
- a = string.split(line)
- if a[0] == "test" and not tdict.has_key(a[-1]):
- tdict[a[-1]] = Test(a[-1], spe)
- cmd = "aegis -list -unf cf 2>/dev/null"
- for line in os.popen(cmd, "r").readlines():
- a = string.split(line)
- if a[0] == "test":
- if a[1] == "remove":
- del tdict[a[-1]]
- elif not tdict.has_key(a[-1]):
- tdict[a[-1]] = Test(a[-1], spe)
-
- keys = tdict.keys()
- keys.sort()
- tests = map(tdict.get, keys)
-elif testlistfile:
- tests = open(testlistfile, 'r').readlines()
- tests = filter(lambda x: x[0] != '#', tests)
- tests = map(lambda x: x[:-1], tests)
- tests = map(Test, tests)
-else:
- sys.stderr.write("""\
-runtest.py: No tests were specified on the command line.
- List one or more tests, or use the -a option
- to find and run all tests.
-""")
+Test = format_class[format]
if package:
scons_lib_dir = os.path.join(test_dir, dir[package], 'lib', l)
pythonpath_dir = scons_lib_dir
+ scons_runtest_dir = os.path.join(cwd, 'build')
+
else:
sd = None
ld = None
else:
base = baseline
+ scons_runtest_dir = base
+
scons_script_dir = sd or os.path.join(base, 'src', 'script')
scons_lib_dir = ld or os.path.join(base, 'src', 'engine')
if scons_exec:
os.environ['SCONS_EXEC'] = '1'
+os.environ['SCONS_RUNTEST_DIR'] = scons_runtest_dir
os.environ['SCONS_SCRIPT_DIR'] = scons_script_dir
os.environ['SCONS_CWD'] = cwd
os.pathsep + \
old_pythonpath
+tests = []
+
+if args:
+ if spe:
+ for a in args:
+ if os.path.isabs(a):
+ tests.extend(glob.glob(a))
+ else:
+ for dir in spe:
+ x = os.path.join(dir, a)
+ globs = glob.glob(x)
+ if globs:
+ tests.extend(globs)
+ break
+ else:
+ for a in args:
+ tests.extend(glob.glob(a))
+elif testlistfile:
+ tests = open(testlistfile, 'r').readlines()
+ tests = filter(lambda x: x[0] != '#', tests)
+ tests = map(lambda x: x[:-1], tests)
+elif all and not qmtest:
+ # Find all of the SCons functional tests in the local directory
+ # tree. This is anything under the 'src' subdirectory that ends
+ # with 'Tests.py', or any Python script (*.py) under the 'test'
+ # subdirectory.
+ #
+ # Note that there are some tests under 'src' that *begin* with
+ # 'test_', but they're packaging and installation tests, not
+ # functional tests, so we don't execute them by default. (They can
+ # still be executed by hand, though, and are routinely executed
+ # by the Aegis packaging build to make sure that we're building
+ # things correctly.)
+ tdict = {}
+
+ def find_Tests_py(tdict, dirname, names):
+ for n in filter(lambda n: n[-8:] == "Tests.py", names):
+ t = os.path.join(dirname, n)
+ if not tdict.has_key(t):
+ tdict[t] = 1
+ os.path.walk('src', find_Tests_py, tdict)
+
+ def find_py(tdict, dirname, names):
+ for n in filter(lambda n: n[-3:] == ".py", names):
+ t = os.path.join(dirname, n)
+ if not tdict.has_key(t):
+ tdict[t] = 1
+ os.path.walk('test', find_py, tdict)
+
+ if format == '--aegis' and aegis:
+ cmd = "aegis -list -unf pf 2>/dev/null"
+ for line in os.popen(cmd, "r").readlines():
+ a = string.split(line)
+ if a[0] == "test" and not tdict.has_key(a[-1]):
+ tdict[a[-1]] = Test(a[-1], spe)
+ cmd = "aegis -list -unf cf 2>/dev/null"
+ for line in os.popen(cmd, "r").readlines():
+ a = string.split(line)
+ if a[0] == "test":
+ if a[1] == "remove":
+ del tdict[a[-1]]
+ elif not tdict.has_key(a[-1]):
+ tdict[a[-1]] = Test(a[-1], spe)
+
+ tests = tdict.keys()
+ tests.sort()
+
if qmtest:
if baseline:
- result_stream = 'AegisBaselineStream'
+ aegis_result_stream = 'scons_tdb.AegisBaselineStream'
qmr_file = 'baseline.qmr'
else:
- result_stream = 'AegisChangeStream'
+ aegis_result_stream = 'scons_tdb.AegisChangeStream'
qmr_file = 'results.qmr'
- #qmtest = r'D:\Applications\python23\scripts\qmtest.py'
- qmtest = 'qmtest.py'
- qmtest_args = [
- qmtest,
+
+ if print_times:
+ aegis_result_stream = aegis_result_stream + "(print_time='1')"
+
+ qmtest_args = [ qmtest, ]
+
+ if format == '--aegis':
+ dir = os.path.join(cwd, 'build')
+ if not os.path.isdir(dir):
+ dir = cwd
+ qmtest_args.extend(['-D', dir])
+
+ qmtest_args.extend([
'run',
'--output %s' % qmr_file,
'--format none',
- '--result-stream=scons_tdb.%s' % result_stream,
- ]
+ '--result-stream="%s"' % aegis_result_stream,
+ ])
if python:
- qmtest_args.append('--context python=%s' % python)
-
- if print_times:
- qmtest_args.append('--context print_time=1')
+ qmtest_args.append('--context python="%s"' % python)
if outputfile:
- #rs = '--result-stream=scons_tdb.AegisBatchStream(results_file=\\"%s\\")' % outputfile
- rs = '\'--result-stream=scons_tdb.AegisBatchStream(results_file="%s")\'' % outputfile
+ if format == '--xml':
+ rsclass = 'scons_tdb.SConsXMLResultStream'
+ else:
+ rsclass = 'scons_tdb.AegisBatchStream'
+ qof = "r'" + outputfile + "'"
+ rs = '--result-stream="%s(filename=%s)"' % (rsclass, qof)
qmtest_args.append(rs)
- os.environ['SCONS'] = os.path.join(cwd, 'src', 'script', 'scons.py')
+ if format == '--aegis':
+ tests = map(lambda x: string.replace(x, cwd+os.sep, ''), tests)
+ else:
+ os.environ['SCONS'] = os.path.join(cwd, 'src', 'script', 'scons.py')
- cmd = string.join(qmtest_args + args, ' ')
+ cmd = string.join(qmtest_args + tests, ' ')
if printcommand:
sys.stdout.write(cmd + '\n')
sys.stdout.flush()
status = 0
if execute_tests:
- status = os.system(cmd)
+ status = os.WEXITSTATUS(os.system(cmd))
sys.exit(status)
#try:
#except OSError:
# pass
+tests = map(Test, tests)
+
class Unbuffered:
def __init__(self, file):
self.file = file
# but time.time() does a better job on Linux systems, so let that be
# the non-Windows default.
-if print_times:
- print_time_func = lambda fmt, time: sys.stdout.write(fmt % time)
-else:
- print_time_func = lambda fmt, time: None
-
if sys.platform == 'win32':
time_func = time.clock
else:
time_func = time.time
-if sys.platform == 'win32':
- time_func = time.clock
+if print_times:
+ print_time_func = lambda fmt, time: sys.stdout.write(fmt % time)
else:
- time_func = time.time
+ print_time_func = lambda fmt, time: None
total_start_time = time_func()
for t in tests:
RELEASE 0.97 - XXX
+ From Anonymous:
+
+ - Allow Python Value Nodes to be Builder targets.
+
+ From Matthias:
+
+ - Only filter Visual Studio common filename prefixes on complete
+ directory names.
+
+ From Chad Austin:
+
+ - Fix the build of the SCons documentation on systems that don't
+ have "python" in the $PATH.
+
From Ken Boortz:
- Enhance ParseConfig() to recognize options that begin with '+'.
+ From John Calcote, Elliot Murphy:
+
+ - Document ways to override the CCPDBFLAGS variable to use the
+ Microsoft linker's /Zi option instead of the default /Z7.
+
From Christopher Drexler:
- Make SCons aware bibtex must be called if any \include files
- Preserve white space in display Action strfunction strings.
+ From James Y. Knight and Gerard Patel:
+
+ - Support creation of shared object files from assembly language.
+
From Steven Knight:
- Speed up the Taskmaster significantly by avoiding unnecessary
This will become the default behavior as we add more functionality
to the QMTest side.
+ - Let linking on mingw use the default function that chooses $CC (gcc)
+ or $CXX (g++) depending on whether there are any C++ source files.
+
+ - Work around a bug in early versions of the Python 2.4 profile module
+ that caused the --profile= option to fail.
+
+ - Only call Options validators and converters once when initializing a
+ construction environment.
+
+ - Fix the ability of env.Append() and env.Prepend(), in all known Python
+ versions, to handle different input value types when the construction
+ variable being updated is a dictionary.
+
+ - Add a --cache-debug option for information about what files it's
+ looking for in a CacheDir().
+
+ - Document the difference in construction variable expansion between
+ {Action,Builder}() and env.{Action,Builder}().
+
From Arve Knudsen:
- Support cleaning and scanning SWIG-generated files.
- From Baptiste Lepilleur:
+ From Carsten Koch:
+
+ - Allow selection of Visual Studio version by setting $MSVS_VERSION
+ after construction environment initialization.
+
+ From Jean-Baptiste Lab:
- Try using zipimport if we can't import Tool or Platform modules
using the normal "imp" module. This allows SCons to be packaged
using py2exe's all-in-one-zip-file approach.
+ From Ben Liblit:
+
+ - Do not re-scan files if the scanner returns no implicit dependencies.
+
From Sanjoy Mahajan:
- Change use of $SOURCES to $SOURCE in all TeX-related Tool modules.
- Prevent scanning the TeX .aux file for additional files from
trying to remove it twice when the -c option is used.
+ From Leanid Nazdrynau:
+
+ - Give the MSVC RES (resource) Builder a src_builder list and a .rc
+ src_suffix so other builders can generate .rc files.
+
+ From Matthew A. Nicholson:
+
+ - Enhance Install() and InstallAs() to handle directory trees as sources.
+
+ From Jan Nijtmans:
+
+ - Don't use the -fPIC flag when using gcc on Windows (e.g. MinGW).
+
From Greg Noel:
- Add an env.ParseFlags() method that provides separate logic for
- Initial infrastructure for running SCons tests under QMTest.
+ From Sohail Sumani:
+
+ - Fix tests that fail due to gcc warnings.
+
+ From Dobes Vandermeer:
+
+ - In stack traces, print the full paths of SConscript files.
+
From Atul Varma:
- Fix detection of Visual C++ Express Edition.
+ From Dobes Vandermeer:
+
+ - Let the src_dir option to the SConscript() function affect all the
+ the source file paths, instead of treating all source files paths
+ as relative to the SConscript directory itself.
+
+ From Nicolas Vigier:
+
+ - Fix finding Fortran modules in build directories.
+
+ - Fix use of BuildDir() when the source file in the source directory
+ is a symlink with a relative path.
+
+ From Edward Wang:
+
+ - Fix the Memoizer when the SCons Python modules are executed from
+ .pyo files at different locations from where they were compiled.
+
From Johan Zander:
- Fix missing os.path.join() when constructing the $FRAMEWORKSDKDIR/bin.
SCons/Action.py
SCons/Builder.py
SCons/Conftest.py
+SCons/cpp.py
SCons/dblite.py
SCons/Debug.py
SCons/Defaults.py
else:
python = sys.executable
+_python_ = '"' + python + '"'
+
class ActionTestCase(unittest.TestCase):
"""Test the Action() factory function"""
except AttributeError:
env = Environment()
- cmd1 = r'%s %s %s xyzzy' % (python, act_py, outfile)
+ cmd1 = r'%s %s %s xyzzy' % (_python_, act_py, outfile)
act = SCons.Action.CommandAction(cmd1)
r = act([], [], env.Copy())
c = test.read(outfile, 'r')
assert c == "act.py: 'xyzzy'\n", c
- cmd2 = r'%s %s %s $TARGET' % (python, act_py, outfile)
+ cmd2 = r'%s %s %s $TARGET' % (_python_, act_py, outfile)
act = SCons.Action.CommandAction(cmd2)
r = act(DummyNode('foo'), [], env.Copy())
c = test.read(outfile, 'r')
assert c == "act.py: 'foo'\n", c
- cmd3 = r'%s %s %s ${TARGETS}' % (python, act_py, outfile)
+ cmd3 = r'%s %s %s ${TARGETS}' % (_python_, act_py, outfile)
act = SCons.Action.CommandAction(cmd3)
r = act(map(DummyNode, ['aaa', 'bbb']), [], env.Copy())
c = test.read(outfile, 'r')
assert c == "act.py: 'aaa' 'bbb'\n", c
- cmd4 = r'%s %s %s $SOURCES' % (python, act_py, outfile)
+ cmd4 = r'%s %s %s $SOURCES' % (_python_, act_py, outfile)
act = SCons.Action.CommandAction(cmd4)
r = act([], [DummyNode('one'), DummyNode('two')], env.Copy())
c = test.read(outfile, 'r')
assert c == "act.py: 'one' 'two'\n", c
- cmd4 = r'%s %s %s ${SOURCES[:2]}' % (python, act_py, outfile)
+ cmd4 = r'%s %s %s ${SOURCES[:2]}' % (_python_, act_py, outfile)
act = SCons.Action.CommandAction(cmd4)
sources = [DummyNode('three'), DummyNode('four'), DummyNode('five')]
c = test.read(outfile, 'r')
assert c == "act.py: 'three' 'four'\n", c
- cmd5 = r'%s %s %s $TARGET XYZZY' % (python, act_py, outfile)
+ cmd5 = r'%s %s %s $TARGET XYZZY' % (_python_, act_py, outfile)
act = SCons.Action.CommandAction(cmd5)
env5 = Environment()
def get_subst_proxy(self):
return self
- cmd6 = r'%s %s %s ${TARGETS[1]} $TARGET ${SOURCES[:2]}' % (python, act_py, outfile)
+ cmd6 = r'%s %s %s ${TARGETS[1]} $TARGET ${SOURCES[:2]}' % (_python_, act_py, outfile)
act = SCons.Action.CommandAction(cmd6)
r = act(target = [Obj('111'), Obj('222')],
r = act([], [], env.Copy(out = outfile))
assert r == expect_nonexecutable, "r == %d" % r
- act = SCons.Action.CommandAction('%s %s 1' % (python, exit_py))
+ act = SCons.Action.CommandAction('%s %s 1' % (_python_, exit_py))
r = act([], [], env)
assert r == 1, r
- act = SCons.Action.CommandAction('@%s %s 1' % (python, exit_py))
+ act = SCons.Action.CommandAction('@%s %s 1' % (_python_, exit_py))
r = act([], [], env)
assert r == 1, r
- act = SCons.Action.CommandAction('@-%s %s 1' % (python, exit_py))
+ act = SCons.Action.CommandAction('@-%s %s 1' % (_python_, exit_py))
r = act([], [], env)
assert r == 0, r
- act = SCons.Action.CommandAction('-%s %s 1' % (python, exit_py))
+ act = SCons.Action.CommandAction('-%s %s 1' % (_python_, exit_py))
r = act([], [], env)
assert r == 0, r
- act = SCons.Action.CommandAction('@ %s %s 1' % (python, exit_py))
+ act = SCons.Action.CommandAction('@ %s %s 1' % (_python_, exit_py))
r = act([], [], env)
assert r == 1, r
- act = SCons.Action.CommandAction('@- %s %s 1' % (python, exit_py))
+ act = SCons.Action.CommandAction('@- %s %s 1' % (_python_, exit_py))
r = act([], [], env)
assert r == 0, r
- act = SCons.Action.CommandAction('- %s %s 1' % (python, exit_py))
+ act = SCons.Action.CommandAction('- %s %s 1' % (_python_, exit_py))
r = act([], [], env)
assert r == 0, r
# test redirection operators
def test_redirect(self, redir, stdout_msg, stderr_msg):
- cmd = r'%s %s %s xyzzy %s' % (python, act_py, outfile, redir)
+ cmd = r'%s %s %s xyzzy %s' % (_python_, act_py, outfile, redir)
# Write the output and error messages to files because
# Windows can't handle strings that are too big in its
# external environment (os.spawnve() returns EINVAL,
a([], [], Environment(s = self))
assert self.inc == 3, self.inc
- cmd2 = r'%s %s %s syzygy' % (python, act_py, outfile)
+ cmd2 = r'%s %s %s syzygy' % (_python_, act_py, outfile)
def function2(target, source, env):
open(env['out'], 'a').write("function2\n")
a = SCons.Action.Action('$BAR')
a([], [], env=Environment(BAR = f, s = self))
assert self.test == 1, self.test
- cmd = r'%s %s %s lazy' % (python, act_py, outfile)
+ cmd = r'%s %s %s lazy' % (_python_, act_py, outfile)
a([], [], env=Environment(BAR = cmd, s = self))
c = test.read(outfile, 'r')
assert c == "act.py: 'lazy'\n", c
caller_dicts = {}
-def caller(back=0):
+def caller(*backlist):
import traceback
- tb = traceback.extract_stack(limit=3+back)
- key = tb[1][:3]
- try:
- entry = caller_dicts[key]
- except KeyError:
- entry = caller_dicts[key] = {}
- key = tb[0][:3]
- try:
- entry[key] = entry[key] + 1
- except KeyError:
- entry[key] = 1
- return '%s:%d(%s)' % func_shorten(key)
+ if not backlist:
+ backlist = [0]
+ result = []
+ for back in backlist:
+ tb = traceback.extract_stack(limit=3+back)
+ key = tb[1][:3]
+ try:
+ entry = caller_dicts[key]
+ except KeyError:
+ entry = caller_dicts[key] = {}
+ key = tb[0][:3]
+ entry[key] = entry.get(key, 0) + 1
+ result.append('%s:%d(%s)' % func_shorten(key))
+ return result
def dump_caller_counts(file=sys.stdout):
keys = caller_dicts.keys()
lambda file: 'Touch("%s")' % file)
# Internal utility functions
-def copyFunc(dest, source, env):
- """Install a source file into a destination by copying it (and its
- permission/mode bits)."""
- shutil.copy2(source, dest)
- st = os.stat(source)
- os.chmod(dest, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE)
+def installFunc(dest, source, env):
+ """Install a source file or directory into a destination by copying,
+ (including copying permission/mode bits)."""
+
+ if os.path.isdir(source):
+ if os.path.exists(dest):
+ if not os.path.isdir(dest):
+ raise SCons.Errors.UserError, "cannot overwrite non-directory `%s' with a directory `%s'" % (str(dest), str(source))
+ else:
+ parent = os.path.split(dest)[0]
+ if not os.path.exists(parent):
+ os.makedirs(parent)
+ shutil.copytree(source, dest)
+ else:
+ shutil.copy2(source, dest)
+ st = os.stat(source)
+ os.chmod(dest, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE)
+
return 0
+def installStr(dest, source, env):
+ source = str(source)
+ if os.path.isdir(source):
+ type = 'directory'
+ else:
+ type = 'file'
+ return 'Install %s: "%s" as "%s"' % (type, source, dest)
+
def _concat(prefix, list, suffix, env, f=lambda x: x, target=None, source=None):
"""Creates a new list from 'list' by first interpolating each
element in the list using the 'env' dictionary and then calling f
'SCANNERS' : [],
'CONFIGUREDIR' : '#/.sconf_temp',
'CONFIGURELOG' : '#/config.log',
- 'INSTALLSTR' : 'Install file: "$SOURCE" as "$TARGET"',
'CPPSUFFIXES' : SCons.Tool.CSuffixes,
'DSUFFIXES' : SCons.Tool.DSuffixes,
+ 'ENV' : {},
'IDLSUFFIXES' : SCons.Tool.IDLSuffixes,
+ 'INSTALL' : installFunc,
+ 'INSTALLSTR' : installStr,
+ '_installStr' : installStr,
'LATEXSUFFIXES' : SCons.Tool.LaTeXSuffixes,
- 'ENV' : {},
- 'INSTALL' : copyFunc,
'_concat' : _concat,
'_defines' : _defines,
'_stripixes' : _stripixes,
return install(target[0].path, source[0].path, env)
def installString(target, source, env):
- return env.subst_target_source(env['INSTALLSTR'], 0, target, source)
+ s = env.get('INSTALLSTR', '')
+ if callable(s):
+ return s(target[0].path, source[0].path, env)
+ else:
+ return env.subst_target_source(s, 0, target, source)
installAction = SCons.Action.Action(installFunc, installString)
# environment before calling the tools, because they may use
# some of them during initialization.
apply(self.Replace, (), kw)
+ keys = kw.keys()
if options:
+ keys = keys + options.keys()
options.Update(self)
+ save = {}
+ for k in keys:
+ try:
+ save[k] = self._dict[k]
+ except KeyError:
+ # No value may have been set if they tried to pass in a
+ # reserved variable name like TARGETS.
+ pass
+
if tools is None:
tools = self._dict.get('TOOLS', None)
if tools is None:
tools = ['default']
apply_tools(self, tools, toolpath)
- # Now re-apply the passed-in variables and customizable options
+ # Now restore the passed-in variables and customized options
# to the environment, since the values the user set explicitly
# should override any values set by the tools.
- apply(self.Replace, (), kw)
- if options:
- options.Update(self)
+ for key, val in save.items():
+ self._dict[key] = val
#######################################################################
# Utility methods that are primarily for internal use by SCons.
self._dict[key] = val
else:
try:
- # Most straightforward: just try to add them
- # together. This will work in most cases, when the
- # original and new values are of compatible types.
- self._dict[key] = orig + val
- except TypeError:
+ # Check if the original looks like a dictionary.
+ # If it is, we can't just try adding the value because
+ # dictionaries don't have __add__() methods, and
+ # things like UserList will incorrectly coerce the
+ # original dict to a list (which we don't want).
+ update_dict = orig.update
+ except AttributeError:
try:
- # Try to update a dictionary value with another.
- # If orig isn't a dictionary, it won't have an
- # update() method; if val isn't a dictionary,
- # it won't have a keys() method. Either way,
- # it's an AttributeError.
- orig.update(val)
- except AttributeError:
+ # Most straightforward: just try to add them
+ # together. This will work in most cases, when the
+ # original and new values are of compatible types.
+ self._dict[key] = orig + val
+ except (KeyError, TypeError):
try:
# Check if the original is a list.
add_to_orig = orig.append
# value to it (if there's a value to append).
if val:
add_to_orig(val)
+ else:
+ # The original looks like a dictionary, so update it
+ # based on what we think the value looks like.
+ if SCons.Util.is_List(val):
+ for v in val:
+ orig[v] = None
+ else:
+ try:
+ update_dict(val)
+ except (AttributeError, TypeError, ValueError):
+ orig[val] = None
self.scanner_map_delete(kw)
def AppendENVPath(self, name, newpath, envname = 'ENV', sep = os.pathsep):
"""
kw = copy_non_reserved_keywords(kw)
for key, val in kw.items():
- if not self._dict.has_key(key) or not self._dict[key]:
+ if not self._dict.has_key(key) or self._dict[key] in ('', None):
self._dict[key] = val
elif SCons.Util.is_Dict(self._dict[key]) and \
SCons.Util.is_Dict(val):
self._dict[key] = val
else:
try:
- # Most straightforward: just try to add them
- # together. This will work in most cases, when the
- # original and new values are of compatible types.
- self._dict[key] = val + orig
- except TypeError:
+ # Check if the original looks like a dictionary.
+ # If it is, we can't just try adding the value because
+ # dictionaries don't have __add__() methods, and
+ # things like UserList will incorrectly coerce the
+ # original dict to a list (which we don't want).
+ update_dict = orig.update
+ except AttributeError:
try:
- # Try to update a dictionary value with another.
- # If orig isn't a dictionary, it won't have an
- # update() method; if val isn't a dictionary,
- # it won't have a keys() method. Either way,
- # it's an AttributeError.
- orig.update(val)
- except AttributeError:
+ # Most straightforward: just try to add them
+ # together. This will work in most cases, when the
+ # original and new values are of compatible types.
+ self._dict[key] = val + orig
+ except (KeyError, TypeError):
try:
# Check if the added value is a list.
add_to_val = val.append
if orig:
add_to_val(orig)
self._dict[key] = val
+ else:
+ # The original looks like a dictionary, so update it
+ # based on what we think the value looks like.
+ if SCons.Util.is_List(val):
+ for v in val:
+ orig[v] = None
+ else:
+ try:
+ update_dict(val)
+ except (AttributeError, TypeError, ValueError):
+ orig[val] = None
self.scanner_map_delete(kw)
def PrependENVPath(self, name, newpath, envname = 'ENV', sep = os.pathsep):
"""
kw = copy_non_reserved_keywords(kw)
for key, val in kw.items():
- if not self._dict.has_key(key) or not self._dict[key]:
+ if not self._dict.has_key(key) or self._dict[key] in ('', None):
self._dict[key] = val
elif SCons.Util.is_Dict(self._dict[key]) and \
SCons.Util.is_Dict(val):
try:
dnodes = self.arg2nodes(dir, self.fs.Dir)
except TypeError:
- raise SCons.Errors.UserError, "Target `%s' of Install() is a file, but should be a directory. Perhaps you have the Install() arguments backwards?" % str(dir)
+ fmt = "Target `%s' of Install() is a file, but should be a directory. Perhaps you have the Install() arguments backwards?"
+ raise SCons.Errors.UserError, fmt % str(dir)
try:
- sources = self.arg2nodes(source, self.fs.File)
+ sources = self.arg2nodes(source, self.fs.Entry)
except TypeError:
if SCons.Util.is_List(source):
- raise SCons.Errors.UserError, "Source `%s' of Install() contains one or more non-files. Install() source must be one or more files." % repr(map(str, source))
+ s = repr(map(str, source))
else:
- raise SCons.Errors.UserError, "Source `%s' of Install() is not a file. Install() source must be one or more files." % str(source)
+ s = str(source)
+ fmt = "Source `%s' of Install() is neither a file nor a directory. Install() source must be one or more files or directories"
+ raise SCons.Errors.UserError, fmt % s
tgt = []
for dnode in dnodes:
for src in sources:
- target = self.fs.File(src.name, dnode)
+ target = self.fs.Entry(src.name, dnode)
tgt.extend(InstallBuilder(self, target, src))
return tgt
def InstallAs(self, target, source):
"""Install sources as targets."""
- sources = self.arg2nodes(source, self.fs.File)
- targets = self.arg2nodes(target, self.fs.File)
+ sources = self.arg2nodes(source, self.fs.Entry)
+ targets = self.arg2nodes(target, self.fs.Entry)
+ if len(sources) != len(targets):
+ if not SCons.Util.is_List(target):
+ target = [target]
+ if not SCons.Util.is_List(source):
+ source = [source]
+ t = repr(map(str, target))
+ s = repr(map(str, source))
+ fmt = "Target (%s) and source (%s) lists of InstallAs() must be the same length."
+ raise SCons.Errors.UserError, fmt % (t, s)
result = []
for src, tgt in map(lambda x, y: (x, y), sources, targets):
result.extend(InstallBuilder(self, tgt, src))
else:
raise SCons.Errors.UserError, "Unknown target signature type '%s'"%type
- def Value(self, value):
+ def Value(self, value, built_value=None):
"""
"""
- return SCons.Node.Python.Value(value)
+ return SCons.Node.Python.Value(value, built_value)
class OverrideEnvironment(Base):
"""A proxy that overrides variables in a wrapped construction
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+import copy
import os
import string
import StringIO
save_stderr = sys.stderr
+ python = '"' + sys.executable + '"'
+
try:
- cmd = '%s %s' % (sys.executable, test.workpath('stdout.py'))
+ cmd = '%s %s' % (python, test.workpath('stdout.py'))
output = env.backtick(cmd)
assert output == 'this came from stdout.py\n', output
sys.stderr = StringIO.StringIO()
- cmd = '%s %s' % (sys.executable, test.workpath('stderr.py'))
+ cmd = '%s %s' % (python, test.workpath('stderr.py'))
output = env.backtick(cmd)
errout = sys.stderr.getvalue()
sys.stderr = StringIO.StringIO()
- cmd = '%s %s' % (sys.executable, test.workpath('fail.py'))
+ cmd = '%s %s' % (python, test.workpath('fail.py'))
try:
env.backtick(cmd)
except OSError, e:
assert not env1.has_key('__env__')
assert not env2.has_key('__env__')
+ def test_options(self):
+ """Test that options only get applied once."""
+ class FakeOptions:
+ def __init__(self, key, val):
+ self.calls = 0
+ self.key = key
+ self.val = val
+ def keys(self):
+ return [self.key]
+ def Update(self, env):
+ env[self.key] = self.val
+ self.calls = self.calls + 1
+
+ o = FakeOptions('AAA', 'fake_opt')
+ env = Environment(options=o, AAA='keyword_arg')
+ assert o.calls == 1, o.calls
+ assert env['AAA'] == 'fake_opt', env['AAA']
+
def test_get(self):
"""Test the get() method."""
env = self.TestEnvironment(aaa = 'AAA')
b2 = Environment()['BUILDERS']
assert b1 == b2, diff_dict(b1, b2)
+ import UserDict
+ UD = UserDict.UserDict
import UserList
UL = UserList.UserList
UL(['i7']), [''], UL(['i7', '']),
UL(['i8']), UL(['']), UL(['i8', '']),
+ {'d1':1}, 'D1', {'d1':1, 'D1':None},
+ {'d2':1}, ['D2'], {'d2':1, 'D2':None},
+ {'d3':1}, UL(['D3']), {'d3':1, 'D3':None},
+ {'d4':1}, {'D4':1}, {'d4':1, 'D4':1},
+ {'d5':1}, UD({'D5':1}), UD({'d5':1, 'D5':1}),
+
+ UD({'u1':1}), 'U1', UD({'u1':1, 'U1':None}),
+ UD({'u2':1}), ['U2'], UD({'u2':1, 'U2':None}),
+ UD({'u3':1}), UL(['U3']), UD({'u3':1, 'U3':None}),
+ UD({'u4':1}), {'U4':1}, UD({'u4':1, 'U4':1}),
+ UD({'u5':1}), UD({'U5':1}), UD({'u5':1, 'U5':1}),
+
'', 'M1', 'M1',
'', ['M2'], ['M2'],
'', UL(['M3']), UL(['M3']),
failed = 0
while cases:
input, append, expect = cases[:3]
- env['XXX'] = input
- env.Append(XXX = append)
- result = env['XXX']
- if result != expect:
+ env['XXX'] = copy.copy(input)
+ try:
+ env.Append(XXX = append)
+ except Exception, e:
if failed == 0: print
- print " %s Append %s => %s did not match %s" % \
- (repr(input), repr(append), repr(result), repr(expect))
+ print " %s Append %s exception: %s" % \
+ (repr(input), repr(append), e)
failed = failed + 1
+ else:
+ result = env['XXX']
+ if result != expect:
+ if failed == 0: print
+ print " %s Append %s => %s did not match %s" % \
+ (repr(input), repr(append), repr(result), repr(expect))
+ failed = failed + 1
del cases[:3]
assert failed == 0, "%d Append() cases failed" % failed
assert env['CCC1'] == 'c1', env['CCC1']
assert env['CCC2'] == ['c2'], env['CCC2']
+ env['CLVar'] = CLVar([])
+ env.AppendUnique(CLVar = 'bar')
+ result = env['CLVar']
+ if sys.version[0] == '1':
+ # Python 1.5.2 has a quirky behavior where CLVar([]) actually
+ # matches '' and [] due to different __coerce__() semantics
+ # in the UserList implementation. It isn't worth a lot of
+ # effort to get this corner case to work identically (support
+ # for Python 1.5 support will die soon anyway), so just treat
+ # it separately for now.
+ assert result == 'bar', result
+ else:
+ assert isinstance(result, CLVar), repr(result)
+ assert result == ['bar'], result
+
+ env['CLVar'] = CLVar(['abc'])
+ env.AppendUnique(CLVar = 'bar')
+ result = env['CLVar']
+ assert isinstance(result, CLVar), repr(result)
+ assert result == ['abc', 'bar'], result
+
+ env['CLVar'] = CLVar(['bar'])
+ env.AppendUnique(CLVar = 'bar')
+ result = env['CLVar']
+ assert isinstance(result, CLVar), repr(result)
+ assert result == ['bar'], result
+
def test_Copy(self):
"""Test construction environment copying
def test_Prepend(self):
"""Test prepending to construction variables in an Environment
"""
+ import UserDict
+ UD = UserDict.UserDict
import UserList
UL = UserList.UserList
UL(['i7']), [''], UL(['', 'i7']),
UL(['i8']), UL(['']), UL(['', 'i8']),
+ {'d1':1}, 'D1', {'d1':1, 'D1':None},
+ {'d2':1}, ['D2'], {'d2':1, 'D2':None},
+ {'d3':1}, UL(['D3']), {'d3':1, 'D3':None},
+ {'d4':1}, {'D4':1}, {'d4':1, 'D4':1},
+ {'d5':1}, UD({'D5':1}), UD({'d5':1, 'D5':1}),
+
+ UD({'u1':1}), 'U1', UD({'u1':1, 'U1':None}),
+ UD({'u2':1}), ['U2'], UD({'u2':1, 'U2':None}),
+ UD({'u3':1}), UL(['U3']), UD({'u3':1, 'U3':None}),
+ UD({'u4':1}), {'U4':1}, UD({'u4':1, 'U4':1}),
+ UD({'u5':1}), UD({'U5':1}), UD({'u5':1, 'U5':1}),
+
'', 'M1', 'M1',
'', ['M2'], ['M2'],
'', UL(['M3']), UL(['M3']),
failed = 0
while cases:
input, prepend, expect = cases[:3]
- env['XXX'] = input
- env.Prepend(XXX = prepend)
- result = env['XXX']
- if result != expect:
+ env['XXX'] = copy.copy(input)
+ try:
+ env.Prepend(XXX = prepend)
+ except Exception, e:
if failed == 0: print
- print " %s Prepend %s => %s did not match %s" % \
- (repr(input), repr(prepend), repr(result), repr(expect))
+ print " %s Prepend %s exception: %s" % \
+ (repr(input), repr(prepend), e)
failed = failed + 1
+ else:
+ result = env['XXX']
+ if result != expect:
+ if failed == 0: print
+ print " %s Prepend %s => %s did not match %s" % \
+ (repr(input), repr(prepend), repr(result), repr(expect))
+ failed = failed + 1
del cases[:3]
assert failed == 0, "%d Prepend() cases failed" % failed
assert env['CCC1'] == 'c1', env['CCC1']
assert env['CCC2'] == ['c2'], env['CCC2']
+ env['CLVar'] = CLVar([])
+ env.PrependUnique(CLVar = 'bar')
+ result = env['CLVar']
+ if sys.version[0] == '1':
+ # Python 1.5.2 has a quirky behavior where CLVar([]) actually
+ # matches '' and [] due to different __coerce__() semantics
+ # in the UserList implementation. It isn't worth a lot of
+ # effort to get this corner case to work identically (support
+ # for Python 1.5 support will die soon anyway), so just treat
+ # it separately for now.
+ assert result == 'bar', result
+ else:
+ assert isinstance(result, CLVar), repr(result)
+ assert result == ['bar'], result
+
+ env['CLVar'] = CLVar(['abc'])
+ env.PrependUnique(CLVar = 'bar')
+ result = env['CLVar']
+ assert isinstance(result, CLVar), repr(result)
+ assert result == ['bar', 'abc'], result
+
+ env['CLVar'] = CLVar(['bar'])
+ env.PrependUnique(CLVar = 'bar')
+ result = env['CLVar']
+ assert isinstance(result, CLVar), repr(result)
+ assert result == ['bar'], result
+
def test_Replace(self):
"""Test replacing construction variables in an Environment
for tnode in tgt:
assert tnode.builder == InstallBuilder
- exc_caught = None
- try:
- tgt = env.Install('export', 'export')
- except SCons.Errors.UserError, e:
- exc_caught = 1
- assert exc_caught, "UserError should be thrown when Install() target is not a file."
- match = str(e) == "Source `export' of Install() is not a file. Install() source must be one or more files."
- assert match, e
+ tgt = env.Install('export', 'build')
+ paths = map(str, tgt)
+ paths.sort()
+ expect = ['export/build']
+ assert paths == expect, paths
+ for tnode in tgt:
+ assert tnode.builder == InstallBuilder
- exc_caught = None
- try:
- tgt = env.Install('export', ['export', 'build/foo1'])
- except SCons.Errors.UserError, e:
- exc_caught = 1
- assert exc_caught, "UserError should be thrown when Install() target containins non-files."
- match = str(e) == "Source `['export', 'build/foo1']' of Install() contains one or more non-files. Install() source must be one or more files."
- assert match, e
+ tgt = env.Install('export', ['build', 'build/foo1'])
+ paths = map(str, tgt)
+ paths.sort()
+ expect = ['export/build', 'export/foo1']
+ assert paths == expect, paths
+ for tnode in tgt:
+ assert tnode.builder == InstallBuilder
+
+ env.File('export/foo1')
exc_caught = None
try:
except SCons.Errors.UserError, e:
exc_caught = 1
assert exc_caught, "UserError should be thrown reversing the order of Install() targets."
- match = str(e) == "Target `export/foo1' of Install() is a file, but should be a directory. Perhaps you have the Install() arguments backwards?"
- assert match, e
+ expect = "Target `export/foo1' of Install() is a file, but should be a directory. Perhaps you have the Install() arguments backwards?"
+ assert str(e) == expect, e
def test_InstallAs(self):
"""Test the InstallAs method"""
assert not v1 is v2
assert v1.value == v2.value
+ v3 = env.Value('c', 'build-c')
+ assert v3.value == 'c', v3.value
+
def test_Environment_global_variable(type):
# Make sure filename has os.sep+'SCons'+os.sep so that
# SCons.Script.find_deepest_user_frame doesn't stop here
import inspect # It's OK, can't get here for Python < 2.1
+ filename = inspect.getsourcefile(_MeMoIZeR_superinit)
+ if not filename:
+ # This file was compiled at a path name different from
+ # how it's invoked now, so just make up something.
+ filename = whoami('superinit', '???')
superinitcode = compile(
"lambda self, *args, **kw: MPI(self, cls, args, kw)",
- inspect.getsourcefile(_MeMoIZeR_superinit) or '<unknown>',
+ filename,
"eval")
superinit = eval(superinitcode,
{'cls':cls,
# there should be *no* changes to the external file system(s)...
#
-def _copy_func(src, dest):
+if hasattr(os, 'link'):
+ def _hardlink_func(fs, src, dst):
+ # If the source is a symlink, we can't just hard-link to it
+ # because a relative symlink may point somewhere completely
+ # different. We must disambiguate the symlink and then
+ # hard-link the final destination file.
+ while fs.islink(src):
+ link = fs.readlink(src)
+ if not os.path.isabs(link):
+ src = link
+ else:
+ src = os.path.join(os.path.dirname(src), link)
+ fs.link(src, dst)
+else:
+ _hardlink_func = None
+
+if hasattr(os, 'symlink'):
+ def _softlink_func(fs, src, dst):
+ fs.symlink(src, dst)
+else:
+ _softlink_func = None
+
+def _copy_func(fs, src, dest):
shutil.copy2(src, dest)
- st=os.stat(src)
- os.chmod(dest, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE)
+ st = fs.stat(src)
+ fs.chmod(dest, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE)
+
Valid_Duplicates = ['hard-soft-copy', 'soft-hard-copy',
'hard-copy', 'soft-copy', 'copy']
# underlying implementations. We do this inside this function,
# not in the top-level module code, so that we can remap os.link
# and os.symlink for testing purposes.
- try:
- _hardlink_func = os.link
- except AttributeError:
- _hardlink_func = None
-
- try:
- _softlink_func = os.symlink
- except AttributeError:
- _softlink_func = None
-
link_dict = {
'hard' : _hardlink_func,
'soft' : _softlink_func,
if not Link_Funcs:
# Set a default order of link functions.
set_duplicate('hard-soft-copy')
+ fs = source[0].fs
# Now link the files with the previously specified order.
for func in Link_Funcs:
try:
- func(src,dest)
+ func(fs, src, dest)
break
except (IOError, OSError):
# An OSError indicates something happened like a permissions
t = target[0]
fs = t.fs
cachedir, cachefile = t.cachepath()
- if fs.exists(cachefile):
- if SCons.Action.execute_actions:
- fs.copy2(cachefile, t.path)
- st = fs.stat(cachefile)
- fs.chmod(t.path, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE)
- return 0
- return 1
+ if not fs.exists(cachefile):
+ fs.CacheDebug('CacheRetrieve(%s): %s not in cache\n', t, cachefile)
+ return 1
+ fs.CacheDebug('CacheRetrieve(%s): retrieving from %s\n', t, cachefile)
+ if SCons.Action.execute_actions:
+ fs.copy2(cachefile, t.path)
+ st = fs.stat(cachefile)
+ fs.chmod(t.path, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE)
+ return 0
def CacheRetrieveString(target, source, env):
t = target[0]
fs = t.fs
cachedir, cachefile = t.cachepath()
if fs.exists(cachefile):
- # Don't bother copying it if it's already there.
+ # Don't bother copying it if it's already there. Note that
+ # usually this "shouldn't happen" because if the file already
+ # existed in cache, we'd have retrieved the file from there,
+ # not built it. This can happen, though, in a race, if some
+ # other person running the same build pushes their copy to
+ # the cache after we decide we need to build it but before our
+ # build completes.
+ fs.CacheDebug('CachePush(%s): %s already exists in cache\n', t, cachefile)
return
+ fs.CacheDebug('CachePush(%s): pushing to %s\n', t, cachefile)
+
if not fs.isdir(cachedir):
fs.makedirs(cachedir)
SCons.Warnings.warn(SCons.Warnings.CacheWriteErrorWarning,
"Unable to copy %s to cache. Cache file is %s"
% (str(target), cachefile))
- return
CachePush = SCons.Action.Action(CachePushFunc, None)
def islink(self, path):
return 0 # no symlinks
+ if hasattr(os, 'readlink'):
+ def readlink(self, file):
+ return os.readlink(file)
+ else:
+ def readlink(self, file):
+ return ''
+
+
if SCons.Memoize.use_old_memoization():
_FSBase = LocalFS
class LocalFS(SCons.Memoize.Memoizer, _FSBase):
result.extend(dir.get_all_rdirs())
return result
+ def CacheDebugWrite(self, fmt, target, cachefile):
+ self.CacheDebugFP.write(fmt % (target, os.path.split(cachefile)[1]))
+
+ def CacheDebugQuiet(self, fmt, target, cachefile):
+ pass
+
+ CacheDebug = CacheDebugQuiet
+
+ def CacheDebugEnable(self, file):
+ if file == '-':
+ self.CacheDebugFP = sys.stdout
+ else:
+ self.CacheDebugFP = open(file, 'w')
+ self.CacheDebug = self.CacheDebugWrite
+
def CacheDir(self, path):
self.CachePath = path
__cacheable__"""
if not scanner:
return []
- return map(lambda N: N.disambiguate(), scanner(self, env, path))
+ return scanner(self, env, path)
def _createDir(self):
# ensure that the directories for this node are
if self.fs.cache_show:
if CacheRetrieveSilent(self, [], None, execute=1) == 0:
self.build(presub=0, execute=0)
+ self.set_state(SCons.Node.executed)
return 1
elif CacheRetrieve(self, [], None, execute=1) == 0:
+ self.set_state(SCons.Node.executed)
return 1
return None
+
def built(self):
"""Called just after this node is successfully built.
__cache_reset__"""
class LinkSimulator :
"""A class to intercept os.[sym]link() calls and track them."""
- def __init__( self, duplicate ) :
+ def __init__( self, duplicate, link, symlink, copy ) :
self.duplicate = duplicate
- self._reset()
-
- def _reset( self ) :
- """Reset the simulator if necessary"""
- if not self._need_reset() : return # skip if not needed now
- self.links_to_be_called = self.duplicate
-
- def _need_reset( self ) :
- """
- Determines whether or not the simulator needs to be reset.
- A reset is necessary if the object is first being initialized,
- or if all three methods have been tried already.
- """
- return (
- ( not hasattr( self , "links_to_be_called" ) )
- or
- (self.links_to_be_called == "")
- )
+ self.have = {}
+ self.have['hard'] = link
+ self.have['soft'] = symlink
+ self.have['copy'] = copy
+
+ self.links_to_be_called = []
+ for link in string.split(self.duplicate, '-'):
+ if self.have[link]:
+ self.links_to_be_called.append(link)
def link_fail( self , src , dest ) :
- self._reset()
- l = string.split(self.links_to_be_called, "-")
- next_link = l[0]
- assert next_link == "hard", \
+ next_link = self.links_to_be_called.pop(0)
+ assert next_link == "hard", \
"Wrong link order: expected %s to be called "\
"instead of hard" % next_link
- self.links_to_be_called = string.join(l[1:], '-')
raise OSError( "Simulating hard link creation error." )
def symlink_fail( self , src , dest ) :
- self._reset()
- l = string.split(self.links_to_be_called, "-")
- next_link = l[0]
- assert next_link == "soft", \
+ next_link = self.links_to_be_called.pop(0)
+ assert next_link == "soft", \
"Wrong link order: expected %s to be called "\
"instead of soft" % next_link
- self.links_to_be_called = string.join(l[1:], '-')
raise OSError( "Simulating symlink creation error." )
def copy( self , src , dest ) :
- self._reset()
- l = string.split(self.links_to_be_called, "-")
- next_link = l[0]
- assert next_link == "copy", \
+ next_link = self.links_to_be_called.pop(0)
+ assert next_link == "copy", \
"Wrong link order: expected %s to be called "\
"instead of copy" % next_link
- self.links_to_be_called = string.join(l[1:], '-')
# copy succeeds, but use the real copy
- self._real_copy(src, dest)
+ self.have['copy'](src, dest)
# end class LinkSimulator
try:
pass
for duplicate in SCons.Node.FS.Valid_Duplicates:
- simulator = LinkSimulator(duplicate)
-
# save the real functions for later restoration
- real_link = None
- real_symlink = None
try:
real_link = os.link
except AttributeError:
- pass
+ real_link = None
try:
real_symlink = os.symlink
except AttributeError:
- pass
+ real_symlink = None
real_copy = shutil.copy2
- simulator._real_copy = real_copy # the simulator needs the real one
+
+ simulator = LinkSimulator(duplicate, real_link, real_symlink, real_copy)
# override the real functions with our simulation
os.link = simulator.link_fail
os.symlink = simulator.symlink_fail
shutil.copy2 = simulator.copy
- SCons.Node.FS.set_duplicate(duplicate)
-
- src_foo = test.workpath('src', 'foo')
- build_foo = test.workpath('build', 'foo')
try:
+
+ SCons.Node.FS.set_duplicate(duplicate)
+
+ src_foo = test.workpath('src', 'foo')
+ build_foo = test.workpath('build', 'foo')
+
test.write(src_foo, 'src/foo\n')
os.chmod(src_foo, stat.S_IRUSR)
try:
NodeInfo = ValueNodeInfo
BuildInfo = ValueBuildInfo
- def __init__(self, value):
+ def __init__(self, value, built_value=None):
SCons.Node.Node.__init__(self)
self.value = value
+ if not built_value is None:
+ self.built_value = built_value
def __str__(self):
return repr(self.value)
- def build(self):
- """A "builder" for Values."""
- pass
+ def build(self, **kw):
+ if not hasattr(self, 'built_value'):
+ apply (SCons.Node.Node.build, (self,), kw)
current = SCons.Node.Node.children_are_up_to_date
# are outside the filesystem:
return 1
+ def write(self, built_value):
+ """Set the value of the node."""
+ self.built_value = built_value
+
+ def read(self):
+ """Return the value. If necessary, the value is built."""
+ self.build()
+ if not hasattr(self, 'built_value'):
+ self.built_value = self.value
+ return self.built_value
+
def get_contents(self):
- """The contents of a Value are the concatenation
- of all the contents of its sources with the node's value itself."""
+ """By the assumption that the node.built_value is a
+ deterministic product of the sources, the contents of a Value
+ are the concatenation of all the contents of its sources. As
+ the value need not be built when get_contents() is called, we
+ cannot use the actual node.built_value."""
contents = str(self.value)
for kid in self.children(None):
contents = contents + kid.get_contents()
assert not v1 is v2
assert v1.value == v2.value
+ v3 = SCons.Node.Python.Value('c', 'cb')
+ assert v3.built_value == 'cb'
+
+ def test_build(self):
+ """Test "building" a Value Node
+ """
+ class fake_executor:
+ def __call__(self, node, exitstatfunc):
+ node.write('faked')
+
+ v1 = SCons.Node.Python.Value('b', 'built')
+ v1.executor = fake_executor()
+ v1.build()
+ assert v1.built_value == 'built', v1.built_value
+
+ v2 = SCons.Node.Python.Value('b')
+ v2.executor = fake_executor()
+ v2.build()
+ assert v2.built_value == 'faked', v2.built_value
+
+ def test_read(self):
+ """Test the Value.read() method
+ """
+ v1 = SCons.Node.Python.Value('a')
+ x = v1.read()
+ assert x == 'a', x
+
+ def test_write(self):
+ """Test the Value.write() method
+ """
+ v1 = SCons.Node.Python.Value('a')
+ assert v1.value == 'a', v1.value
+ assert not hasattr(v1, 'built_value')
+
+ v1.write('new')
+ assert v1.value == 'a', v1.value
+ assert v1.built_value == 'new', v1.built_value
+
def test_get_csig(self):
"""Test calculating the content signature of a Value() object
"""
d = filter(lambda x, seen=seen: not seen.has_key(x),
n.get_found_includes(env, scanner, path))
if d:
+ d = map(lambda N: N.disambiguate(), d)
deps.extend(d)
for n in d:
seen[n] = 1
# Here's where we implement --implicit-cache.
if implicit_cache and not implicit_deps_changed:
implicit = self.get_stored_implicit()
- if implicit:
+ if implicit is not None:
factory = build_env.get_factory(self.builder.source_factory)
nodes = []
for i in implicit:
UserList.UserList.__init__(self, filter(None, initlist))
self.allowedElems = allowedElems[:]
self.allowedElems.sort()
-
+
def __cmp__(self, other):
raise NotImplementedError
def __eq__(self, other):
return string.join(self, ',')
def __repr__(self):
return self.__str__()
-
+
def _converter(val, allowedElems, mapdict):
"""
"""
l = o.converter('all')
n = l.__class__(copy.copy(l))
- def test___repr__(self):
- """Test copying a ListOption like an Environment would"""
-
if __name__ == "__main__":
suite = unittest.makeSuite(ListOptionTestCase, 'test_')
if not unittest.TextTestRunner().run(suite).wasSuccessful():
class OptionsTestCase(unittest.TestCase):
+ def test_keys(self):
+ """Test the Options.keys() method"""
+ opts = SCons.Options.Options()
+
+ opts.Add('VAR1')
+ opts.Add('VAR2',
+ 'THE answer to THE question',
+ "42",
+ check,
+ lambda x: int(x) + 12)
+ keys = opts.keys()
+ assert keys == ['VAR1', 'VAR2'], keys
+
def test_Add(self):
"""Test adding to an Options object"""
opts = SCons.Options.Options()
self.options.append(option)
+ def keys(self):
+ """
+ Returns the keywords for the options
+ """
+ return map(lambda o: o.key, self.options)
def Add(self, key, help="", default=None, validator=None, converter=None, **kw):
"""
self._do_add(key, help, default, validator, converter)
-
def AddOptions(self, *optlist):
"""
Add a list of options.
# returned by os.waitpid() or os.system().
return stat
-def exec_fork(l, env):
+def exec_fork(l, env):
pid = os.fork()
if not pid:
# Child process.
try:
os.execvpe(l[0], l, env)
except OSError, e:
- exitval = exitvalmap[e[0]]
+ exitval = exitvalmap.get(e[0], e[0])
sys.stderr.write("scons: %s: %s\n" % (l[0], e[1]))
os._exit(exitval)
else:
try:
os.execvpe(l[0], l, env)
except OSError, e:
- exitval = exitvalmap[e[0]]
+ exitval = exitvalmap.get(e[0], e[0])
stderr.write("scons: %s: %s\n" % (l[0], e[1]))
os._exit(exitval)
else:
ret = os.spawnve(os.P_WAIT, sh, args, env)
except OSError, e:
# catch any error
- ret = exitvalmap[e[0]]
+ try:
+ ret = exitvalmap[e[0]]
+ except KeyError:
+ result = 127
+ sys.stderr.write("scons: unknown OSError exception code %d - %s: %s\n" % (e[0], cmd, e[1]))
if stderr != None:
stderr.write("scons: %s: %s\n" % (cmd, e[1]))
# copy child output from tempfiles to our streams
try:
result = os.spawnve(os.P_WAIT, l[0], l, env)
except OSError, e:
- result = exitvalmap[e[0]]
- sys.stderr.write("scons: %s: %s\n" % (l[0], e[1]))
+ try:
+ result = exitvalmap[e[0]]
+ sys.stderr.write("scons: %s: %s\n" % (l[0], e[1]))
+ except KeyError:
+ result = 127
+ if len(l) > 2:
+ if len(l[2]) < 1000:
+ command = string.join(l[0:3])
+ else:
+ command = l[0]
+ else:
+ command = l[0]
+ sys.stderr.write("scons: unknown OSError exception code %d - '%s': %s\n" % (e[0], command, e[1]))
return result
def spawn(sh, escape, cmd, args, env):
return 127
return exec_spawn([sh, '/C', escape(string.join(args))], env)
-# Windows does not allow special characters in file names anyway, so
-# no need for a complex escape function, we will just quote the arg.
-escape = lambda x: '"' + x + '"'
+# Windows does not allow special characters in file names anyway, so no
+# need for a complex escape function, we will just quote the arg, except
+# that "cmd /c" requires that if an argument ends with a backslash it
+# needs to be escaped so as not to interfere with closing double quote
+# that we add.
+def escape(x):
+ if x[-1] == '\\':
+ x = x + '\\'
+ return '"' + x + '"'
# Get the windows system directory name
def get_system_root():
class CScannerTestCase1(unittest.TestCase):
def runTest(self):
+ """Find local files with no CPPPATH"""
env = DummyEnvironment(CPPPATH=[])
s = SCons.Scanner.C.CScanner()
path = s.path(env)
class CScannerTestCase2(unittest.TestCase):
def runTest(self):
+ """Find a file in a CPPPATH directory"""
env = DummyEnvironment(CPPPATH=[test.workpath("d1")])
s = SCons.Scanner.C.CScanner()
path = s.path(env)
class CScannerTestCase3(unittest.TestCase):
def runTest(self):
+ """Find files in explicit subdirectories, ignore missing file"""
env = DummyEnvironment(CPPPATH=[test.workpath("d1")])
s = SCons.Scanner.C.CScanner()
path = s.path(env)
class CScannerTestCase4(unittest.TestCase):
def runTest(self):
+ """Find files in explicit subdirectories"""
env = DummyEnvironment(CPPPATH=[test.workpath("d1"), test.workpath("d1/d2")])
s = SCons.Scanner.C.CScanner()
path = s.path(env)
class CScannerTestCase5(unittest.TestCase):
def runTest(self):
+ """Make sure files in repositories will get scanned"""
env = DummyEnvironment(CPPPATH=[])
s = SCons.Scanner.C.CScanner()
path = s.path(env)
class CScannerTestCase6(unittest.TestCase):
def runTest(self):
+ """Find a same-named file in different directories when CPPPATH changes"""
env1 = DummyEnvironment(CPPPATH=[test.workpath("d1")])
env2 = DummyEnvironment(CPPPATH=[test.workpath("d1/d2")])
s = SCons.Scanner.C.CScanner()
class CScannerTestCase8(unittest.TestCase):
def runTest(self):
+ """Find files in a subdirectory relative to the current directory"""
env = DummyEnvironment(CPPPATH=["include"])
s = SCons.Scanner.C.CScanner()
path = s.path(env)
class CScannerTestCase9(unittest.TestCase):
def runTest(self):
+ """Generate a warning when we can't find a #included file"""
SCons.Warnings.enableWarningClass(SCons.Warnings.DependencyWarning)
class TestOut:
def __call__(self, x):
class CScannerTestCase10(unittest.TestCase):
def runTest(self):
+ """Find files in the local directory when the scanned file is elsewhere"""
fs = SCons.Node.FS.FS(test.workpath(''))
fs.chdir(fs.Dir('include'))
env = DummyEnvironment(CPPPATH=[])
class CScannerTestCase11(unittest.TestCase):
def runTest(self):
+ """Handle dependencies on a derived .h file in a non-existent directory"""
os.chdir(test.workpath('work'))
fs = SCons.Node.FS.FS(test.workpath('work'))
fs.Repository(test.workpath('repository'))
class CScannerTestCase12(unittest.TestCase):
def runTest(self):
+ """Find files in BuildDir() directories"""
os.chdir(test.workpath('work'))
fs = SCons.Node.FS.FS(test.workpath('work'))
fs.BuildDir('build1', 'src', 1)
class CScannerTestCase13(unittest.TestCase):
def runTest(self):
+ """Find files in directories named in a substituted environment variable"""
class SubstEnvironment(DummyEnvironment):
def subst(self, arg, test=test):
return test.workpath("d1")
class CScannerTestCase14(unittest.TestCase):
def runTest(self):
+ """Find files when there's no space between "#include" and the name"""
env = DummyEnvironment(CPPPATH=[])
s = SCons.Scanner.C.CScanner()
path = s.path(env)
class CScannerTestCase15(unittest.TestCase):
def runTest(self):
+ """Verify scanner initialization with the suffixes in $CPPSUFFIXES"""
suffixes = [".c", ".C", ".cxx", ".cpp", ".c++", ".cc",
".h", ".H", ".hxx", ".hpp", ".hh",
".F", ".fpp", ".FPP",
path = path + '/' + d
return path
+def version_string(label, module):
+ fmt = "\t%s: v%s.%s, %s, by %s on %s\n"
+ return fmt % (label,
+ module.__version__,
+ module.__build__,
+ module.__date__,
+ module.__developer__,
+ module.__buildsys__)
class OptParser(OptionParser):
def __init__(self):
import __main__
- import SCons
+
parts = ["SCons by Steven Knight et al.:\n"]
try:
- parts.append("\tscript: v%s.%s, %s, by %s on %s\n" % (__main__.__version__,
- __main__.__build__,
- __main__.__date__,
- __main__.__developer__,
- __main__.__buildsys__))
+ parts.append(version_string("script", __main__))
except KeyboardInterrupt:
raise
except:
# On Windows there is no scons.py, so there is no
# __main__.__version__, hence there is no script version.
pass
- parts.append("\tengine: v%s.%s, %s, by %s on %s\n" % (SCons.__version__,
- SCons.__build__,
- SCons.__date__,
- SCons.__developer__,
- SCons.__buildsys__))
+ parts.append(version_string("engine", SCons))
parts.append("__COPYRIGHT__")
OptionParser.__init__(self, version=string.join(parts, ''),
usage="usage: scons [OPTION] [TARGET] ...")
metavar="DIR",
help="Change to DIR before doing anything.")
+ self.add_option('--cache-debug', action="store",
+ dest="cache_debug", metavar="FILE",
+ help="Print CacheDir debug info to FILE.")
+
self.add_option('--cache-disable', '--no-cache',
action="store_true", dest='cache_disable', default=0,
help="Do not retrieve built targets from CacheDir.")
display.set_mode(0)
if options.silent:
SCons.Action.print_actions = None
+
+ if options.cache_debug:
+ fs.CacheDebugEnable(options.cache_debug)
if options.cache_disable:
def disable(self): pass
fs.CacheDir = disable
import pdb
pdb.Pdb().runcall(_main, args, parser)
elif options.profile_file:
- import profile
- prof = profile.Profile()
+ from profile import Profile
+
+ # Some versions of Python 2.4 shipped a profiler that had the
+ # wrong 'c_exception' entry in its dispatch table. Make sure
+ # we have the right one. (This may put an unnecessary entry
+ # in the table in earlier versions of Python, but its presence
+ # shouldn't hurt anything).
+ try:
+ dispatch = Profile.dispatch
+ except AttributeError:
+ pass
+ else:
+ dispatch['c_exception'] = Profile.trace_dispatch_return
+
+ prof = Profile()
try:
prof.runcall(_main, args, parser)
except SystemExit:
# fs match so we can open the SConscript.
fs.chdir(top, change_os_dir=1)
if f.rexists():
- _file_ = open(f.rstr(), "r")
+ _file_ = open(f.rfile().get_abspath(), "r")
elif f.has_src_builder():
# The SConscript file apparently exists in a source
# code management system. Build it, but then clear
f.build()
f.builder_set(None)
if f.exists():
- _file_ = open(str(f), "r")
+ _file_ = open(f.get_abspath(), "r")
if _file_:
# Chdir to the SConscript directory. Use a path
# name relative to the SConstruct file so that if
# where the SConstruct and SConscript files might be
# in different Repositories. For now, cross that
# bridge when someone comes to it.
- ldir = fs.Dir(f.dir.get_path(sd))
+ try:
+ src_dir = kw['src_dir']
+ except KeyError:
+ ldir = fs.Dir(f.dir.get_path(sd))
+ else:
+ ldir = fs.Dir(src_dir)
+ if not ldir.is_under(f.dir):
+ # They specified a source directory, but
+ # it's above the SConscript directory.
+ # Do the sensible thing and just use the
+ # SConcript directory.
+ ldir = fs.Dir(f.dir.get_path(sd))
try:
fs.chdir(ldir, change_os_dir=sconscript_chdir)
except OSError:
# interpret the stuff within the SConscript file
# relative to where we are logically.
fs.chdir(ldir, change_os_dir=0)
+ # TODO Not sure how to handle src_dir here
os.chdir(f.rfile().dir.get_abspath())
# Append the SConscript directory to the beginning
# SConscript can base the printed frames at this
# level and not show SCons internals as well.
call_stack[-1].globals.update({stack_bottom:1})
- exec _file_ in call_stack[-1].globals
+ old_file = call_stack[-1].globals.get('__file__')
+ try:
+ del call_stack[-1].globals['__file__']
+ except KeyError:
+ pass
+ try:
+ exec _file_ in call_stack[-1].globals
+ finally:
+ if old_file is not None:
+ call_stack[-1].globals.update({__file__:old_file})
else:
SCons.Warnings.warn(SCons.Warnings.MissingSConscriptWarning,
"Ignoring missing SConscript '%s'" % f.path)
src_dir = kw.get('src_dir')
if not src_dir:
src_dir, fname = os.path.split(str(files[0]))
+ files = [os.path.join(str(build_dir), fname)]
else:
if not isinstance(src_dir, SCons.Node.Node):
src_dir = self.fs.Dir(src_dir)
if fn.is_under(src_dir):
# Get path relative to the source directory.
fname = fn.get_path(src_dir)
+ files = [os.path.join(str(build_dir), fname)]
else:
- # Fast way to only get the terminal path component of a Node.
- fname = fn.get_path(fn.dir)
+ files = [fn.abspath]
+ kw['src_dir'] = build_dir
self.fs.BuildDir(build_dir, src_dir, duplicate)
- files = [os.path.join(str(build_dir), fname)]
return (files, exports)
subst_kw[key] = val
files, exports = self._get_SConscript_filenames(ls, subst_kw)
-
- return apply(_SConscript, [self.fs,] + files, {'exports' : exports})
+ subst_kw['exports'] = exports
+ return apply(_SConscript, [self.fs,] + files, subst_kw)
def SConscriptChdir(self, flag):
global sconscript_chdir
for suffix in ASSuffixes:
static_obj.add_action(suffix, SCons.Defaults.ASAction)
+ shared_obj.add_action(suffix, SCons.Defaults.ASAction)
static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter)
+ shared_obj.add_emitter(suffix, SCons.Defaults.SharedObjectEmitter)
for suffix in ASPPSuffixes:
static_obj.add_action(suffix, SCons.Defaults.ASPPAction)
+ shared_obj.add_action(suffix, SCons.Defaults.ASPPAction)
static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter)
+ shared_obj.add_emitter(suffix, SCons.Defaults.SharedObjectEmitter)
env['AS'] = env.Detect(assemblers) or 'as'
env['ASFLAGS'] = SCons.Util.CLVar('')
env['FORTRANMODDIR'] = '' # where the compiler should place .mod files
env['FORTRANMODDIRPREFIX'] = '' # some prefix to $FORTRANMODDIR - similar to $INCPREFIX
env['FORTRANMODDIRSUFFIX'] = '' # some suffix to $FORTRANMODDIR - similar to $INCSUFFIX
- env['_FORTRANMODFLAG'] = '$( ${_concat(FORTRANMODDIRPREFIX, FORTRANMODDIR, FORTRANMODDIRSUFFIX, __env__)} $)'
+ env['_FORTRANMODFLAG'] = '$( ${_concat(FORTRANMODDIRPREFIX, FORTRANMODDIR, FORTRANMODDIRSUFFIX, __env__, RDirs)} $)'
env.AppendUnique(FORTRANSUFFIXES = FortranSuffixes + FortranPPSuffixes)
cc.generate(env)
env['CC'] = env.Detect(compilers) or 'gcc'
- if env['PLATFORM'] == 'cygwin':
+ if env['PLATFORM'] in ['cygwin', 'win32']:
env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS')
else:
env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS -fPIC')
# Most of mingw is the same as gcc and friends...
- gnu_tools = ['gcc', 'g++', 'gnulink', 'ar', 'gas']
+ gnu_tools = ['gcc', 'g++', 'gnulink', 'ar', 'gas', 'm4']
for tool in gnu_tools:
SCons.Tool.Tool(tool)(env)
env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS -shared')
env['SHLINKCOM'] = shlib_action
env.Append(SHLIBEMITTER = [shlib_emitter])
- env['LINK'] = 'g++'
env['AS'] = 'as'
env['WIN32DEFPREFIX'] = ''
<example>
env['PDB'] = 'hello.pdb'
</example>
+
+The Visual C++ compiler switch that SCons uses by default
+to generate PDB information is <option>/Z7</option>.
+This works correctly with parallel (<option>-j</option>) builds
+because it embeds the debug information in the intermediate object files,
+as opposed to sharing a single PDB file between multiple object files.
+This is also the only way to get debug information
+embedded into a static library.
+Using the <option>/Zi</option> instead may yield improved
+link-time performance,
+although parallel builds will no longer work.
+You can generate PDB files with the <option>/Zi</option>
+switch by overriding the default &cv-CCPDBFLAGS; variable;
+see the entry for that variable for specific examples.
</summary>
</cvar>
include_paths.append( env_include_path )
if SCons.Util.can_read_reg and paths.has_key('FRAMEWORKSDKDIR'):
- include_paths.append( os.path.join( paths['FRAMEWORKSDKDIR'], 'include' ) )
- lib_paths.append( os.path.join( paths['FRAMEWORKSDKDIR'], 'lib' ) )
- exe_paths.append( paths['FRAMEWORKSDKDIR'], 'bin' )
+ fwdir = paths['FRAMEWORKSDKDIR']
+ include_paths.append( os.path.join( fwdir, 'include' ) )
+ lib_paths.append( os.path.join( fwdir, 'lib' ) )
+ exe_paths.append( os.path.join( fwdir, 'bin' ) )
if SCons.Util.can_read_reg and paths.has_key('FRAMEWORKDIR') and paths.has_key('FRAMEWORKVERSION'):
exe_paths.append( os.path.join( paths['FRAMEWORKDIR'], paths['FRAMEWORKVERSION'] ) )
emitter=pch_emitter,
source_scanner=SCons.Tool.SourceFileScanner)
res_action = SCons.Action.Action('$RCCOM', '$RCCOMSTR')
-res_builder = SCons.Builder.Builder(action=res_action, suffix='.res',
+res_builder = SCons.Builder.Builder(action=res_action,
+ src_suffix='.rc',
+ suffix='.res',
+ src_builder=[],
source_scanner=SCons.Tool.SourceFileScanner)
SCons.Tool.SourceFileScanner.add_scanner('.rc', SCons.Defaults.CScan)
</summary>
</builder>
+<cvar name="CCPCHFLAGS">
+<summary>
+Options added to the compiler command line
+to support building with precompiled headers.
+The default value expands expands to the appropriate
+Microsoft Visual C++ command-line options
+when the &cv-PCH; construction variable is set.
+</summary>
+
+<cvar name="CCPDBFLAGS">
+<summary>
+Options added to the compiler command line
+to support storing debugging information in a
+Microsoft Visual C++ PDB file.
+The default value expands expands to appropriate
+Microsoft Visual C++ command-line options
+when the &cv-PDB; construction variable is set.
+
+The Visual C++ compiler option that SCons uses by default
+to generate PDB information is <option>/Z7</option>.
+This works correctly with parallel (<option>-j</option>) builds
+because it embeds the debug information in the intermediate object files,
+as opposed to sharing a single PDB file between multiple object files.
+This is also the only way to get debug information
+embedded into a static library.
+Using the <option>/Zi</option> instead may yield improved
+link-time performance,
+although parallel builds will no longer work.
+
+You can generate PDB files with the <option>/Zi</option>
+switch by overriding the default &cv-CCPDBFLAGS; variable as follows:
+
+<example>
+import SCons.Util
+env['CCPDBFLAGS'] = SCons.Util.CLVar(['${(PDB and "/Zi /Fd%s" % File(PDB)) or ""}'])
+</example>
+
+An alternative would be to use the <option>/Zi</option>
+to put the debugging information in a separate <filename>.pdb</filename>
+file for each object file by overriding
+the &cv-CCPDBFLAGS; variable as follows:
+
+<example>
+env['CCPDBFLAGS'] = '/Zi /Fd${TARGET}.pdb'
+</example>
+</summary>
+
<cvar name="PCH">
<summary>
The Microsoft Visual C++ precompiled header that will be used when compiling
for n in sourcenames:
self.sources[n].sort(lambda a, b: cmp(a.lower(), b.lower()))
- def AddConfig(variant, buildtarget, outdir, runfile, cmdargs):
+ def AddConfig(self, variant, buildtarget, outdir, runfile, cmdargs, dspfile=dspfile):
config = Config()
config.buildtarget = buildtarget
config.outdir = outdir
print "Adding '" + self.name + ' - ' + config.variant + '|' + config.platform + "' to '" + str(dspfile) + "'"
for i in range(len(variants)):
- AddConfig(variants[i], buildtarget[i], outdir[i], runfile[i], cmdargs)
+ AddConfig(self, variants[i], buildtarget[i], outdir[i], runfile[i], cmdargs)
self.platforms = []
for key in self.configs.keys():
pdata = base64.encodestring(pdata)
self.file.write(pdata + '-->\n')
+ def printSources(self, hierarchy, commonprefix):
+ sorteditems = hierarchy.items()
+ sorteditems.sort(lambda a, b: cmp(a[0].lower(), b[0].lower()))
+
+ # First folders, then files
+ for key, value in sorteditems:
+ if SCons.Util.is_Dict(value):
+ self.file.write('\t\t\t<Filter\n'
+ '\t\t\t\tName="%s"\n'
+ '\t\t\t\tFilter="">\n' % (key))
+ self.printSources(value, commonprefix)
+ self.file.write('\t\t\t</Filter>\n')
+
+ for key, value in sorteditems:
+ if SCons.Util.is_String(value):
+ file = value
+ if commonprefix:
+ file = os.path.join(commonprefix, value)
+ file = os.path.normpath(file)
+ self.file.write('\t\t\t<File\n'
+ '\t\t\t\tRelativePath="%s">\n'
+ '\t\t\t</File>\n' % (file))
+
def PrintSourceFiles(self):
categories = {'Source Files': 'cpp;c;cxx;l;y;def;odl;idl;hpj;bat',
'Header Files': 'h;hpp;hxx;hm;inl',
'\t\t\tName="%s"\n'
'\t\t\tFilter="%s">\n' % (kind, categories[kind]))
-
- def printSources(hierarchy, commonprefix):
- sorteditems = hierarchy.items()
- sorteditems.sort(lambda a, b: cmp(a[0].lower(), b[0].lower()))
-
- # First folders, then files
- for key, value in sorteditems:
- if SCons.Util.is_Dict(value):
- self.file.write('\t\t\t<Filter\n'
- '\t\t\t\tName="%s"\n'
- '\t\t\t\tFilter="">\n' % (key))
- printSources(value, commonprefix)
- self.file.write('\t\t\t</Filter>\n')
-
- for key, value in sorteditems:
- if SCons.Util.is_String(value):
- file = value
- if commonprefix:
- file = os.path.join(commonprefix, value)
- file = os.path.normpath(file)
- self.file.write('\t\t\t<File\n'
- '\t\t\t\tRelativePath="%s">\n'
- '\t\t\t</File>\n' % (file))
-
sources = self.sources[kind]
# First remove any common prefix
commonprefix = None
if len(sources) > 1:
s = map(os.path.normpath, sources)
- cp = os.path.commonprefix(s)
+ # take the dirname because the prefix may include parts
+ # of the filenames (e.g. if you have 'dir\abcd' and
+ # 'dir\acde' then the cp will be 'dir\a' )
+ cp = os.path.dirname( os.path.commonprefix(s) )
if cp and s[0][len(cp)] == os.sep:
- sources = map(lambda s, l=len(cp): s[l:], sources)
+ # +1 because the filename starts after the separator
+ sources = map(lambda s, l=len(cp)+1: s[l:], sources)
commonprefix = cp
+ elif len(sources) == 1:
+ commonprefix = os.path.dirname( sources[0] )
+ sources[0] = os.path.basename( sources[0] )
hierarchy = makeHierarchy(sources)
- printSources(hierarchy, commonprefix=commonprefix)
+ self.printSources(hierarchy, commonprefix=commonprefix)
if len(cats)>1:
self.file.write('\t\t</Filter>\n')
if self.nokeep == 0 and os.path.exists(self.dswfile):
self.Parse()
- def AddConfig(variant):
+ def AddConfig(self, variant, dswfile=dswfile):
config = Config()
match = re.match('(.*)\|(.*)', variant)
"You must specify a 'variant' argument (i.e. 'Debug' or " +\
"'Release') to create an MSVS Solution File."
elif SCons.Util.is_String(env['variant']):
- AddConfig(env['variant'])
+ AddConfig(self, env['variant'])
elif SCons.Util.is_List(env['variant']):
for variant in env['variant']:
- AddConfig(variant)
+ AddConfig(self, variant)
self.platforms = []
for key in self.configs.keys():
def get_default_visualstudio_version(env):
"""Returns the version set in the env, or the latest version
installed, if it can find it, or '6.0' if all else fails. Also
- updated the environment with what it found."""
+ updates the environment with what it found."""
- version = '6.0'
- versions = [version]
+ versions = ['6.0']
if not env.has_key('MSVS') or not SCons.Util.is_Dict(env['MSVS']):
- env['MSVS'] = {}
-
- if env['MSVS'].has_key('VERSIONS'):
- versions = env['MSVS']['VERSIONS']
- elif SCons.Util.can_read_reg:
- v = get_visualstudio_versions()
- if v:
- versions = v
- if env.has_key('MSVS_VERSION'):
- version = env['MSVS_VERSION']
- else:
- version = versions[0] #use highest version by default
-
- env['MSVS_VERSION'] = version
- env['MSVS']['VERSIONS'] = versions
- env['MSVS']['VERSION'] = version
+ v = get_visualstudio_versions()
+ if v:
+ versions = v
+ env['MSVS'] = {'VERSIONS' : versions}
else:
- version = env['MSVS']['VERSION']
+ versions = env['MSVS'].get('VERSIONS', versions)
+
+ if not env.has_key('MSVS_VERSION'):
+ env['MSVS_VERSION'] = versions[0] #use highest version by default
+
+ env['MSVS']['VERSION'] = env['MSVS_VERSION']
- return version
+ return env['MSVS_VERSION']
def get_visualstudio_versions():
"""
assert env['MSVS']['VERSION'] == '7.0', env['MSVS']['VERSION']
assert v2 == '7.0', v2
+ env = DummyEnv()
+ v3 = get_default_visualstudio_version(env)
+ if v3 == '7.1':
+ override = '7.0'
+ else:
+ override = '7.1'
+ env['MSVS_VERSION'] = override
+ v3 = get_default_visualstudio_version(env)
+ assert env['MSVS_VERSION'] == override, env['MSVS_VERSION']
+ assert env['MSVS']['VERSION'] == override, env['MSVS']['VERSION']
+ assert v3 == override, v3
+
def test_get_visual_studio_versions(self):
"""Test retrieval of the list of visual studio versions"""
v1 = get_visualstudio_versions()
--- /dev/null
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+__doc__ = """
+SCons C Pre-Processor module
+"""
+
+import os
+import re
+import string
+import sys
+
+
+
+import __builtin__
+try:
+ __builtin__.zip
+except AttributeError:
+ def zip(*lists):
+ result = []
+ for i in xrange(len(lists[0])):
+ result.append(tuple(map(lambda l, i=i: l[i], lists)))
+ return result
+
+
+
+#
+# First "subsystem" of regular expressions that we set up:
+#
+# Stuff to turn the C preprocessor directives in a file's contents into
+# a list of tuples that we can process easily.
+#
+
+# A table of regular expressions that fetch the arguments from the rest of
+# a C preprocessor line. Different directives have different arguments
+# that we want to fetch, using the regular expressions to which the lists
+# of preprocessor directives map.
+cpp_lines_dict = {
+ # Fetch the rest of a #if/#elif/#ifdef/#ifndef/#import/#include/
+ # #include_next line as one argument.
+ ('if', 'elif', 'ifdef', 'ifndef', 'import', 'include', 'include_next',)
+ : '\s+(.+)',
+
+ # We don't care what comes after a #else or #endif line.
+ ('else', 'endif',) : '',
+
+ # Fetch three arguments from a #define line:
+ # 1) The #defined keyword.
+ # 2) The optional parentheses and arguments (if it's a function-like
+ # macro, '' if it's not).
+ # 3) The expansion value.
+ ('define',) : '\s+([_A-Za-z][_A-Za-z0-9_]+)(\([^)]*\))?\s*(.*)',
+
+ # Fetch the #undefed keyword from a #undef line.
+ ('undef',) : '\s+([_A-Za-z][A-Za-z0-9_]+)',
+}
+
+# Create a table that maps each individual C preprocessor directive to
+# the corresponding compiled regular expression that fetches the arguments
+# we care about.
+Table = {}
+for op_list, expr in cpp_lines_dict.items():
+ e = re.compile(expr)
+ for op in op_list:
+ Table[op] = e
+del e
+del op
+del op_list
+
+# Create a list of the expressions we'll use to match all of the
+# preprocessor directives. These are the same as the directives
+# themselves *except* that we must use a negative lookahead assertion
+# when matching "if" so it doesn't match the "if" in "ifdef."
+override = {
+ 'if' : 'if(?!def)',
+}
+l = map(lambda x, o=override: o.get(x, x), Table.keys())
+
+
+# Turn the list of expressions into one big honkin' regular expression
+# that will match all the preprocessor lines at once. This will return
+# a list of tuples, one for each preprocessor line. The preprocessor
+# directive will be the first element in each tuple, and the rest of
+# the line will be the second element.
+e = '^\s*#\s*(' + string.join(l, '|') + ')(.*)$'
+
+# And last but not least, compile the expression.
+CPP_Expression = re.compile(e, re.M)
+
+
+
+
+#
+# Second "subsystem" of regular expressions that we set up:
+#
+# Stuff to translate a C preprocessor expression (as found on a #if or
+# #elif line) into an equivalent Python expression that we can eval().
+#
+
+# A dictionary that maps the C representation of Boolean operators
+# to their Python equivalents.
+CPP_to_Python_Ops_Dict = {
+ '!' : ' not ',
+ '!=' : ' != ',
+ '&&' : ' and ',
+ '||' : ' or ',
+ '?' : ' and ',
+ ':' : ' or ',
+ '\r' : '',
+}
+
+CPP_to_Python_Ops_Sub = lambda m, d=CPP_to_Python_Ops_Dict: d[m.group(0)]
+
+# We have to sort the keys by length so that longer expressions
+# come *before* shorter expressions--in particular, "!=" must
+# come before "!" in the alternation. Without this, the Python
+# re module, as late as version 2.2.2, empirically matches the
+# "!" in "!=" first, instead of finding the longest match.
+# What's up with that?
+l = CPP_to_Python_Ops_Dict.keys()
+l.sort(lambda a, b: cmp(len(b), len(a)))
+
+# Turn the list of keys into one regular expression that will allow us
+# to substitute all of the operators at once.
+expr = string.join(map(re.escape, l), '|')
+
+# ...and compile the expression.
+CPP_to_Python_Ops_Expression = re.compile(expr)
+
+# A separate list of expressions to be evaluated and substituted
+# sequentially, not all at once.
+CPP_to_Python_Eval_List = [
+ ['defined\s+(\w+)', '__dict__.has_key("\\1")'],
+ ['defined\s*\((\w+)\)', '__dict__.has_key("\\1")'],
+ ['/\*.*\*/', ''],
+ ['/\*.*', ''],
+ ['//.*', ''],
+ ['(0x[0-9A-Fa-f]*)[UL]+', '\\1L'],
+]
+
+# Replace the string representations of the regular expressions in the
+# list with compiled versions.
+for l in CPP_to_Python_Eval_List:
+ l[0] = re.compile(l[0])
+
+# Wrap up all of the above into a handy function.
+def CPP_to_Python(s):
+ """
+ Converts a C pre-processor expression into an equivalent
+ Python expression that can be evaluated.
+ """
+ s = CPP_to_Python_Ops_Expression.sub(CPP_to_Python_Ops_Sub, s)
+ for expr, repl in CPP_to_Python_Eval_List:
+ s = expr.sub(repl, s)
+ return s
+
+
+
+del expr
+del l
+del override
+
+
+
+class FunctionEvaluator:
+ """
+ Handles delayed evaluation of a #define function call.
+ """
+ def __init__(self, name, args, expansion):
+ """
+ Squirrels away the arguments and expansion value of a #define
+ macro function for later evaluation when we must actually expand
+ a value that uses it.
+ """
+ self.name = name
+ self.args = function_arg_separator.split(args)
+ self.expansion = string.split(expansion, '##')
+ def __call__(self, *values):
+ """
+ Evaluates the expansion of a #define macro function called
+ with the specified values.
+ """
+ if len(self.args) != len(values):
+ raise ValueError, "Incorrect number of arguments to `%s'" % self.name
+ # Create a dictionary that maps the macro arguments to the
+ # corresponding values in this "call." We'll use this when we
+ # eval() the expansion so that arguments will get expanded to
+ # the right values.
+ locals = {}
+ for k, v in zip(self.args, values):
+ locals[k] = v
+
+ parts = []
+ for s in self.expansion:
+ if not s in self.args:
+ s = repr(s)
+ parts.append(s)
+ statement = string.join(parts, ' + ')
+
+ return eval(statement, globals(), locals)
+
+
+
+# Find line continuations.
+line_continuations = re.compile('\\\\\r?\n')
+
+# Search for a "function call" macro on an expansion. Returns the
+# two-tuple of the "function" name itself, and a string containing the
+# arguments within the call parentheses.
+function_name = re.compile('(\S+)\(([^)]*)\)')
+
+# Split a string containing comma-separated function call arguments into
+# the separate arguments.
+function_arg_separator = re.compile(',\s*')
+
+
+
+class PreProcessor:
+ """
+ The main workhorse class for handling C pre-processing.
+ """
+ def __init__(self, current='.', cpppath=[], dict={}, all=0):
+ global Table
+
+ self.searchpath = {
+ '"' : [current] + cpppath,
+ '<' : cpppath + [current],
+ }
+
+ # Initialize our C preprocessor namespace for tracking the
+ # values of #defined keywords. We use this namespace to look
+ # for keywords on #ifdef/#ifndef lines, and to eval() the
+ # expressions on #if/#elif lines (after massaging them from C to
+ # Python).
+ self.cpp_namespace = dict.copy()
+ self.cpp_namespace['__dict__'] = self.cpp_namespace
+
+ if all:
+ self.do_include = self.all_include
+
+ # For efficiency, a dispatch table maps each C preprocessor
+ # directive (#if, #define, etc.) to the method that should be
+ # called when we see it. We accomodate state changes (#if,
+ # #ifdef, #ifndef) by pushing the current dispatch table on a
+ # stack and changing what method gets called for each relevant
+ # directive we might see next at this level (#else, #elif).
+ # #endif will simply pop the stack.
+ d = {}
+ for op in Table.keys():
+ d[op] = getattr(self, 'do_' + op)
+ self.default_table = d
+
+ # Controlling methods.
+
+ def tupleize(self, contents):
+ """
+ Turns the contents of a file into a list of easily-processed
+ tuples describing the CPP lines in the file.
+
+ The first element of each tuple is the line's preprocessor
+ directive (#if, #include, #define, etc., minus the initial '#').
+ The remaining elements are specific to the type of directive, as
+ pulled apart by the regular expression.
+ """
+ global CPP_Expression, Table
+ contents = line_continuations.sub('', contents)
+ cpp_tuples = CPP_Expression.findall(contents)
+ return map(lambda m, t=Table:
+ (m[0],) + t[m[0]].match(m[1]).groups(),
+ cpp_tuples)
+
+ def __call__(self, contents):
+ """
+ Pre-processes a file contents.
+
+ This is the main entry point, which
+ """
+ self.stack = []
+ self.dispatch_table = self.default_table.copy()
+ self.tuples = self.tupleize(contents)
+
+ self.result = []
+ while self.tuples:
+ t = self.tuples.pop(0)
+ # Uncomment to see the list of tuples being processed (e.g.,
+ # to validate the CPP lines are being translated correctly).
+ #print t
+ self.dispatch_table[t[0]](t)
+
+ return self.result
+
+ # Dispatch table stack manipulation methods.
+
+ def save(self):
+ """
+ Pushes the current dispatch table on the stack and re-initializes
+ the current dispatch table to the default.
+ """
+ self.stack.append(self.dispatch_table)
+ self.dispatch_table = self.default_table.copy()
+
+ def restore(self):
+ """
+ Pops the previous dispatch table off the stack and makes it the
+ current one.
+ """
+ try: self.dispatch_table = self.stack.pop()
+ except IndexError: pass
+
+ # Utility methods.
+
+ def do_nothing(self, t):
+ """
+ Null method for when we explicitly want the action for a
+ specific preprocessor directive to do nothing.
+ """
+ pass
+
+ def eval_expression(self, t):
+ """
+ Evaluates a C preprocessor expression.
+
+ This is done by converting it to a Python equivalent and
+ eval()ing it in the C preprocessor namespace we use to
+ track #define values.
+ """
+ t = CPP_to_Python(string.join(t[1:]))
+ try: return eval(t, self.cpp_namespace)
+ except (NameError, TypeError): return 0
+
+ def find_include_file(self, t):
+ """
+ Finds the #include file for a given preprocessor tuple.
+ """
+ fname = t[2]
+ for d in self.searchpath[t[1]]:
+ f = os.path.join(d, fname)
+ if os.path.isfile(f):
+ return f
+ return None
+
+ # Start and stop processing include lines.
+
+ def start_handling_includes(self, t=None):
+ """
+ Causes the PreProcessor object to start processing #import,
+ #include and #include_next lines.
+
+ This method will be called when a #if, #ifdef, #ifndef or #elif
+ evaluates True, or when we reach the #else in a #if, #ifdef,
+ #ifndef or #elif block where a condition already evaluated
+ False.
+
+ """
+ d = self.dispatch_table
+ d['import'] = self.do_import
+ d['include'] = self.do_include
+ d['include_next'] = self.do_include
+
+ def stop_handling_includes(self, t=None):
+ """
+ Causes the PreProcessor object to stop processing #import,
+ #include and #include_next lines.
+
+ This method will be called when a #if, #ifdef, #ifndef or #elif
+ evaluates False, or when we reach the #else in a #if, #ifdef,
+ #ifndef or #elif block where a condition already evaluated True.
+ """
+ d = self.dispatch_table
+ d['import'] = self.do_nothing
+ d['include'] = self.do_nothing
+ d['include_next'] = self.do_nothing
+
+ # Default methods for handling all of the preprocessor directives.
+ # (Note that what actually gets called for a given directive at any
+ # point in time is really controlled by the dispatch_table.)
+
+ def _do_if_else_condition(self, condition):
+ """
+ Common logic for evaluating the conditions on #if, #ifdef and
+ #ifndef lines.
+ """
+ self.save()
+ d = self.dispatch_table
+ if condition:
+ self.start_handling_includes()
+ d['elif'] = self.stop_handling_includes
+ d['else'] = self.stop_handling_includes
+ else:
+ self.stop_handling_includes()
+ d['elif'] = self.do_elif
+ d['else'] = self.start_handling_includes
+
+ def do_ifdef(self, t):
+ """
+ Default handling of a #ifdef line.
+ """
+ self._do_if_else_condition(self.cpp_namespace.has_key(t[1]))
+
+ def do_ifndef(self, t):
+ """
+ Default handling of a #ifndef line.
+ """
+ self._do_if_else_condition(not self.cpp_namespace.has_key(t[1]))
+
+ def do_if(self, t):
+ """
+ Default handling of a #if line.
+ """
+ self._do_if_else_condition(self.eval_expression(t))
+
+ def do_elif(self, t):
+ """
+ Default handling of a #elif line.
+ """
+ d = self.dispatch_table
+ if self.eval_expression(t):
+ self.start_handling_includes()
+ d['elif'] = self.stop_handling_includes
+ d['else'] = self.stop_handling_includes
+
+ def do_else(self, t):
+ """
+ Default handling of a #else line.
+ """
+ pass
+
+ def do_endif(self, t):
+ """
+ Default handling of a #endif line.
+ """
+ self.restore()
+
+ def do_define(self, t):
+ """
+ Default handling of a #define line.
+ """
+ _, name, args, expansion = t
+ try:
+ expansion = int(expansion)
+ except (TypeError, ValueError):
+ pass
+ if args:
+ evaluator = FunctionEvaluator(name, args[1:-1], expansion)
+ self.cpp_namespace[name] = evaluator
+ else:
+ self.cpp_namespace[name] = expansion
+
+ def do_undef(self, t):
+ """
+ Default handling of a #undef line.
+ """
+ try: del self.cpp_namespace[t[1]]
+ except KeyError: pass
+
+ def do_import(self, t):
+ """
+ Default handling of a #import line.
+ """
+ # XXX finish this -- maybe borrow/share logic from do_include()...?
+ pass
+
+ def do_include(self, t):
+ """
+ Default handling of a #include line.
+ """
+ t = self.resolve_include(t)
+ include_file = self.find_include_file(t)
+ if include_file:
+ #print "include_file =", include_file
+ self.result.append(include_file)
+ contents = open(include_file).read()
+ new_tuples = self.tupleize(contents)
+ self.tuples[:] = new_tuples + self.tuples
+
+ # Date: Tue, 22 Nov 2005 20:26:09 -0500
+ # From: Stefan Seefeld <seefeld@sympatico.ca>
+ #
+ # By the way, #include_next is not the same as #include. The difference
+ # being that #include_next starts its search in the path following the
+ # path that let to the including file. In other words, if your system
+ # include paths are ['/foo', '/bar'], and you are looking at a header
+ # '/foo/baz.h', it might issue an '#include_next <baz.h>' which would
+ # correctly resolve to '/bar/baz.h' (if that exists), but *not* see
+ # '/foo/baz.h' again. See http://www.delorie.com/gnu/docs/gcc/cpp_11.html
+ # for more reasoning.
+ #
+ # I have no idea in what context 'import' might be used.
+
+ # XXX is #include_next really the same as #include ?
+ do_include_next = do_include
+
+ # Utility methods for handling resolution of include files.
+
+ def resolve_include(self, t):
+ """Resolve a tuple-ized #include line.
+
+ This handles recursive expansion of values without "" or <>
+ surrounding the name until an initial " or < is found, to handle
+ #include FILE
+ where FILE is a #define somewhere else.
+ """
+ s = t[1]
+ while not s[0] in '<"':
+ #print "s =", s
+ try:
+ s = self.cpp_namespace[s]
+ except KeyError:
+ m = function_name.search(s)
+ s = self.cpp_namespace[m.group(1)]
+ if callable(s):
+ args = function_arg_separator.split(m.group(2))
+ s = apply(s, args)
+ if not s:
+ return None
+ return (t[0], s[0], s[1:-1])
+
+ def all_include(self, t):
+ """
+ """
+ self.result.append(self.resolve_include(t))
+
+class DumbPreProcessor(PreProcessor):
+ """A preprocessor that ignores all #if/#elif/#else/#endif directives
+ and just reports back *all* of the #include files (like the classic
+ SCons scanner did).
+
+ This is functionally equivalent to using a regular expression to
+ find all of the #include lines, only slower. It exists mainly as
+ an example of how the main PreProcessor class can be sub-classed
+ to tailor its behavior.
+ """
+ def __init__(self, *args, **kw):
+ apply(PreProcessor.__init__, (self,)+args, kw)
+ d = self.default_table
+ for func in ['if', 'elif', 'else', 'endif', 'ifdef', 'ifndef']:
+ d[func] = d[func] = self.do_nothing
+
+del __revision__
--- /dev/null
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import sys
+import unittest
+
+print sys.path
+import cpp
+
+
+
+basic_input = """
+#include "file1-yes"
+#include <file2-yes>
+"""
+
+
+substitution_input = """
+#define FILE3 "file3-yes"
+#define FILE4 <file4-yes>
+
+#include FILE3
+#include FILE4
+
+#define XXX_FILE5 YYY_FILE5
+#define YYY_FILE5 ZZZ_FILE5
+#define ZZZ_FILE5 FILE5
+
+#define FILE5 "file5-yes"
+#define FILE6 <file6-yes>
+
+#define XXX_FILE6 YYY_FILE6
+#define YYY_FILE6 ZZZ_FILE6
+#define ZZZ_FILE6 FILE6
+
+#include XXX_FILE5
+#include XXX_FILE6
+"""
+
+
+ifdef_input = """
+#define DEFINED 0
+
+#ifdef DEFINED
+#include "file7-yes"
+#else
+#include "file7-no"
+#endif
+
+#ifdef NOT_DEFINED
+#include <file8-no>
+#else
+#include <file8-yes>
+#endif
+"""
+
+
+if_boolean_input = """
+#define ZERO 0
+#define ONE 1
+
+#if ZERO
+#include "file9-no"
+#else
+#include "file9-yes"
+#endif
+
+#if ONE
+#include <file10-yes>
+#else
+#include <file10-no>
+#endif
+
+#if ZERO
+#include "file11-no-1"
+#elif ZERO
+#include "file11-no-2"
+#else
+#include "file11-yes"
+#endif
+
+#if ZERO
+#include <file12-no-1>
+#elif ONE
+#include <file12-yes>
+#else
+#include <file12-no-2>
+#endif
+
+#if ONE
+#include "file13-yes"
+#elif ZERO
+#include "file13-no-1"
+#else
+#include "file13-no-2"
+#endif
+
+#if ONE
+#include <file14-yes>
+#elif ONE
+#include <file14-no-1>
+#else
+#include <file14-no-2>
+#endif
+"""
+
+
+if_defined_input = """
+#define DEFINED 0
+
+#if defined(DEFINED)
+#include "file15-yes"
+#endif
+
+#if ! defined(DEFINED)
+#include <file16-no>
+#else
+#include <file16-yes>
+#endif
+
+#if defined DEFINED
+#include "file17-yes"
+#endif
+
+#if ! defined DEFINED
+#include <file18-no>
+#else
+#include <file18-yes>
+#endif
+"""
+
+
+expression_input = """
+#define ZERO 0
+#define ONE 1
+
+#if ZERO && ZERO
+#include "file19-no"
+#else
+#include "file19-yes"
+#endif
+
+#if ZERO && ONE
+#include <file20-no>
+#else
+#include <file20-yes>
+#endif
+
+#if ONE && ZERO
+#include "file21-no"
+#else
+#include "file21-yes"
+#endif
+
+#if ONE && ONE
+#include <file22-yes>
+#else
+#include <file22-no>
+#endif
+
+#if ZERO || ZERO
+#include "file23-no"
+#else
+#include "file23-yes"
+#endif
+
+#if ZERO || ONE
+#include <file24-yes>
+#else
+#include <file24-no>
+#endif
+
+#if ONE || ZERO
+#include "file25-yes"
+#else
+#include "file25-no"
+#endif
+
+#if ONE || ONE
+#include <file26-yes>
+#else
+#include <file26-no>
+#endif
+
+#if ONE == ONE
+#include "file27-yes"
+#else
+#include "file27-no"
+#endif
+
+#if ONE != ONE
+#include <file28-no>
+#else
+#include <file28-yes>
+#endif
+
+#if ! (ONE == ONE)
+#include "file29-no"
+#else
+#include "file29-yes"
+#endif
+
+#if ! (ONE != ONE)
+#include <file30-yes>
+#else
+#include <file30-no>
+#endif
+"""
+
+
+undef_input = """
+#define UNDEFINE 0
+
+#ifdef UNDEFINE
+#include "file31-yes"
+#else
+#include "file31-no"
+#endif
+
+#undef UNDEFINE
+
+#ifdef UNDEFINE
+#include <file32-no>
+#else
+#include <file32-yes>
+#endif
+"""
+
+
+macro_function_input = """
+#define ZERO 0
+#define ONE 1
+
+#define FUNC33(x) "file33-yes"
+#define FUNC34(x) <file34-yes>
+
+#include FUNC33(ZERO)
+#include FUNC34(ZERO)
+
+#define FILE35 "file35-yes"
+#define FILE36 <file36-yes>
+
+#define FUNC35(x, y) FILE35
+#define FUNC36(x, y) FILE36
+
+#include FUNC35(ZERO, ONE)
+#include FUNC36(ZERO, ONE)
+
+#define FILE37 "file37-yes"
+#define FILE38 <file38-yes>
+
+#define FUNC37a(x, y) FILE37
+#define FUNC38a(x, y) FILE38
+
+#define FUNC37b(x, y) FUNC37a(x, y)
+#define FUNC38b(x, y) FUNC38a(x, y)
+
+#define FUNC37c(x, y) FUNC37b(x, y)
+#define FUNC38c(x, y) FUNC38b(x, y)
+
+#include FUNC37c(ZERO, ONE)
+#include FUNC38c(ZERO, ONE)
+
+#define FILE39 "file39-yes"
+#define FILE40 <file40-yes>
+
+#define FUNC39a(x0, y0) FILE39
+#define FUNC40a(x0, y0) FILE40
+
+#define FUNC39b(x1, y2) FUNC39a(x1, y1)
+#define FUNC40b(x1, y2) FUNC40a(x1, y1)
+
+#define FUNC39c(x2, y2) FUNC39b(x2, y2)
+#define FUNC40c(x2, y2) FUNC40b(x2, y2)
+
+#include FUNC39c(ZERO, ONE)
+#include FUNC40c(ZERO, ONE)
+"""
+
+
+token_pasting_input = """
+#define PASTE_QUOTE(q, name) q##name##-yes##q
+#define PASTE_ANGLE(name) <##name##-yes>
+
+#define FUNC41 PASTE_QUOTE(", file41)
+#define FUNC42 PASTE_ANGLE(file42)
+
+#include FUNC41
+#include FUNC42
+"""
+
+
+
+# pp_class = PreProcessor
+# #pp_class = DumbPreProcessor
+
+# pp = pp_class(current = ".",
+# cpppath = ['/usr/include'],
+# print_all = 1)
+# #pp(open(sys.argv[1]).read())
+# pp(input)
+
+
+class cppTestCase(unittest.TestCase):
+ def setUp(self):
+ self.cpp = self.cpp_class(current = ".",
+ cpppath = ['/usr/include'])
+
+ def test_basic(self):
+ """Test basic #include scanning"""
+ expect = self.basic_expect
+ result = self.cpp(basic_input)
+ assert expect == result, (expect, result)
+
+ def test_substitution(self):
+ """Test substitution of #include files using CPP variables"""
+ expect = self.substitution_expect
+ result = self.cpp(substitution_input)
+ assert expect == result, (expect, result)
+
+ def test_ifdef(self):
+ """Test basic #ifdef processing"""
+ expect = self.ifdef_expect
+ result = self.cpp(ifdef_input)
+ assert expect == result, (expect, result)
+
+ def test_if_boolean(self):
+ """Test #if with Boolean values"""
+ expect = self.if_boolean_expect
+ result = self.cpp(if_boolean_input)
+ assert expect == result, (expect, result)
+
+ def test_if_defined(self):
+ """Test #if defined() idioms"""
+ expect = self.if_defined_expect
+ result = self.cpp(if_defined_input)
+ assert expect == result, (expect, result)
+
+ def test_expression(self):
+ """Test #if with arithmetic expressions"""
+ expect = self.expression_expect
+ result = self.cpp(expression_input)
+ assert expect == result, (expect, result)
+
+ def test_undef(self):
+ """Test #undef handling"""
+ expect = self.undef_expect
+ result = self.cpp(undef_input)
+ assert expect == result, (expect, result)
+
+ def test_macro_function(self):
+ """Test using macro functions to express file names"""
+ expect = self.macro_function_expect
+ result = self.cpp(macro_function_input)
+ assert expect == result, (expect, result)
+
+ def test_token_pasting(self):
+ """Test taken-pasting to construct file names"""
+ expect = self.token_pasting_expect
+ result = self.cpp(token_pasting_input)
+ assert expect == result, (expect, result)
+
+class cppAllTestCase(cppTestCase):
+ def setUp(self):
+ self.cpp = self.cpp_class(current = ".",
+ cpppath = ['/usr/include'],
+ all=1)
+
+class PreProcessorTestCase(cppAllTestCase):
+ cpp_class = cpp.PreProcessor
+
+ basic_expect = [
+ ('include', '"', 'file1-yes'),
+ ('include', '<', 'file2-yes'),
+ ]
+
+ substitution_expect = [
+ ('include', '"', 'file3-yes'),
+ ('include', '<', 'file4-yes'),
+ ('include', '"', 'file5-yes'),
+ ('include', '<', 'file6-yes'),
+ ]
+
+ ifdef_expect = [
+ ('include', '"', 'file7-yes'),
+ ('include', '<', 'file8-yes'),
+ ]
+
+ if_boolean_expect = [
+ ('include', '"', 'file9-yes'),
+ ('include', '<', 'file10-yes'),
+ ('include', '"', 'file11-yes'),
+ ('include', '<', 'file12-yes'),
+ ('include', '"', 'file13-yes'),
+ ('include', '<', 'file14-yes'),
+ ]
+
+ if_defined_expect = [
+ ('include', '"', 'file15-yes'),
+ ('include', '<', 'file16-yes'),
+ ('include', '"', 'file17-yes'),
+ ('include', '<', 'file18-yes'),
+ ]
+
+ expression_expect = [
+ ('include', '"', 'file19-yes'),
+ ('include', '<', 'file20-yes'),
+ ('include', '"', 'file21-yes'),
+ ('include', '<', 'file22-yes'),
+ ('include', '"', 'file23-yes'),
+ ('include', '<', 'file24-yes'),
+ ('include', '"', 'file25-yes'),
+ ('include', '<', 'file26-yes'),
+ ('include', '"', 'file27-yes'),
+ ('include', '<', 'file28-yes'),
+ ('include', '"', 'file29-yes'),
+ ('include', '<', 'file30-yes'),
+ ]
+
+ undef_expect = [
+ ('include', '"', 'file31-yes'),
+ ('include', '<', 'file32-yes'),
+ ]
+
+ macro_function_expect = [
+ ('include', '"', 'file33-yes'),
+ ('include', '<', 'file34-yes'),
+ ('include', '"', 'file35-yes'),
+ ('include', '<', 'file36-yes'),
+ ('include', '"', 'file37-yes'),
+ ('include', '<', 'file38-yes'),
+ ('include', '"', 'file39-yes'),
+ ('include', '<', 'file40-yes'),
+ ]
+
+ token_pasting_expect = [
+ ('include', '"', 'file41-yes'),
+ ('include', '<', 'file42-yes'),
+ ]
+
+class DumbPreProcessorTestCase(cppAllTestCase):
+ cpp_class = cpp.DumbPreProcessor
+
+ basic_expect = [
+ ('include', '"', 'file1-yes'),
+ ('include', '<', 'file2-yes'),
+ ]
+
+ substitution_expect = [
+ ('include', '"', 'file3-yes'),
+ ('include', '<', 'file4-yes'),
+ ('include', '"', 'file5-yes'),
+ ('include', '<', 'file6-yes'),
+ ]
+
+ ifdef_expect = [
+ ('include', '"', 'file7-yes'),
+ ('include', '"', 'file7-no'),
+ ('include', '<', 'file8-no'),
+ ('include', '<', 'file8-yes'),
+ ]
+
+ if_boolean_expect = [
+ ('include', '"', 'file9-no'),
+ ('include', '"', 'file9-yes'),
+ ('include', '<', 'file10-yes'),
+ ('include', '<', 'file10-no'),
+ ('include', '"', 'file11-no-1'),
+ ('include', '"', 'file11-no-2'),
+ ('include', '"', 'file11-yes'),
+ ('include', '<', 'file12-no-1'),
+ ('include', '<', 'file12-yes'),
+ ('include', '<', 'file12-no-2'),
+ ('include', '"', 'file13-yes'),
+ ('include', '"', 'file13-no-1'),
+ ('include', '"', 'file13-no-2'),
+ ('include', '<', 'file14-yes'),
+ ('include', '<', 'file14-no-1'),
+ ('include', '<', 'file14-no-2'),
+ ]
+
+ if_defined_expect = [
+ ('include', '"', 'file15-yes'),
+ ('include', '<', 'file16-no'),
+ ('include', '<', 'file16-yes'),
+ ('include', '"', 'file17-yes'),
+ ('include', '<', 'file18-no'),
+ ('include', '<', 'file18-yes'),
+ ]
+
+ expression_expect = [
+ ('include', '"', 'file19-no'),
+ ('include', '"', 'file19-yes'),
+ ('include', '<', 'file20-no'),
+ ('include', '<', 'file20-yes'),
+ ('include', '"', 'file21-no'),
+ ('include', '"', 'file21-yes'),
+ ('include', '<', 'file22-yes'),
+ ('include', '<', 'file22-no'),
+ ('include', '"', 'file23-no'),
+ ('include', '"', 'file23-yes'),
+ ('include', '<', 'file24-yes'),
+ ('include', '<', 'file24-no'),
+ ('include', '"', 'file25-yes'),
+ ('include', '"', 'file25-no'),
+ ('include', '<', 'file26-yes'),
+ ('include', '<', 'file26-no'),
+ ('include', '"', 'file27-yes'),
+ ('include', '"', 'file27-no'),
+ ('include', '<', 'file28-no'),
+ ('include', '<', 'file28-yes'),
+ ('include', '"', 'file29-no'),
+ ('include', '"', 'file29-yes'),
+ ('include', '<', 'file30-yes'),
+ ('include', '<', 'file30-no'),
+ ]
+
+ undef_expect = [
+ ('include', '"', 'file31-yes'),
+ ('include', '"', 'file31-no'),
+ ('include', '<', 'file32-no'),
+ ('include', '<', 'file32-yes'),
+ ]
+
+ macro_function_expect = [
+ ('include', '"', 'file33-yes'),
+ ('include', '<', 'file34-yes'),
+ ('include', '"', 'file35-yes'),
+ ('include', '<', 'file36-yes'),
+ ('include', '"', 'file37-yes'),
+ ('include', '<', 'file38-yes'),
+ ('include', '"', 'file39-yes'),
+ ('include', '<', 'file40-yes'),
+ ]
+
+ token_pasting_expect = [
+ ('include', '"', 'file41-yes'),
+ ('include', '<', 'file42-yes'),
+ ]
+
+if __name__ == '__main__':
+ suite = unittest.TestSuite()
+ tclasses = [ PreProcessorTestCase,
+ DumbPreProcessorTestCase,
+ ]
+ for tclass in tclasses:
+ names = unittest.getTestCaseNames(tclass, 'test_')
+ suite.addTests(map(tclass, names))
+ if not unittest.TextTestRunner().run(suite).wasSuccessful():
+ sys.exit(1)
+
except KeyError:
cwd = os.getcwd()
-build_scons = os.path.join(cwd, 'build', 'scons')
-build_local = os.path.join(cwd, 'build', 'scons-local', 'scons-local-0.96.92')
-build_src = os.path.join(cwd, 'build', 'scons-src')
+def build_path(*args):
+ return apply(os.path.join, (cwd, 'build',)+args)
+
+build_scons = build_path('scons')
+build_local = build_path('scons-local', 'scons-local-'+test.scons_version)
+build_src = build_path('scons-src')
class Collect:
expression = re.compile('Copyright.*The SCons Foundation')
--- /dev/null
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Verify that we have certain important files in our distribution
+packages.
+
+Note that this is a packaging test, not a functional test, so the
+name of this script doesn't end in *Tests.py.
+"""
+
+import os
+import os.path
+import re
+import string
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+try:
+ cwd = os.environ['SCONS_CWD']
+except KeyError:
+ cwd = os.getcwd()
+
+def build_path(*args):
+ return apply(os.path.join, (cwd, 'build',) + args)
+
+build_scons_tar_gz = build_path('unpack-tar-gz', 'scons-'+test.scons_version)
+build_scons_zip = build_path('unpack-zip', 'scons-'+test.scons_version)
+build_local_tar_gz = build_path('test-local-tar-gz')
+build_local_zip = build_path('test-local-zip')
+
+scons_files = [
+ 'CHANGES.txt',
+ 'LICENSE.txt',
+ 'README.txt',
+ 'RELEASE.txt',
+]
+
+local_files = [
+ 'scons-LICENSE',
+ 'scons-README',
+]
+
+# Map each directory to search (dictionary keys) to a list of its
+# subsidiary files and directories to exclude from copyright checks.
+check = {
+ build_scons_tar_gz : scons_files,
+ build_scons_zip : scons_files,
+ build_local_tar_gz : local_files,
+ build_local_zip : local_files,
+}
+
+missing = []
+no_result = []
+
+for directory, check_list in check.items():
+ if os.path.exists(directory):
+ for c in check_list:
+ f = os.path.join(directory, c)
+ if not os.path.isfile(f):
+ missing.append(f)
+ else:
+ no_result.append(directory)
+
+if missing:
+ print "Missing the following files:\n"
+ print "\t" + string.join(missing, "\n\t")
+ test.fail_test(1)
+
+if no_result:
+ print "Cannot check files, the following have apparently not been built:"
+ print "\t" + string.join(no_result, "\n\t")
+ test.no_result(1)
+
+test.pass_test()
try: WindowsError
except NameError: WindowsError = OSError
-#try:
-# version = os.environ['SCONS_VERSION']
-#except KeyError:
-# version = '__VERSION__'
-version = '0.96.92'
+import TestSCons
-scons_version = 'scons-%s' % version
+version = TestSCons.TestSCons.scons_version
-import TestSCons
+scons_version = 'scons-%s' % version
python = TestSCons.python
os.system("gunzip -c %s | tar xf -" % tar_gz)
if not os.path.isdir(scons_version):
- print "Found neither SCons package `%s' nor `%s'." % (tar_gz, zip)
- print "Cannot test package installation."
+ print "Cannot test package installation, found none of the following packages:"
+ print "\t" + tar_gz
+ print "\t" + zip
test.no_result(1)
# Verify that a virgin installation installs the version library,
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
test = TestSCons.TestSCons()
test.write('SConstruct', """
foo = Environment(LIBS = ['foo'], LIBPATH = ['.'])
ar = foo.Dictionary('AR')
-bar = Environment(LIBS = ['bar'], LIBPATH = ['.'], AR = r'%s wrapper.py ' + ar)
+bar = Environment(LIBS = ['bar'], LIBPATH = ['.'], AR = r'%(_python_)s wrapper.py ' + ar)
foo.Library(target = 'foo', source = 'foo.c')
bar.Library(target = 'bar', source = 'bar.c')
foo.Program(target = 'f', source = obj)
bar.Program(target = 'b', source = obj)
-""" % python)
+""" % locals())
test.write('foo.c', r"""
+#include <stdio.h>
+
void
library_function(void)
{
""")
test.write('bar.c', r"""
+#include <stdio.h>
+
void
library_function(void)
{
""")
test.write('main.c', r"""
+#include <stdio.h>
+#include <stdlib.h>
+
int
main(int argc, char *argv[])
{
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(tools=['default', 'ar'],
- ARCOM = r'%s myar.py $TARGET $SOURCES',
- RANLIBCOM = r'%s myranlib.py $TARGET',
+ ARCOM = r'%(_python_)s myar.py $TARGET $SOURCES',
+ RANLIBCOM = r'%(_python_)s myranlib.py $TARGET',
LIBPREFIX = '',
LIBSUFFIX = '.lib')
env.Library(target = 'output', source = ['file.1', 'file.2'])
-""" % (python, python))
+""" % locals())
test.write('file.1', "file.1\n/*ar*/\n")
test.write('file.2', "file.2\n/*ar*/\n")
import TestSCons
import string
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(tools=['default', 'ar'],
- ARCOM = r'%s myar.py $TARGET $SOURCES',
+ ARCOM = r'%(_python_)s myar.py $TARGET $SOURCES',
ARCOMSTR = 'Archiving $TARGET from $SOURCES',
- RANLIBCOM = r'%s myranlib.py $TARGET',
+ RANLIBCOM = r'%(_python_)s myranlib.py $TARGET',
LIBPREFIX = '',
LIBSUFFIX = '.lib')
env.Library(target = 'output', source = ['file.1', 'file.2'])
-""" % (python, python))
+""" % locals())
test.write('file.1', "file.1\n/*ar*/\n")
test.write('file.2', "file.2\n/*ar*/\n")
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
test = TestSCons.TestSCons()
test.write('SConstruct', """
foo = Environment(LIBS = ['foo'], LIBPATH = ['.'])
bar = Environment(LIBS = ['bar'], LIBPATH = ['.'],
- AR = '', ARFLAGS = foo.subst(r'%s wrapper.py $AR $ARFLAGS'))
+ AR = '', ARFLAGS = foo.subst(r'%(_python_)s wrapper.py $AR $ARFLAGS'))
foo.Library(target = 'foo', source = 'foo.c')
bar.Library(target = 'bar', source = 'bar.c')
foo.Program(target = 'f', source = obj)
bar.Program(target = 'b', source = obj)
-""" % python)
+""" % locals())
test.write('foo.c', r"""
+#include <stdio.h>
+
void
library_function(void)
{
""")
test.write('bar.c', r"""
+#include <stdio.h>
+
void
library_function(void)
{
""")
test.write('main.c', r"""
+#include <stdlib.h>
+
int
main(int argc, char *argv[])
{
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-env = Environment(LINK = r'%s mylink.py',
- LINKFLAGS = [],
- AS = r'%s myas.py',
- CC = r'%s myas.py')
+env = Environment(LINK = r'%(_python_)s mylink.py',
+ AS = r'%(_python_)s myas.py',
+ CC = r'%(_python_)s myas.py')
env.Program(target = 'test1', source = 'test1.s')
env.Program(target = 'test2', source = 'test2.S')
env.Program(target = 'test3', source = 'test3.asm')
env.Program(target = 'test4', source = 'test4.ASM')
env.Program(target = 'test5', source = 'test5.spp')
env.Program(target = 'test6', source = 'test6.SPP')
-""" % (python, python, python))
+""" % locals())
test.write('test1.s', r"""This is a .s file.
#as
test.write('SConstruct', """\
aaa = Environment()
-bbb = aaa.Copy(AS = r'%s wrapper.py ' + WhereIs('as'))
+bbb = aaa.Copy(AS = r'%(_python_)s wrapper.py ' + WhereIs('as'))
ccc = aaa.Copy(CPPPATH=['.'])
aaa.Program(target = 'aaa', source = ['aaa.s', 'aaa_main.c'])
bbb.Program(target = 'bbb', source = ['bbb.s', 'bbb_main.c'])
ccc.Program(target = 'ccc', source = ['ccc.S', 'ccc_main.c'])
-""" % python)
+""" % locals())
test.write('aaa.s',
""" .file "aaa.s"
""")
test.write('aaa_main.c', r"""
+#include <stdlib.h>
+#include <stdio.h>
+
extern char name[];
int
""")
test.write('bbb_main.c', r"""
+#include <stdlib.h>
+#include <stdio.h>
+
extern char name[];
int
""")
test.write('ccc_main.c', r"""
+#include <stdlib.h>
+#include <stdio.h>
+
extern char name[];
int
ccc = Environment(tools = ['msvc', 'mslink', 'masm'],
ASFLAGS = '/nologo /coff')
ccc['ENV']['PATH'] = ccc['ENV']['PATH'] + os.pathsep + os.environ['PATH']
-ddd = ccc.Copy(AS = r'%s wrapper.py ' + ccc['AS'])
+ddd = ccc.Copy(AS = r'%(_python_)s wrapper.py ' + ccc['AS'])
ccc.Program(target = 'ccc', source = ['ccc.asm', 'ccc_main.c'])
ddd.Program(target = 'ddd', source = ['ddd.asm', 'ddd_main.c'])
-""" % python)
+""" % locals())
test.write('ccc.asm',
"""
test.write('SConstruct', """
eee = Environment(tools = ['gcc', 'gnulink', 'nasm'],
- ASFLAGS = '-f %s')
-fff = eee.Copy(AS = r'%s wrapper.py ' + WhereIs('nasm'))
+ ASFLAGS = '-f %(nasm_format)s')
+fff = eee.Copy(AS = r'%(_python_)s wrapper.py ' + WhereIs('nasm'))
eee.Program(target = 'eee', source = ['eee.asm', 'eee_main.c'])
fff.Program(target = 'fff', source = ['fff.asm', 'fff_main.c'])
-""" % (nasm_format, python))
+""" % locals())
test.write('eee.asm',
"""
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
alt_asm_suffix = '.asm'
test.write('SConstruct', """
-env = Environment(ASCOM = r'%(python)s myas.py $TARGET $SOURCE',
- OBJSUFFIX = '.obj')
+env = Environment(ASCOM = r'%(_python_)s myas.py $TARGET $SOURCE',
+ OBJSUFFIX = '.obj',
+ SHOBJSUFFIX = '.shobj')
env.Object(target = 'test1', source = 'test1.s')
env.Object(target = 'test2', source = 'test2%(alt_s_suffix)s')
env.Object(target = 'test3', source = 'test3.asm')
env.Object(target = 'test4', source = 'test4%(alt_asm_suffix)s')
+env.SharedObject(target = 'test5', source = 'test5.s')
+env.SharedObject(target = 'test6', source = 'test6%(alt_s_suffix)s')
+env.SharedObject(target = 'test7', source = 'test7.asm')
+env.SharedObject(target = 'test8', source = 'test8%(alt_asm_suffix)s')
""" % locals())
test.write('test1.s', "test1.s\n#as\n")
test.write('test2'+alt_s_suffix, "test2.S\n#as\n")
test.write('test3.asm', "test3.asm\n#as\n")
test.write('test4'+alt_asm_suffix, "test4.ASM\n#as\n")
+test.write('test5.s', "test5.s\n#as\n")
+test.write('test6'+alt_s_suffix, "test6.S\n#as\n")
+test.write('test7.asm', "test7.asm\n#as\n")
+test.write('test8'+alt_asm_suffix, "test8.ASM\n#as\n")
test.run(arguments = '.')
test.fail_test(test.read('test2.obj') != "test2.S\n")
test.fail_test(test.read('test3.obj') != "test3.asm\n")
test.fail_test(test.read('test4.obj') != "test4.ASM\n")
+test.fail_test(test.read('test5.shobj') != "test5.s\n")
+test.fail_test(test.read('test6.shobj') != "test6.S\n")
+test.fail_test(test.read('test7.shobj') != "test7.asm\n")
+test.fail_test(test.read('test8.shobj') != "test8.ASM\n")
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
alt_asm_suffix = '.asm'
test.write('SConstruct', """
-env = Environment(ASCOM = r'%(python)s myas.py $TARGET $SOURCE',
+env = Environment(ASCOM = r'%(_python_)s myas.py $TARGET $SOURCE',
ASCOMSTR = 'Assembling $TARGET from $SOURCE',
OBJSUFFIX = '.obj')
env.Object(target = 'test1', source = 'test1.s')
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
_exe = TestSCons._exe
test.write('SConstruct', """
-env = Environment(LINK = r'%s mylink.py',
+env = Environment(LINK = r'%(_python_)s mylink.py',
LINKFLAGS = [],
- AS = r'%s myas.py', ASFLAGS = '-x',
- CC = r'%s myas.py')
+ AS = r'%(_python_)s myas.py', ASFLAGS = '-x',
+ CC = r'%(_python_)s myas.py')
env.Program(target = 'test1', source = 'test1.s')
env.Program(target = 'test2', source = 'test2.S')
env.Program(target = 'test3', source = 'test3.asm')
env.Program(target = 'test4', source = 'test4.ASM')
env.Program(target = 'test5', source = 'test5.spp')
env.Program(target = 'test6', source = 'test6.SPP')
-""" % (python, python, python))
+""" % locals())
test.write('test1.s', r"""This is a .s file.
#as
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-env = Environment(LINK = r'%s mylink.py',
+env = Environment(LINK = r'%(_python_)s mylink.py',
LINKFLAGS = [],
- ASPP = r'%s myas.py',
- CC = r'%s myas.py')
+ ASPP = r'%(_python_)s myas.py',
+ CC = r'%(_python_)s myas.py')
env.Program(target = 'test1', source = 'test1.spp')
env.Program(target = 'test2', source = 'test2.SPP')
-""" % (python, python, python))
+""" % locals())
test.write('test1.spp', r"""This is a .spp file.
#as
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-env = Environment(ASPPCOM = r'%(python)s myas.py $TARGET $SOURCE',
- OBJSUFFIX = '.obj')
+env = Environment(ASPPCOM = r'%(_python_)s myas.py $TARGET $SOURCE',
+ OBJSUFFIX = '.obj',
+ SHOBJSUFFIX = '.shobj')
env.Object(target = 'test1', source = 'test1.spp')
env.Object(target = 'test2', source = 'test2.SPP')
+env.SharedObject(target = 'test3', source = 'test3.spp')
+env.SharedObject(target = 'test4', source = 'test4.SPP')
""" % locals())
test.write('test1.spp', "test1.spp\n#as\n")
test.write('test2.SPP', "test2.SPP\n#as\n")
+test.write('test3.spp', "test3.spp\n#as\n")
+test.write('test4.SPP', "test4.SPP\n#as\n")
test.run(arguments = '.')
test.fail_test(test.read('test1.obj') != "test1.spp\n")
test.fail_test(test.read('test2.obj') != "test2.SPP\n")
+test.fail_test(test.read('test3.shobj') != "test3.spp\n")
+test.fail_test(test.read('test4.shobj') != "test4.SPP\n")
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-env = Environment(ASPPCOM = r'%(python)s myas.py $TARGET $SOURCE',
+env = Environment(ASPPCOM = r'%(_python_)s myas.py $TARGET $SOURCE',
ASPPCOMSTR = 'Assembling $TARGET from $SOURCE',
OBJSUFFIX = '.obj')
env.Object(target = 'test1', source = 'test1.spp')
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
_exe = TestSCons._exe
test.write('SConstruct', """
-env = Environment(LINK = r'%(python)s mylink.py',
+env = Environment(LINK = r'%(_python_)s mylink.py',
LINKFLAGS = [],
- ASPP = r'%(python)s myas.py', ASPPFLAGS = '-x',
- CC = r'%(python)s myas.py')
+ ASPP = r'%(_python_)s myas.py', ASPPFLAGS = '-x',
+ CC = r'%(_python_)s myas.py')
env.Program(target = 'test1', source = 'test1.spp')
env.Program(target = 'test2', source = 'test2.SPP')
""" % locals())
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-B = Builder(action = r'%s build.py $TARGET 1 $SOURCES')
+B = Builder(action = r'%(_python_)s build.py $TARGET 1 $SOURCES')
env = Environment(BUILDERS = { 'B' : B })
env.B(target = 'foo.out', source = 'foo.in')
-""" % python)
+""" % locals())
test.write('foo.in', "foo.in\n")
test.up_to_date(arguments = '.')
test.write('SConstruct', """
-B = Builder(action = r'%s build.py $TARGET 2 $SOURCES')
+B = Builder(action = r'%(_python_)s build.py $TARGET 2 $SOURCES')
env = Environment(BUILDERS = { 'B' : B })
env.B(target = 'foo.out', source = 'foo.in')
-""" % python)
+""" % locals())
test.run(arguments = '.')
import os
import string
def func(env, target, source):
- cmd = r'%s build.py %%s 3 %%s' %% (string.join(map(str, target)),
+ cmd = r'%(_python_)s build.py %%s 3 %%s' %% (string.join(map(str, target)),
string.join(map(str, source)))
print cmd
return os.system(cmd)
B = Builder(action = func)
env = Environment(BUILDERS = { 'B' : B })
env.B(target = 'foo.out', source = 'foo.in')
-""" % python)
+""" % locals())
test.run(arguments = '.', stderr = None)
import string
class bld:
def __init__(self):
- self.cmd = r'%s build.py %%s 4 %%s'
+ self.cmd = r'%(_python_)s build.py %%s 4 %%s'
def __call__(self, env, target, source):
cmd = self.get_contents(env, target, source)
print cmd
B = Builder(action = bld())
env = Environment(BUILDERS = { 'B' : B })
env.B(target = 'foo.out', source = 'foo.in')
-""" % python)
+""" % locals())
test.run(arguments = '.')
import TestSCons
_exe = TestSCons._exe
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
env = Environment()
o = env.Command(['pre-post', 'file.out'],
'file.in',
- "%(python)s build.py ${TARGETS[1]} $SOURCE")
+ '%(_python_)s build.py ${TARGETS[1]} $SOURCE')
env.AddPreAction(o, pre_action)
env.AddPostAction(o, post_action)
""" % locals())
import TestSCons
import TestCmd
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons(match=TestCmd.match_re)
""")
test.write('SConstruct', """
-B = Builder(action = r"%s build.py $TARGET $SOURCES")
+B = Builder(action = r'%(_python_)s build.py $TARGET $SOURCES')
env = Environment()
env['BUILDERS']['B'] = B
env.B(target = 'f1.out', source = 'f1.in')
assert Alias('foo') == foo
assert Alias('bar') == bar
-""" % python)
+""" % locals())
test.write(['sub1', 'SConscript'], """
Import("env")
test.write('SConstruct', """
TargetSignatures('content')
-B = Builder(action = r"%s build.py $TARGET $SOURCES")
+B = Builder(action = r'%(_python_)s build.py $TARGET $SOURCES')
env = Environment()
env['BUILDERS']['B'] = B
env.B(target = 'f1.out', source = 'f1.in')
env.Alias('blat', ['sub2', 'f3.out'])
env.Alias('blat', ['f2.out', 'sub1'])
env.Depends('f1.out', 'bar')
-""" % python)
+""" % locals())
os.unlink(test.workpath('f1.out'))
test.write('f3.in', "f3.in 3 \n")
-test.run(arguments = 'f1.out',
- match = TestCmd.match_exact,
- stdout = test.wrap_stdout("""\
-%s build.py f3.out f3.in
-%s build.py f1.out f1.in
-""" % (python, python)))
+expect = test.wrap_stdout("""\
+%(_python_)s build.py f3.out f3.in
+%(_python_)s build.py f1.out f1.in
+""" % locals())
+
+test.run(arguments = 'f1.out', match = TestCmd.match_exact, stdout = expect)
test.up_to_date(arguments = 'f1.out')
test = TestSCons.TestSCons()
+SConstruct_path = test.workpath('SConstruct')
+
sconstruct = """
def buildop(env, source, target):
outf = open(str(target[0]), 'wb')
### Gross mistake in Builder spec
-test.write('SConstruct', sconstruct % '\
+test.write(SConstruct_path, sconstruct % '\
b2 = Builder(act__ion=buildop, src_suffix=".b", suffix=".c")')
-test.run(arguments='.',
- stderr="""\
+expect_stderr = """\
scons: *** Builder b2 must have an action to build ['foo.c'].
-File "SConstruct", line 14, in ?
-""",
-status = 2)
+File "%(SConstruct_path)s", line 14, in ?
+""" % locals()
+
+test.run(arguments='.', stderr=expect_stderr, status = 2)
### Subtle mistake in Builder spec
-test.write('SConstruct', sconstruct % '\
+test.write(SConstruct_path, sconstruct % '\
b2 = Builder(actoin=buildop, src_suffix=".b", suffix=".c")')
-test.run(arguments='test2',
- stderr="""\
+expect_stderr="""\
scons: *** Builder b2 must have an action to build ['foo.c'].
-File "SConstruct", line 14, in ?
-""",
-status = 2)
+File "%(SConstruct_path)s", line 14, in ?
+""" % locals()
+
+test.run(arguments='test2', stderr=expect_stderr, status=2)
### Missing action in Builder spec
-test.write('SConstruct', sconstruct % '\
+test.write(SConstruct_path, sconstruct % '\
b2 = Builder(src_suffix=".b", suffix=".c")')
-test.run(arguments='test2',
- stderr="""\
+expect_stderr = """\
scons: *** Builder b2 must have an action to build ['foo.c'].
-File "SConstruct", line 14, in ?
-""",
-status = 2)
+File "%(SConstruct_path)s", line 14, in ?
+""" % locals()
+
+test.run(arguments='test2', stderr=expect_stderr, status = 2)
test.pass_test()
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
f.close()
env = Environment(TOOLS = ['default', 'BitKeeper'],
BUILDERS={'Cat':Builder(action=cat)},
- BITKEEPERCOM='%(python)s my-bk-get.py $TARGET')
+ BITKEEPERCOM='%(_python_)s my-bk-get.py $TARGET')
env.Cat('aaa.out', 'aaa.in')
env.Cat('bbb.out', 'bbb.in')
env.Cat('ccc.out', 'ccc.in')
test.run(arguments = '.',
stdout = test.wrap_stdout(read_str = """\
-%(python)s my-bk-get.py %(sub_SConscript)s
+%(_python_)s my-bk-get.py %(sub_SConscript)s
""" % locals(),
build_str = """\
-%(python)s my-bk-get.py aaa.in
+%(_python_)s my-bk-get.py aaa.in
cat(["aaa.out"], ["aaa.in"])
cat(["bbb.out"], ["bbb.in"])
-%(python)s my-bk-get.py ccc.in
+%(_python_)s my-bk-get.py ccc.in
cat(["ccc.out"], ["ccc.in"])
cat(["all"], ["aaa.out", "bbb.out", "ccc.out"])
-%(python)s my-bk-get.py %(sub_ddd_in)s
+%(_python_)s my-bk-get.py %(sub_ddd_in)s
cat(["%(sub_ddd_out)s"], ["%(sub_ddd_in)s"])
cat(["%(sub_eee_out)s"], ["%(sub_eee_in)s"])
-%(python)s my-bk-get.py %(sub_fff_in)s
+%(_python_)s my-bk-get.py %(sub_fff_in)s
cat(["%(sub_fff_out)s"], ["%(sub_fff_in)s"])
cat(["%(sub_all)s"], ["%(sub_ddd_out)s", "%(sub_eee_out)s", "%(sub_fff_out)s"])
""" % locals()))
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
f.close()
env = Environment(TOOLS = ['default', 'BitKeeper'],
BUILDERS={'Cat':Builder(action=cat)},
- BITKEEPERCOM='%(python)s my-bk-get.py $TARGET',
+ BITKEEPERCOM='%(_python_)s my-bk-get.py $TARGET',
BITKEEPERCOMSTR='Checking out $TARGET from our fake BitKeeper')
env.Cat('aaa.out', 'aaa.in')
env.Cat('bbb.out', 'bbb.in')
""" % (fortran_runtime, fortran_runtime))
test.write(['work1', 'src', 'f1.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+
#include "f1.h"
int
""")
test.write(['work1', 'src', 'f2.in'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+
#include "f2.h"
int
""")
test.write(['work1', 'src', 'f3.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+
#include "f3.h"
int
""")
test.write(['work1', 'src', 'f4.in'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+
#include "f4.h"
int
""")
test.write(['work2', 'prog.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+
int
main(int argc, char *argv[])
{
""")
test.write(['test2', 'bar.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+
void
bar(void) {
printf("bar.c\n");
""")
test.write(['test2', 'foo.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+
int
main(int argc, char *argv[]) {
bar();
# build directory results in an error message, rather
# than just silently failing.
test.subdir('duplicate', ['duplicate', 'src1'], ['duplicate', 'src2'])
-test.write(['duplicate', 'SConstruct'], """\
+
+duplicate_SConstruct_path = test.workpath('duplicate', 'SConstruct')
+
+test.write(duplicate_SConstruct_path, """\
BuildDir('build', 'src1')
BuildDir('build', 'src2')
""")
+expect_stderr = """
+scons: *** 'build' already has a source directory: 'src1'.
+File "%(duplicate_SConstruct_path)s", line 2, in ?
+""" % locals()
+
test.run(chdir = 'duplicate',
arguments = ".",
status = 2,
- stderr = """
-scons: *** 'build' already has a source directory: 'src1'.
-File "SConstruct", line 2, in ?
-""")
+ stderr = expect_stderr)
test.pass_test()
--- /dev/null
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Test that nested SConscript files in a BuildDir don't throw
+an OSError exception looking for the wrong file.
+"""
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+test.subdir(['src'],
+ ['src', 'md'],
+ ['src', 'md', 'test'])
+
+test.write(['src', 'SConstruct'], """\
+BUILD_DIR = '../build'
+
+base_env = Environment()
+
+for flavor in ['prod', 'debug']:
+ build_env = base_env.Copy()
+ # In real life, we would modify build_env appropriately here
+ FLAVOR_DIR = BUILD_DIR + '/' + flavor
+ Export('build_env')
+ BuildDir(FLAVOR_DIR, 'md', duplicate=0)
+ SConscript(FLAVOR_DIR + '/SConscript')
+""")
+
+test.write(['src', 'md', 'SConscript'], """\
+SConscript('test/SConscript')
+""")
+
+test.write(['src', 'md', 'test', 'SConscript'], """\
+# empty
+""")
+
+test.run(chdir='src')
+
+test.pass_test()
import TestSCons
test = TestSCons.TestSCons()
-python = TestSCons.python
-re_python = re.escape(python)
+
+_python_ = TestSCons._python_
+re_python = re.escape(TestSCons.python)
test.write("mycc.py", """
print 'Compile'
""")
sconstruct = """
-env = Environment(CC = r'%(python)s mycc.py',
- LINK = r'%(python)s mylink.py',
+env = Environment(CC = r'%(_python_)s mycc.py',
+ LINK = r'%(_python_)s mylink.py',
INCPREFIX = 'INC_',
INCSUFFIX = '_CNI',
CPPPATH='%(cpppath)s') # note no leading '#'
targets = re.escape(os.path.join('dir1', 'dir2'))
INC_CNI = re.escape(os.path.join('INC_dir1', 'dir2', 'dir1', 'dir2_CNI'))
-# The .* after mycc\\.py below handles /nologo flags from Visual C/C++.
-test.run(arguments = '',
- stdout=test.wrap_stdout("""\
+# The .+ after mycc\\.py below handles /nologo flags from Visual C/C++.
+expect = test.wrap_stdout("""\
scons: building associated BuildDir targets: %(targets)s
-%(re_python)s mycc\\.py.* %(INC_CNI)s .+
+"%(re_python)s" mycc\\.py.* %(INC_CNI)s .+
Compile
-%(re_python)s mylink\\.py .+
+"%(re_python)s" mylink\\.py .+
Link
-""" % locals()),
- match=TestSCons.match_re,
- )
+""" % locals())
+
+test.run(arguments = '', match=TestSCons.match_re, stdout=expect)
# Note that we don't check for the existence of dir1/dir2/foo.h, because
# this bad cpppath will expand to dir1/dir2/dir1/dir2, which means it
test.run(arguments = '',
stdout=test.wrap_stdout("""\
scons: building associated BuildDir targets: %(targets)s
-%(re_python)s mycc\\.py.* %(INC_CNI)s .+
+"%(re_python)s" mycc\\.py.* %(INC_CNI)s .+
Compile
-%(re_python)s mylink\\.py .+
+"%(re_python)s" mylink\\.py .+
Link
""" % locals()),
match=TestSCons.match_re,
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
test = TestSCons.TestSCons()
test.write('SConstruct', """
cc = Environment().Dictionary('CC')
-env = Environment(LINK = r'%s mylink.py',
+env = Environment(LINK = r'%(_python_)s mylink.py',
LINKFLAGS = [],
- CC = r'%s mycc.py',
+ CC = r'%(_python_)s mycc.py',
CXX = cc,
CXXFLAGS = [])
env.Program(target = 'test1', source = 'test1.c')
-""" % (python, python))
+""" % locals())
test.write('test1.c', r"""This is a .c file.
/*cc*/
test.write('SConstruct', """
cc = Environment().Dictionary('CC')
-env = Environment(LINK = r'%s mylink.py',
- CC = r'%s mycc.py',
+env = Environment(LINK = r'%(_python_)s mylink.py',
+ CC = r'%(_python_)s mycc.py',
CXX = cc)
env.Program(target = 'test2', source = 'test2.C')
-""" % (python, python))
+""" % locals())
test.write('test2.C', r"""This is a .C file.
/*cc*/
test.write('SConstruct', """
foo = Environment()
cc = foo.Dictionary('CC')
-bar = Environment(CC = r'%s wrapper.py ' + cc)
+bar = Environment(CC = r'%(_python_)s wrapper.py ' + cc)
foo.Program(target = 'foo', source = 'foo.c')
bar.Program(target = 'bar', source = 'bar.c')
-""" % python)
+""" % locals())
test.write('foo.c', r"""
+#include <stdio.h>
+#include <stdlib.h>
+
int
main(int argc, char *argv[])
{
""")
test.write('bar.c', r"""
+#include <stdio.h>
+#include <stdlib.h>
+
int
main(int argc, char *argv[])
{
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
test = TestSCons.TestSCons()
alt_c_suffix = '.c'
test.write('SConstruct', """
-env = Environment(CCCOM = r'%(python)s mycc.py $TARGET $SOURCE',
+env = Environment(CCCOM = r'%(_python_)s mycc.py $TARGET $SOURCE',
OBJSUFFIX='.obj')
env.Object(target = 'test1', source = 'test1.c')
env.Object(target = 'test2', source = 'test2%(alt_c_suffix)s')
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
test = TestSCons.TestSCons()
alt_c_suffix = '.c'
test.write('SConstruct', """
-env = Environment(CCCOM = r'%(python)s mycc.py $TARGET $SOURCE',
+env = Environment(CCCOM = r'%(_python_)s mycc.py $TARGET $SOURCE',
CCCOMSTR = 'Building $TARGET from $SOURCE',
OBJSUFFIX='.obj')
env.Object(target = 'test1', source = 'test1.c')
""" % (fooflags, barflags, _obj, _obj, _obj, _obj))
test.write('prog.c', r"""
+#include <stdio.h>
+#include <stdlib.h>
+
int
main(int argc, char *argv[])
{
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
foo = Environment()
shcc = foo.Dictionary('SHCC')
-bar = Environment(SHCC = r'%s wrapper.py ' + shcc)
+bar = Environment(SHCC = r'%(_python_)s wrapper.py ' + shcc)
foo.SharedObject(target = 'foo/foo', source = 'foo.c')
bar.SharedObject(target = 'bar/bar', source = 'bar.c')
-""" % python)
+""" % locals())
test.write('foo.c', r"""
+#include <stdio.h>
+#include <stdlib.h>
+
int
main(int argc, char *argv[])
{
""")
test.write('bar.c', r"""
+#include <stdio.h>
+#include <stdlib.h>
+
int
main(int argc, char *argv[])
{
Test the ability to configure the $SHCCCOM construction variable.
"""
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
alt_c_suffix = '.c'
test.write('SConstruct', """
-env = Environment(SHCCCOM = r'%(python)s mycc.py $TARGET $SOURCE',
+env = Environment(SHCCCOM = r'%(_python_)s mycc.py $TARGET $SOURCE',
SHOBJSUFFIX='.obj')
env.SharedObject(target = 'test1', source = 'test1.c')
env.SharedObject(target = 'test2', source = 'test2%(alt_c_suffix)s')
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
test = TestSCons.TestSCons()
alt_c_suffix = '.c'
test.write('SConstruct', """
-env = Environment(SHCCCOM = r'%(python)s mycc.py $TARGET $SOURCE',
+env = Environment(SHCCCOM = r'%(_python_)s mycc.py $TARGET $SOURCE',
SHCCCOMSTR = 'Building $TARGET from $SOURCE',
SHOBJSUFFIX='.obj')
env.SharedObject(target = 'test1', source = 'test1.c')
import TestSCons
import os
import string
-
-if sys.platform == 'win32':
- fooflags = '/nologo -DFOO'
- barflags = '/nologo -DBAR'
-else:
- fooflags = '-DFOO'
- barflags = '-DBAR'
test = TestSCons.TestSCons()
+e = test.Environment()
+fooflags = e['SHCCFLAGS'] + ' -DFOO'
+barflags = e['SHCCFLAGS'] + ' -DBAR'
+
if os.name == 'posix':
os.environ['LD_LIBRARY_PATH'] = '.'
if string.find(sys.platform, 'irix') > -1:
""")
test.write('prog.c', r"""
+#include <stdio.h>
+
void
doIt()
{
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-env = Environment(LEX = r'%s mylex.py', tools = ['lex'])
+env = Environment(LEX = r'%(_python_)s mylex.py', tools = ['lex'])
env.CFile(target = 'foo', source = 'foo.l')
env.Copy(CFILESUFFIX = '.xyz').CFile(target = 'bar', source = 'bar.l')
-""" % python)
+""" % locals())
input = r"""
int
""")
test.write('prog.c', r"""
+#include <stdio.h>
+#include <stdlib.h>
+
int
main(int argc, char *argv[])
{
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
_obj = TestSCons._obj
_shobj = TestSCons._shobj
test.write('SConstruct', """
env = Environment(CPPFLAGS = '-x',
- LINK = r'%s mylink.py',
+ LINK = r'%(_python_)s mylink.py',
LINKFLAGS = [],
- CC = r'%s mygcc.py cc',
- CXX = r'%s mygcc.py c++',
+ CC = r'%(_python_)s mygcc.py cc',
+ CXX = r'%(_python_)s mygcc.py c++',
CXXFLAGS = [],
- FORTRAN = r'%s mygcc.py g77')
+ FORTRAN = r'%(_python_)s mygcc.py g77')
env.Program(target = 'foo', source = Split('test1.c test2.cpp test3.F'))
-""" % (python, python, python, python))
+""" % locals())
test.write('test1.c', r"""test1.c
#cc
test.write('SConstruct', """
env = Environment(CPPFLAGS = '-x',
- SHLINK = r'%s mylink.py',
+ SHLINK = r'%(_python_)s mylink.py',
SHLINKFLAGS = [],
- CC = r'%s mygcc.py cc',
- CXX = r'%s mygcc.py c++',
+ CC = r'%(_python_)s mygcc.py cc',
+ CXX = r'%(_python_)s mygcc.py c++',
CXXFLAGS = [],
- FORTRAN = r'%s mygcc.py g77')
+ FORTRAN = r'%(_python_)s mygcc.py g77')
env.SharedLibrary(target = File('foo.bar'),
source = Split('test1.c test2.cpp test3.F'))
-""" % (python, python, python, python))
+""" % locals())
test.write('test1.c', r"""test1.c
#cc
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(CPPPATH = ['.'],
- CC = r'%s mycc.py',
+ CC = r'%(_python_)s mycc.py',
CCFLAGS = [],
CCCOM = '$CC $TARGET $SOURCES',
OBJSUFFIX = '.o')
env.InstallAs('test1_c', 'test1.c')
env.InstallAs('test1_h', 'test1.h')
env.InstallAs('test1_x', 'test1.x')
-""" % (python,))
+""" % locals())
test.write('test1.c', """\
test1.c 1
test.write('foo.h', "foo.h 1\n")
-test.run(arguments='.', stdout=test.wrap_stdout("""\
-%s mycc.py test1.o test1.c
+expect = test.wrap_stdout("""\
+%(_python_)s mycc.py test1.o test1.c
Install file: "test1.c" as "test1_c"
Install file: "test1.h" as "test1_h"
Install file: "test1.x" as "test1_x"
-""" % (python,)))
+""" % locals())
+
+test.run(arguments='.', stdout=expect)
test.must_match('test1.o', """\
test1.c 1
test.write('foo.h', "foo.h 2\n")
-test.run(arguments='.', stdout=test.wrap_stdout("""\
-%s mycc.py test1.o test1.c
-""" % (python,)))
+expect = test.wrap_stdout("""\
+%(_python_)s mycc.py test1.o test1.c
+""" % locals())
+
+test.run(arguments='.', stdout=expect)
test.must_match('test1.o', """\
test1.c 1
#include <foo.h>
""")
-test.run(arguments='.', stdout=test.wrap_stdout("""\
-%s mycc.py test1.o test1.c
+expect = test.wrap_stdout("""\
+%(_python_)s mycc.py test1.o test1.c
Install file: "test1.x" as "test1_x"
-""" % (python,)))
+""" % locals())
+
+test.run(arguments='.', stdout=expect)
test.must_match('test1.o', """\
test1.c 1
#include <foo.h>
""")
-test.run(arguments='.', stdout=test.wrap_stdout("""\
-%s mycc.py test1.o test1.c
+expect = test.wrap_stdout("""\
+%(_python_)s mycc.py test1.o test1.c
Install file: "test1.h" as "test1_h"
-""" % (python,)))
+""" % locals())
+
+test.run(arguments='.', stdout=expect)
test.must_match('test1.o', """\
test1.c 1
for src in source:
f.write(open(src, "rb").read())
f.close()
-env = Environment(ENV = { 'PATH' : os.environ['PATH'] },
+env = Environment(ENV = { 'PATH' : os.environ['PATH'],
+ 'EDITOR' : os.environ.get('EDITOR', 'ed') },
BUILDERS={'Cat':Builder(action=cat)})
env.Prepend(CVSFLAGS='-Q')
env.Cat('aaa.out', 'foo/aaa.in')
for src in source:
f.write(open(src, "rb").read())
f.close()
-env = Environment(ENV = { 'PATH' : os.environ['PATH'] },
+env = Environment(ENV = { 'PATH' : os.environ['PATH'],
+ 'EDITOR' : os.environ.get('EDITOR', 'ed') },
BUILDERS={'Cat':Builder(action=cat)})
env.Prepend(CVSFLAGS='-q')
env.Cat('aaa.out', 'aaa.in')
for src in source:
f.write(open(src, "rb").read())
f.close()
-env = Environment(ENV = { 'PATH' : os.environ['PATH'] },
+env = Environment(ENV = { 'PATH' : os.environ['PATH'],
+ 'EDITOR' : os.environ.get('EDITOR', 'ed') },
BUILDERS={'Cat':Builder(action=cat)},
CVSROOT=r'%s')
env.Prepend(CVSFLAGS='-q')
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
f.close()
env = Environment(TOOLS = ['default', 'CVS'],
BUILDERS={'Cat':Builder(action=cat)},
- CVSCOM='%(python)s my-cvs-co-.py $TARGET')
+ CVSCOM='%(_python_)s my-cvs-co-.py $TARGET')
env.Cat('aaa.out', 'aaa.in')
env.Cat('bbb.out', 'bbb.in')
env.Cat('ccc.out', 'ccc.in')
test.run(arguments = '.',
stdout = test.wrap_stdout(read_str = """\
-%(python)s my-cvs-co-.py %(sub_SConscript)s
+%(_python_)s my-cvs-co-.py %(sub_SConscript)s
""" % locals(),
build_str = """\
-%(python)s my-cvs-co-.py aaa.in
+%(_python_)s my-cvs-co-.py aaa.in
cat(["aaa.out"], ["aaa.in"])
cat(["bbb.out"], ["bbb.in"])
-%(python)s my-cvs-co-.py ccc.in
+%(_python_)s my-cvs-co-.py ccc.in
cat(["ccc.out"], ["ccc.in"])
cat(["all"], ["aaa.out", "bbb.out", "ccc.out"])
-%(python)s my-cvs-co-.py %(sub_ddd_in)s
+%(_python_)s my-cvs-co-.py %(sub_ddd_in)s
cat(["%(sub_ddd_out)s"], ["%(sub_ddd_in)s"])
cat(["%(sub_eee_out)s"], ["%(sub_eee_in)s"])
-%(python)s my-cvs-co-.py %(sub_fff_in)s
+%(_python_)s my-cvs-co-.py %(sub_fff_in)s
cat(["%(sub_fff_out)s"], ["%(sub_fff_in)s"])
cat(["%(sub_all)s"], ["%(sub_ddd_out)s", "%(sub_eee_out)s", "%(sub_fff_out)s"])
""" % locals()))
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
f.close()
env = Environment(TOOLS = ['default', 'CVS'],
BUILDERS={'Cat':Builder(action=cat)},
- CVSCOM='%(python)s my-cvs-co.py $TARGET',
+ CVSCOM='%(_python_)s my-cvs-co.py $TARGET',
CVSCOMSTR='Checking out $TARGET from our fake CVS')
env.Cat('aaa.out', 'aaa.in')
env.Cat('bbb.out', 'bbb.in')
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-env = Environment(LINK = r'%s mylink.py',
+env = Environment(LINK = r'%(_python_)s mylink.py',
LINKFLAGS = [],
- CXX = r'%s myc++.py',
+ CXX = r'%(_python_)s myc++.py',
CXXFLAGS = [])
env.Program(target = 'test1', source = 'test1.cc')
env.Program(target = 'test2', source = 'test2.cpp')
env.Program(target = 'test3', source = 'test3.cxx')
env.Program(target = 'test4', source = 'test4.c++')
env.Program(target = 'test5', source = 'test5.C++')
-""" % (python, python))
+""" % locals())
test.write('test1.cc', r"""This is a .cc file.
/*c++*/
if TestSCons.case_sensitive_suffixes('.c', '.C'):
test.write('SConstruct', """
-env = Environment(LINK = r'%s mylink.py',
+env = Environment(LINK = r'%(_python_)s mylink.py',
LINKFLAGS = [],
- CXX = r'%s myc++.py',
+ CXX = r'%(_python_)s myc++.py',
CXXFLAGS = [])
env.Program(target = 'test6', source = 'test6.C')
-""" % (python, python))
+""" % locals())
test.write('test6.C', r"""This is a .C file.
/*c++*/
test.write('SConstruct', """
foo = Environment()
cxx = foo.Dictionary('CXX')
-bar = Environment(CXX = r'%s wrapper.py ' + cxx)
+bar = Environment(CXX = r'%(_python_)s wrapper.py ' + cxx)
foo.Program(target = 'foo', source = 'foo.cxx')
bar.Program(target = 'bar', source = 'bar.cxx')
-""" % python)
+""" % locals())
test.write('foo.cxx', r"""
#include <stdio.h>
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
test = TestSCons.TestSCons()
alt_cpp_suffix = '.C'
test.write('SConstruct', """
-env = Environment(CXXCOM = r'%(python)s mycc.py $TARGET $SOURCE',
+env = Environment(CXXCOM = r'%(_python_)s mycc.py $TARGET $SOURCE',
OBJSUFFIX='.obj')
env.Object(target = 'test1', source = 'test1.cpp')
env.Object(target = 'test2', source = 'test2.cc')
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
test = TestSCons.TestSCons()
alt_cpp_suffix = '.C'
test.write('SConstruct', """
-env = Environment(CXXCOM = r'%(python)s mycc.py $TARGET $SOURCE',
+env = Environment(CXXCOM = r'%(_python_)s mycc.py $TARGET $SOURCE',
CXXCOMSTR = 'Building $TARGET from $SOURCE',
OBJSUFFIX='.obj')
env.Object(target = 'test1', source = 'test1.cpp')
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-env = Environment(LEX = r'%s mylex.py', tools = ['lex'])
+env = Environment(LEX = r'%(_python_)s mylex.py', tools = ['lex'])
env.CXXFile(target = 'foo', source = 'foo.ll')
env.Copy(CXXFILESUFFIX = '.xyz').CXXFile(target = 'bar', source = 'bar.ll')
-""" % python)
+""" % locals())
input = r"""
int
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
foo = Environment()
shcxx = foo.Dictionary('SHCXX')
-bar = Environment(SHCXX = r'%s wrapper.py ' + shcxx)
+bar = Environment(SHCXX = r'%(_python_)s wrapper.py ' + shcxx)
foo.SharedObject(target = 'foo/foo', source = 'foo.cpp')
bar.SharedObject(target = 'bar/bar', source = 'bar.cpp')
-""" % python)
+""" % locals())
test.write('foo.cpp', r"""
#include <stdio.h>
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
test = TestSCons.TestSCons()
alt_cpp_suffix = '.C'
test.write('SConstruct', """
-env = Environment(SHCXXCOM = r'%(python)s mycc.py $TARGET $SOURCE',
+env = Environment(SHCXXCOM = r'%(_python_)s mycc.py $TARGET $SOURCE',
SHOBJSUFFIX='.obj')
env.SharedObject(target = 'test1', source = 'test1.cpp')
env.SharedObject(target = 'test2', source = 'test2.cc')
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
test = TestSCons.TestSCons()
alt_cpp_suffix = '.C'
test.write('SConstruct', """
-env = Environment(SHCXXCOM = r'%(python)s mycc.py $TARGET $SOURCE',
+env = Environment(SHCXXCOM = r'%(_python_)s mycc.py $TARGET $SOURCE',
SHCXXCOMSTR = 'Building shared object $TARGET from $SOURCE',
SHOBJSUFFIX='.obj')
env.SharedObject(target = 'test1', source = 'test1.cpp')
import os
import string
-if sys.platform == 'win32':
- _obj = '.obj'
- fooflags = '/nologo -DFOO'
- barflags = '/nologo -DBAR'
-else:
- _obj = '.o'
- fooflags = '-DFOO'
- barflags = '-DBAR'
-
+_obj = TestSCons._obj
+
if os.name == 'posix':
os.environ['LD_LIBRARY_PATH'] = '.'
if string.find(sys.platform, 'irix') > -1:
test = TestSCons.TestSCons()
+e = test.Environment()
+fooflags = e['SHCXXFLAGS'] + ' -DFOO'
+barflags = e['SHCXXFLAGS'] + ' -DBAR'
+
test.write('SConstruct', """
foo = Environment(SHCXXFLAGS = '%s', WINDOWS_INSERT_DEF=1)
bar = Environment(SHCXXFLAGS = '%s', WINDOWS_INSERT_DEF=1)
+++ /dev/null
-#!/usr/bin/env python
-#
-# __COPYRIGHT__
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be included
-# in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
-# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
-# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-#
-
-__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
-
-"""
-Test retrieving derived files from a CacheDir.
-"""
-
-import os.path
-import shutil
-
-import TestSCons
-
-test = TestSCons.TestSCons()
-
-# cache2 omitted from list in order to test automatic creation of CacheDir
-# directory.
-test.subdir('cache1', 'cache3', 'src', 'subdir')
-
-test.write(['src', 'SConstruct'], """\
-CacheDir(r'%s')
-SConscript('SConscript')
-""" % test.workpath('cache1'))
-
-test.write(['src', 'SConscript'], """\
-def cat(env, source, target):
- target = str(target[0])
- open('cat.out', 'ab').write(target + "\\n")
- source = map(str, source)
- f = open(target, "wb")
- for src in source:
- f.write(open(src, "rb").read())
- f.close()
-env = Environment(BUILDERS={'Cat':Builder(action=cat)})
-env.Cat('aaa.out', 'aaa.in')
-env.Cat('bbb.out', 'bbb.in')
-env.Cat('ccc.out', 'ccc.in')
-env.Cat('all', ['aaa.out', 'bbb.out', 'ccc.out'])
-""")
-
-test.write(['src', 'aaa.in'], "aaa.in\n")
-test.write(['src', 'bbb.in'], "bbb.in\n")
-test.write(['src', 'ccc.in'], "ccc.in\n")
-
-#############################################################################
-
-# Verify that building with -n and an empty cache reports that proper
-# build operations would be taken, but that nothing is actually built
-# and that the cache is still empty.
-test.run(chdir = 'src', arguments = '-n .', stdout = test.wrap_stdout("""\
-cat(["aaa.out"], ["aaa.in"])
-cat(["bbb.out"], ["bbb.in"])
-cat(["ccc.out"], ["ccc.in"])
-cat(["all"], ["aaa.out", "bbb.out", "ccc.out"])
-"""))
-
-test.must_not_exist(test.workpath('src', 'aaa.out'))
-test.must_not_exist(test.workpath('src', 'bbb.out'))
-test.must_not_exist(test.workpath('src', 'ccc.out'))
-test.must_not_exist(test.workpath('src', 'all'))
-test.fail_test(len(os.listdir(test.workpath('cache1'))))
-
-# Verify that a normal build works correctly, and clean up.
-# This should populate the cache with our derived files.
-test.run(chdir = 'src', arguments = '.')
-
-test.must_match(['src', 'all'], "aaa.in\nbbb.in\nccc.in\n")
-test.must_match(['src', 'cat.out'], "aaa.out\nbbb.out\nccc.out\nall\n")
-
-test.up_to_date(chdir = 'src', arguments = '.')
-
-test.run(chdir = 'src', arguments = '-c .')
-test.unlink(['src', 'cat.out'])
-
-# Verify that we now retrieve the derived files from cache,
-# not rebuild them. Then clean up.
-test.run(chdir = 'src', arguments = '.', stdout = test.wrap_stdout("""\
-Retrieved `aaa.out' from cache
-Retrieved `bbb.out' from cache
-Retrieved `ccc.out' from cache
-Retrieved `all' from cache
-"""))
-
-test.must_not_exist(test.workpath('src', 'cat.out'))
-
-test.up_to_date(chdir = 'src', arguments = '.')
-
-test.run(chdir = 'src', arguments = '-c .')
-
-# Verify that rebuilding with -n reports that everything was retrieved
-# from the cache, but that nothing really was.
-test.run(chdir = 'src', arguments = '-n .', stdout = test.wrap_stdout("""\
-Retrieved `aaa.out' from cache
-Retrieved `bbb.out' from cache
-Retrieved `ccc.out' from cache
-Retrieved `all' from cache
-"""))
-
-test.must_not_exist(test.workpath('src', 'aaa.out'))
-test.must_not_exist(test.workpath('src', 'bbb.out'))
-test.must_not_exist(test.workpath('src', 'ccc.out'))
-test.must_not_exist(test.workpath('src', 'all'))
-
-# Verify that rebuilding with -s retrieves everything from the cache
-# even though it doesn't report anything.
-test.run(chdir = 'src', arguments = '-s .', stdout = "")
-
-test.must_match(['src', 'all'], "aaa.in\nbbb.in\nccc.in\n")
-test.must_not_exist(test.workpath('src', 'cat.out'))
-
-test.up_to_date(chdir = 'src', arguments = '.')
-
-test.run(chdir = 'src', arguments = '-c .')
-
-# Verify that updating one input file builds its derived file and
-# dependency but that the other files are retrieved from cache.
-test.write(['src', 'bbb.in'], "bbb.in 2\n")
-
-test.run(chdir = 'src', arguments = '.', stdout = test.wrap_stdout("""\
-Retrieved `aaa.out' from cache
-cat(["bbb.out"], ["bbb.in"])
-Retrieved `ccc.out' from cache
-cat(["all"], ["aaa.out", "bbb.out", "ccc.out"])
-"""))
-
-test.must_match(['src', 'all'], "aaa.in\nbbb.in 2\nccc.in\n")
-test.must_match(['src', 'cat.out'], "bbb.out\nall\n")
-
-test.up_to_date(chdir = 'src', arguments = '.')
-
-#############################################################################
-# Now we try out BuildDir() functionality.
-# This is largely cut-and-paste of the above,
-# with appropriate directory modifications.
-
-build_aaa_out = os.path.join('build', 'aaa.out')
-build_bbb_out = os.path.join('build', 'bbb.out')
-build_ccc_out = os.path.join('build', 'ccc.out')
-build_all = os.path.join('build', 'all')
-
-# First, clean up the source directory and start over with fresh files.
-test.run(chdir = 'src', arguments = '-c .')
-
-test.write(['src', 'aaa.in'], "aaa.in\n")
-test.write(['src', 'bbb.in'], "bbb.in\n")
-test.write(['src', 'ccc.in'], "ccc.in\n")
-
-#
-test.write('SConstruct', """\
-env = Environment(TWO = '2')
-env.CacheDir(r'%s')
-BuildDir('build', 'src', duplicate=0)
-SConscript('build/SConscript')
-""" % test.workpath('cache${TWO}'))
-
-# Verify that a normal build works correctly, and clean up.
-# This should populate the cache with our derived files.
-test.run()
-
-test.must_match(['build', 'all'], "aaa.in\nbbb.in\nccc.in\n")
-test.must_match('cat.out', "%s\n%s\n%s\n%s\n" % (build_aaa_out, build_bbb_out, build_ccc_out, build_all))
-
-test.up_to_date(arguments = '.')
-
-test.run(arguments = '-c .')
-test.unlink('cat.out')
-
-# Verify that we now retrieve the derived files from cache,
-# not rebuild them. Then clean up.
-test.run(stdout = test.wrap_stdout("""\
-Retrieved `%s' from cache
-Retrieved `%s' from cache
-Retrieved `%s' from cache
-Retrieved `%s' from cache
-""" % (build_aaa_out, build_bbb_out, build_ccc_out, build_all)))
-
-test.must_not_exist(test.workpath('cat.out'))
-
-test.up_to_date(arguments = '.')
-
-test.run(arguments = '-c .')
-
-# Verify that rebuilding with -n reports that everything was retrieved
-# from the cache, but that nothing really was.
-test.run(arguments = '-n .', stdout = test.wrap_stdout("""\
-Retrieved `%s' from cache
-Retrieved `%s' from cache
-Retrieved `%s' from cache
-Retrieved `%s' from cache
-""" % (build_aaa_out, build_bbb_out, build_ccc_out, build_all)))
-
-test.must_not_exist(test.workpath('build', 'aaa.out'))
-test.must_not_exist(test.workpath('build', 'bbb.out'))
-test.must_not_exist(test.workpath('build', 'ccc.out'))
-test.must_not_exist(test.workpath('build', 'all'))
-
-# Verify that rebuilding with -s retrieves everything from the cache
-# even though it doesn't report anything.
-test.run(arguments = '-s .', stdout = "")
-
-test.must_match(['build', 'all'], "aaa.in\nbbb.in\nccc.in\n")
-test.must_not_exist(test.workpath('cat.out'))
-
-test.up_to_date(arguments = '.')
-
-test.run(arguments = '-c .')
-
-# Verify that updating one input file builds its derived file and
-# dependency but that the other files are retrieved from cache.
-test.write(['src', 'bbb.in'], "bbb.in 2\n")
-
-test.run(stdout = test.wrap_stdout("""\
-Retrieved `%s' from cache
-cat(["%s"], ["%s"])
-Retrieved `%s' from cache
-cat(["%s"], ["%s", "%s", "%s"])
-""" % (build_aaa_out,
- build_bbb_out, os.path.join('src', 'bbb.in'),
- build_ccc_out,
- build_all, build_aaa_out, build_bbb_out, build_ccc_out)))
-
-test.must_match(['build', 'all'], "aaa.in\nbbb.in 2\nccc.in\n")
-test.must_match('cat.out', "%s\n%s\n" % (build_bbb_out, build_all))
-
-test.up_to_date(arguments = '.')
-
-#############################################################################
-# Test the case (reported by Jeff Petkau, bug #694744) where a target
-# is source for another target with a scanner, which used to cause us
-# to push the file to the CacheDir after the build signature had already
-# been cleared (as a sign that the built file should now be rescanned).
-
-test.write(['subdir', 'SConstruct'], """\
-import SCons
-
-CacheDir(r'%s')
-
-def docopy(target,source,env):
- data = source[0].get_contents()
- f = open(target[0].rfile().get_abspath(), "wb")
- f.write(data)
- f.close()
-
-def sillyScanner(node, env, dirs):
- print 'This is never called (unless we build file.out)'
- return []
-
-SillyScanner = SCons.Scanner.Base(function = sillyScanner, skeys = ['.res'])
-
-env = Environment(tools=[],
- SCANNERS = [SillyScanner],
- BUILDERS = {})
-
-r = env.Command('file.res', 'file.ma', docopy)
-
-env.Command('file.out', r, docopy)
-
-# make r the default. Note that we don't even try to build file.out,
-# and so SillyScanner never runs. The bug is the same if we build
-# file.out, though.
-Default(r)
-""" % test.workpath('cache3'))
-
-test.write(['subdir', 'file.ma'], "subdir/file.ma\n")
-
-test.run(chdir = 'subdir')
-
-test.must_not_exist(test.workpath('cache3', 'N', 'None'))
-
-#############################################################################
-# Test that multiple target files get retrieved from cache correctly.
-
-test.subdir('multiple', 'cache4')
-
-test.write(['multiple', 'SConstruct'], """\
-def touch(env, source, target):
- open('foo', 'w').write("")
- open('bar', 'w').write("")
-CacheDir(r'%s')
-env = Environment()
-env.Command(['foo', 'bar'], ['input'], touch)
-""" % (test.workpath('cache4')))
-
-test.write(['multiple', 'input'], "multiple/input\n")
-
-test.run(chdir = 'multiple')
-
-test.must_exist(test.workpath('multiple', 'foo'))
-test.must_exist(test.workpath('multiple', 'bar'))
-
-test.run(chdir = 'multiple', arguments = '-c')
-
-test.must_not_exist(test.workpath('multiple', 'foo'))
-test.must_not_exist(test.workpath('multiple', 'bar'))
-
-test.run(chdir = 'multiple')
-
-test.must_exist(test.workpath('multiple', 'foo'))
-test.must_exist(test.workpath('multiple', 'bar'))
-
-# All done.
-test.pass_test()
--- /dev/null
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Test retrieving derived files from a CacheDir when a BuildDir is used.
+"""
+
+import os.path
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+test.subdir('cache', 'src')
+
+cache = test.workpath('cache')
+cat_out = test.workpath('cat.out')
+
+test.write(['src', 'SConstruct'], """\
+CacheDir(r'%(cache)s')
+SConscript('SConscript')
+""" % locals())
+
+test.write(['src', 'SConscript'], """\
+def cat(env, source, target):
+ target = str(target[0])
+ open('cat.out', 'ab').write(target + "\\n")
+ source = map(str, source)
+ f = open(target, "wb")
+ for src in source:
+ f.write(open(src, "rb").read())
+ f.close()
+env = Environment(BUILDERS={'Cat':Builder(action=cat)})
+env.Cat('aaa.out', 'aaa.in')
+env.Cat('bbb.out', 'bbb.in')
+env.Cat('ccc.out', 'ccc.in')
+env.Cat('all', ['aaa.out', 'bbb.out', 'ccc.out'])
+""")
+
+build_aaa_out = os.path.join('build', 'aaa.out')
+build_bbb_out = os.path.join('build', 'bbb.out')
+build_ccc_out = os.path.join('build', 'ccc.out')
+build_all = os.path.join('build', 'all')
+
+test.write(['src', 'aaa.in'], "aaa.in\n")
+test.write(['src', 'bbb.in'], "bbb.in\n")
+test.write(['src', 'ccc.in'], "ccc.in\n")
+
+#
+test.write('SConstruct', """\
+env = Environment(TWO = '2')
+env.CacheDir(r'%s')
+BuildDir('build', 'src', duplicate=0)
+SConscript('build/SConscript')
+""" % test.workpath('cache${TWO}'))
+
+# Verify that a normal build works correctly, and clean up.
+# This should populate the cache with our derived files.
+test.run()
+
+test.must_match(['build', 'all'], "aaa.in\nbbb.in\nccc.in\n")
+test.must_match('cat.out', "%s\n%s\n%s\n%s\n" % (build_aaa_out, build_bbb_out, build_ccc_out, build_all))
+
+test.up_to_date(arguments = '.')
+
+test.run(arguments = '-c .')
+test.unlink('cat.out')
+
+# Verify that we now retrieve the derived files from cache,
+# not rebuild them. Then clean up.
+test.run(stdout = test.wrap_stdout("""\
+Retrieved `%s' from cache
+Retrieved `%s' from cache
+Retrieved `%s' from cache
+Retrieved `%s' from cache
+""" % (build_aaa_out, build_bbb_out, build_ccc_out, build_all)))
+
+test.must_not_exist(cat_out)
+
+test.up_to_date(arguments = '.')
+
+test.run(arguments = '-c .')
+
+# Verify that rebuilding with -n reports that everything was retrieved
+# from the cache, but that nothing really was.
+test.run(arguments = '-n .', stdout = test.wrap_stdout("""\
+Retrieved `%s' from cache
+Retrieved `%s' from cache
+Retrieved `%s' from cache
+Retrieved `%s' from cache
+""" % (build_aaa_out, build_bbb_out, build_ccc_out, build_all)))
+
+test.must_not_exist(test.workpath('build', 'aaa.out'))
+test.must_not_exist(test.workpath('build', 'bbb.out'))
+test.must_not_exist(test.workpath('build', 'ccc.out'))
+test.must_not_exist(test.workpath('build', 'all'))
+
+# Verify that rebuilding with -s retrieves everything from the cache
+# even though it doesn't report anything.
+test.run(arguments = '-s .', stdout = "")
+
+test.must_match(['build', 'all'], "aaa.in\nbbb.in\nccc.in\n")
+test.must_not_exist(cat_out)
+
+test.up_to_date(arguments = '.')
+
+test.run(arguments = '-c .')
+
+# Verify that updating one input file builds its derived file and
+# dependency but that the other files are retrieved from cache.
+test.write(['src', 'bbb.in'], "bbb.in 2\n")
+
+test.run(stdout = test.wrap_stdout("""\
+Retrieved `%s' from cache
+cat(["%s"], ["%s"])
+Retrieved `%s' from cache
+cat(["%s"], ["%s", "%s", "%s"])
+""" % (build_aaa_out,
+ build_bbb_out, os.path.join('src', 'bbb.in'),
+ build_ccc_out,
+ build_all, build_aaa_out, build_bbb_out, build_ccc_out)))
+
+test.must_match(['build', 'all'], "aaa.in\nbbb.in 2\nccc.in\n")
+test.must_match('cat.out', "%s\n%s\n" % (build_bbb_out, build_all))
+
+test.up_to_date(arguments = '.')
+
+
+
+test.pass_test()
--- /dev/null
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Test retrieving derived files from a CacheDir.
+"""
+
+import os
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+cache = test.workpath('cache')
+
+src_aaa_out = test.workpath('src', 'aaa.out')
+src_bbb_out = test.workpath('src', 'bbb.out')
+src_ccc_out = test.workpath('src', 'ccc.out')
+src_cat_out = test.workpath('src', 'cat.out')
+src_all = test.workpath('src', 'all')
+
+test.subdir('cache', 'src')
+
+test.write(['src', 'SConstruct'], """\
+CacheDir(r'%(cache)s')
+SConscript('SConscript')
+""" % locals())
+
+test.write(['src', 'SConscript'], """\
+def cat(env, source, target):
+ target = str(target[0])
+ open('cat.out', 'ab').write(target + "\\n")
+ source = map(str, source)
+ f = open(target, "wb")
+ for src in source:
+ f.write(open(src, "rb").read())
+ f.close()
+env = Environment(BUILDERS={'Cat':Builder(action=cat)})
+env.Cat('aaa.out', 'aaa.in')
+env.Cat('bbb.out', 'bbb.in')
+env.Cat('ccc.out', 'ccc.in')
+env.Cat('all', ['aaa.out', 'bbb.out', 'ccc.out'])
+""")
+
+test.write(['src', 'aaa.in'], "aaa.in\n")
+test.write(['src', 'bbb.in'], "bbb.in\n")
+test.write(['src', 'ccc.in'], "ccc.in\n")
+
+# Verify that building with -n and an empty cache reports that proper
+# build operations would be taken, but that nothing is actually built
+# and that the cache is still empty.
+test.run(chdir = 'src', arguments = '-n .', stdout = test.wrap_stdout("""\
+cat(["aaa.out"], ["aaa.in"])
+cat(["bbb.out"], ["bbb.in"])
+cat(["ccc.out"], ["ccc.in"])
+cat(["all"], ["aaa.out", "bbb.out", "ccc.out"])
+"""))
+
+test.must_not_exist(src_aaa_out)
+test.must_not_exist(src_bbb_out)
+test.must_not_exist(src_ccc_out)
+test.must_not_exist(src_all)
+test.fail_test(len(os.listdir(cache)))
+
+# Verify that a normal build works correctly, and clean up.
+# This should populate the cache with our derived files.
+test.run(chdir = 'src', arguments = '.')
+
+test.must_match(['src', 'all'], "aaa.in\nbbb.in\nccc.in\n")
+test.must_match(['src', 'cat.out'], "aaa.out\nbbb.out\nccc.out\nall\n")
+
+test.up_to_date(chdir = 'src', arguments = '.')
+
+test.run(chdir = 'src', arguments = '-c .')
+test.unlink(['src', 'cat.out'])
+
+# Verify that we now retrieve the derived files from cache,
+# not rebuild them. Then clean up.
+test.run(chdir = 'src', arguments = '.', stdout = test.wrap_stdout("""\
+Retrieved `aaa.out' from cache
+Retrieved `bbb.out' from cache
+Retrieved `ccc.out' from cache
+Retrieved `all' from cache
+"""))
+
+test.must_not_exist(src_cat_out)
+
+test.up_to_date(chdir = 'src', arguments = '.')
+
+test.run(chdir = 'src', arguments = '-c .')
+
+# Verify that rebuilding with -n reports that everything was retrieved
+# from the cache, but that nothing really was.
+test.run(chdir = 'src', arguments = '-n .', stdout = test.wrap_stdout("""\
+Retrieved `aaa.out' from cache
+Retrieved `bbb.out' from cache
+Retrieved `ccc.out' from cache
+Retrieved `all' from cache
+"""))
+
+test.must_not_exist(src_aaa_out)
+test.must_not_exist(src_bbb_out)
+test.must_not_exist(src_ccc_out)
+test.must_not_exist(src_all)
+
+# Verify that rebuilding with -s retrieves everything from the cache
+# even though it doesn't report anything.
+test.run(chdir = 'src', arguments = '-s .', stdout = "")
+
+test.must_match(['src', 'all'], "aaa.in\nbbb.in\nccc.in\n")
+test.must_not_exist(src_cat_out)
+
+test.up_to_date(chdir = 'src', arguments = '.')
+
+test.run(chdir = 'src', arguments = '-c .')
+
+# Verify that updating one input file builds its derived file and
+# dependency but that the other files are retrieved from cache.
+test.write(['src', 'bbb.in'], "bbb.in 2\n")
+
+test.run(chdir = 'src', arguments = '.', stdout = test.wrap_stdout("""\
+Retrieved `aaa.out' from cache
+cat(["bbb.out"], ["bbb.in"])
+Retrieved `ccc.out' from cache
+cat(["all"], ["aaa.out", "bbb.out", "ccc.out"])
+"""))
+
+test.must_match(['src', 'all'], "aaa.in\nbbb.in 2\nccc.in\n")
+test.must_match(['src', 'cat.out'], "bbb.out\nall\n")
+
+test.up_to_date(chdir = 'src', arguments = '.')
+
+
+test.pass_test()
--- /dev/null
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Test that use of SideEffect() doesn't interfere with CacheDir.
+"""
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+test.subdir('cache', 'work')
+
+cache = test.workpath('cache')
+
+test.write(['work', 'SConstruct'], """\
+def copy(source, target):
+ open(target, "wb").write(open(source, "rb").read())
+
+def build(env, source, target):
+ s = str(source[0])
+ t = str(target[0])
+ copy(s, t)
+ if target[0].side_effects:
+ side_effect = open(str(target[0].side_effects[0]), "ab")
+ side_effect.write(s + ' -> ' + t + '\\n')
+
+CacheDir(r'%(cache)s')
+
+Build = Builder(action=build)
+env = Environment(BUILDERS={'Build':Build}, SUBDIR='subdir')
+env.Build('f1.out', 'f1.in')
+env.Build('f2.out', 'f2.in')
+env.Build('f3.out', 'f3.in')
+SideEffect('log.txt', ['f1.out', 'f2.out', 'f3.out'])
+""" % locals())
+
+test.write(['work', 'f1.in'], 'f1.in\n')
+test.write(['work', 'f2.in'], 'f2.in\n')
+test.write(['work', 'f3.in'], 'f3.in\n')
+
+test.run(chdir='work', arguments='f1.out f2.out')
+
+expect = """\
+f1.in -> f1.out
+f2.in -> f2.out
+"""
+
+test.must_match(['work', 'log.txt'], expect)
+
+
+
+test.write(['work', 'f2.in'], 'f2.in 2 \n')
+
+test.run(chdir='work', arguments='log.txt')
+
+expect = """\
+f1.in -> f1.out
+f2.in -> f2.out
+f2.in -> f2.out
+f3.in -> f3.out
+"""
+
+test.must_match(['work', 'log.txt'], expect)
+
+
+
+test.write(['work', 'f1.in'], 'f1.in 2 \n')
+
+test.run(chdir='work', arguments=".")
+
+expect = """\
+f1.in -> f1.out
+f2.in -> f2.out
+f2.in -> f2.out
+f3.in -> f3.out
+f1.in -> f1.out
+"""
+
+test.must_match(['work', 'log.txt'], expect)
+
+
+
+test.pass_test()
--- /dev/null
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Test the --cache-debug option to see if it prints the expected messages.
+
+Note that we don't check for the "race condition" message when someone
+else's build populates the CacheDir with a file in between the time we
+to build it because it doesn't exist in the CacheDir, and the time our
+build of the file completes and we push it out.
+"""
+
+import os
+
+import TestSCons
+
+test = TestSCons.TestSCons(match=TestSCons.match_re)
+
+test.subdir('cache', 'src')
+
+cache = test.workpath('cache')
+debug_out = test.workpath('cache-debug.out')
+
+
+
+test.write(['src', 'SConstruct'], """\
+CacheDir(r'%(cache)s')
+SConscript('SConscript')
+""" % locals())
+
+test.write(['src', 'SConscript'], """\
+def cat(env, source, target):
+ target = str(target[0])
+ open('cat.out', 'ab').write(target + "\\n")
+ source = map(str, source)
+ f = open(target, "wb")
+ for src in source:
+ f.write(open(src, "rb").read())
+ f.close()
+env = Environment(BUILDERS={'Cat':Builder(action=cat)})
+env.Cat('aaa.out', 'aaa.in')
+env.Cat('bbb.out', 'bbb.in')
+env.Cat('ccc.out', 'ccc.in')
+env.Cat('all', ['aaa.out', 'bbb.out', 'ccc.out'])
+""")
+
+test.write(['src', 'aaa.in'], "aaa.in\n")
+test.write(['src', 'bbb.in'], "bbb.in\n")
+test.write(['src', 'ccc.in'], "ccc.in\n")
+
+
+
+# Test for messages about files not being in CacheDir, with -n (don't
+# actually build or push) and sendinig the message to a file.
+
+expect = \
+r"""cat\(\["aaa.out"\], \["aaa.in"\]\)
+cat\(\["bbb.out"\], \["bbb.in"\]\)
+cat\(\["ccc.out"\], \["ccc.in"\]\)
+cat\(\["all"\], \["aaa.out", "bbb.out", "ccc.out"\]\)
+"""
+
+test.run(chdir='src',
+ arguments='-n -Q --cache-debug=%s .' % debug_out,
+ stdout=expect)
+
+expect = \
+r"""CacheRetrieve\(aaa.out\): [0-9a-fA-F]+ not in cache
+CacheRetrieve\(bbb.out\): [0-9a-fA-F]+ not in cache
+CacheRetrieve\(ccc.out\): [0-9a-fA-F]+ not in cache
+CacheRetrieve\(all\): [0-9a-fA-F]+ not in cache
+"""
+
+test.must_match(debug_out, expect, mode='r')
+
+
+
+# Test for messages about actually pushing to the cache, without -n
+# and to standard ouput.
+
+expect = \
+r"""CacheRetrieve\(aaa.out\): [0-9a-fA-F]+ not in cache
+cat\(\["aaa.out"\], \["aaa.in"\]\)
+CachePush\(aaa.out\): pushing to [0-9a-fA-F]+
+CacheRetrieve\(bbb.out\): [0-9a-fA-F]+ not in cache
+cat\(\["bbb.out"\], \["bbb.in"\]\)
+CachePush\(bbb.out\): pushing to [0-9a-fA-F]+
+CacheRetrieve\(ccc.out\): [0-9a-fA-F]+ not in cache
+cat\(\["ccc.out"\], \["ccc.in"\]\)
+CachePush\(ccc.out\): pushing to [0-9a-fA-F]+
+CacheRetrieve\(all\): [0-9a-fA-F]+ not in cache
+cat\(\["all"\], \["aaa.out", "bbb.out", "ccc.out"\]\)
+CachePush\(all\): pushing to [0-9a-fA-F]+
+"""
+
+test.run(chdir='src',
+ arguments='-Q --cache-debug=- .',
+ stdout=expect)
+
+
+
+# Clean up the local targets.
+
+test.run(chdir='src', arguments='-c --cache-debug=%s .' % debug_out)
+test.unlink(['src', 'cat.out'])
+
+
+
+# Test for messages about retrieving files from CacheDir, with -n
+# and sending the messages to standard output.
+
+expect = \
+r"""Retrieved `aaa.out' from cache
+CacheRetrieve\(aaa.out\): retrieving from [0-9a-fA-F]+
+Retrieved `bbb.out' from cache
+CacheRetrieve\(bbb.out\): retrieving from [0-9a-fA-F]+
+Retrieved `ccc.out' from cache
+CacheRetrieve\(ccc.out\): retrieving from [0-9a-fA-F]+
+Retrieved `all' from cache
+CacheRetrieve\(all\): retrieving from [0-9a-fA-F]+
+"""
+
+test.run(chdir='src',
+ arguments='-n -Q --cache-debug=- .',
+ stdout=expect)
+
+
+
+# And finally test for message about retrieving file from CacheDir
+# *without* -n and sending the message to a file.
+
+expect = \
+r"""Retrieved `aaa.out' from cache
+Retrieved `bbb.out' from cache
+Retrieved `ccc.out' from cache
+Retrieved `all' from cache
+"""
+
+test.run(chdir='src',
+ arguments='-Q --cache-debug=%s .' % debug_out,
+ stdout=expect)
+
+expect = \
+r"""CacheRetrieve\(aaa.out\): retrieving from [0-9a-fA-F]+
+CacheRetrieve\(bbb.out\): retrieving from [0-9a-fA-F]+
+CacheRetrieve\(ccc.out\): retrieving from [0-9a-fA-F]+
+CacheRetrieve\(all\): retrieving from [0-9a-fA-F]+
+"""
+
+test.must_match(debug_out, expect, mode='r')
+
+
+
+test.pass_test()
--- /dev/null
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Test that multiple target files get retrieved from a CacheDir correctly.
+"""
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+test.subdir('cache', 'multiple')
+
+cache = test.workpath('cache')
+
+multiple_bar = test.workpath('multiple', 'bar')
+multiple_foo = test.workpath('multiple', 'foo')
+
+test.write(['multiple', 'SConstruct'], """\
+def touch(env, source, target):
+ open('foo', 'w').write("")
+ open('bar', 'w').write("")
+CacheDir(r'%(cache)s')
+env = Environment()
+env.Command(['foo', 'bar'], ['input'], touch)
+""" % locals())
+
+test.write(['multiple', 'input'], "multiple/input\n")
+
+test.run(chdir = 'multiple')
+
+test.must_exist(multiple_foo)
+test.must_exist(multiple_bar)
+
+test.run(chdir = 'multiple', arguments = '-c')
+
+test.must_not_exist(multiple_foo)
+test.must_not_exist(multiple_bar)
+
+test.run(chdir = 'multiple')
+
+test.must_exist(multiple_foo)
+test.must_exist(multiple_bar)
+
+
+
+test.pass_test()
--- /dev/null
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Test retrieving derived files from a CacheDir.
+
+This tests the case reported by Jeff Petkau (SourceForge bug #694744)
+where a target is source for another target with a scanner, which used
+to cause us to push the file to the CacheDir after the build signature
+had already been cleared (as a sign that the built file should now
+be rescanned).
+"""
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+cache = test.workpath('cache')
+
+test.subdir('cache', 'subdir')
+
+test.write(['subdir', 'SConstruct'], """\
+import SCons
+
+CacheDir(r'%(cache)s')
+
+def docopy(target,source,env):
+ data = source[0].get_contents()
+ f = open(target[0].rfile().get_abspath(), "wb")
+ f.write(data)
+ f.close()
+
+def sillyScanner(node, env, dirs):
+ print 'This is never called (unless we build file.out)'
+ return []
+
+SillyScanner = SCons.Scanner.Base(function = sillyScanner, skeys = ['.res'])
+
+env = Environment(tools=[],
+ SCANNERS = [SillyScanner],
+ BUILDERS = {})
+
+r = env.Command('file.res', 'file.ma', docopy)
+
+env.Command('file.out', r, docopy)
+
+# make r the default. Note that we don't even try to build file.out,
+# and so SillyScanner never runs. The bug is the same if we build
+# file.out, though.
+Default(r)
+""" % locals())
+
+test.write(['subdir', 'file.ma'], "subdir/file.ma\n")
+
+test.run(chdir = 'subdir')
+
+test.must_not_exist(test.workpath(cache, 'N', 'None'))
+
+
+
+test.pass_test()
""")
test.write('main.c', """\
+#include <stdlib.h>
+
void foo();
void bar();
int main() {
import TestSCons
python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
t.close()
return 0
-env = Environment(COPY_THROUGH_TEMP = "%(python)s build.py .tmp $SOURCE\\n%(python)s build.py $TARGET .tmp",
- EXPAND = "$COPY_THROUGH_TEMP")
+env = Environment(COPY_THROUGH_TEMP = '%(_python_)s build.py .tmp $SOURCE\\n%(_python_)s build.py $TARGET .tmp',
+ EXPAND = '$COPY_THROUGH_TEMP')
env.Command(target = 'f1.out', source = 'f1.in',
action = buildIt)
env.Command(target = 'f2.out', source = 'f2.in',
- action = r"%(python)s build.py temp2 $SOURCES" + '\\n' + r"%(python)s build.py $TARGET temp2")
+ action = r'%(_python_)s build.py temp2 $SOURCES' + '\\n' + r'%(_python_)s build.py $TARGET temp2')
env.Command(target = 'f3.out', source = 'f3.in',
action = [ [ r'%(python)s', 'build.py', 'temp3', '$SOURCES' ],
[ r'%(python)s', 'build.py', '$TARGET', 'temp3'] ])
Command(target = 'f4.out', source = 'sub', action = sub)
env.Command(target = 'f5.out', source = 'f5.in', action = buildIt,
- XYZZY="XYZZY is set")
+ XYZZY='XYZZY is set')
Command(target = 'f6.out', source = 'f6.in',
- action = r"%(python)s build.py f6.out f6.in")
+ action = r'%(_python_)s build.py f6.out f6.in')
env.Command(target = 'f7.out', source = 'f7.in',
- action = r"%(python)s build.py $TARGET $SOURCE")
+ action = r'%(_python_)s build.py $TARGET $SOURCE')
Command(target = 'f8.out', source = 'f8.in',
- action = r"%(python)s build.py $TARGET $SOURCE")
+ action = r'%(_python_)s build.py $TARGET $SOURCE')
env.Command(target = 'f9.out', source = 'f9.in',
- action = r"$EXPAND")
+ action = r'$EXPAND')
env.Command(target = '${F10}.out', source = '${F10}.in',
- action = r"%(python)s build.py $TARGET $SOURCE",
+ action = r'%(_python_)s build.py $TARGET $SOURCE',
F10 = 'f10')
-""" % {'python': python})
+""" % locals())
test.write('f1.in', "f1.in\n")
test.write('f2.in', "f2.in\n")
test.write('SConstruct', """
def g(source, target, for_signature, env):
import sys
- python = r"%s"
+ python = r'%(python)s'
return [[python, "build.py", "$TEMPFILE"] + source,
[python, "build.py"] + target + ["$TEMPFILE"]]
env.b(target = 'foo1.out', source = 'foo1.in')
env.b(target = 'foo2.out', source = 'foo2.in')
env.b(target = 'foo3.out', source = 'foo3.in')
-""" % python)
+""" % locals())
test.write('foo1.in', "foo1.in\n")
#!/usr/bin/env python
#
-# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
+# __COPYRIGHT__
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "test/Configure.py 0.96.D308 2005/09/25 12:59:35 knight"
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
"""
Test that the configure context directory can be specified by
test = TestSCons.TestSCons()
-test.write("SConstruct", """\
+SConstruct_path = test.workpath('SConstruct')
+
+test.write(SConstruct_path, """\
def CustomTest(context):
context.Message('Executing Custom Test ...')
context.Result(1)
test.run()
expect = """\
-file SConstruct,line 6:
+file %(SConstruct_path)s,line 6:
\tConfigure(confdir = .sconf_temp)
scons: Configure: Executing Custom Test ...
scons: Configure: (cached) yes
-"""
+""" % locals()
test.must_match('custom.logfile', expect, mode='r')
work_cnt = 0
work_dir = None
python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
_obj = TestSCons._obj
_exe = TestSCons._exe
sconf_dir = sconf_dir
sconstruct = sconstruct
- log = re.escape("file " + sconstruct + ",line ") + r"\d+:" + ls
+ log = r'file\ \S*%s\,line \d+:' % re.escape(sconstruct) + ls
if doCheckLog: lastEnd = matchPart(log, logfile, lastEnd)
log = "\t" + re.escape("Configure(confdir = %s)" % sconf_dir) + ls
if doCheckLog: lastEnd = matchPart(log, logfile, lastEnd)
return 0
conf = env.Configure(custom_tests = {'MyTest' : CustomTest})
if not conf.MyTest():
- env.Command("hello", [], "%s cmd.py $TARGET")
+ env.Command("hello", [], '%(_python_)s cmd.py $TARGET')
env = conf.Finish()
-""" % python)
+""" % locals())
test.run(chdir=work_dir, stderr="Hello World on stderr\n")
# 4.2 test that calling Configure from a builder results in a
# 5.1 test the ConfigureDryRunError
reset(EXACT) # exact match
- test.write([work_dir, 'SConstruct'], """
+
+ SConstruct_path = test.workpath(work_dir, 'SConstruct')
+
+ test.write(SConstruct_path, """
env = Environment()
import os
env.AppendENVPath('PATH', os.environ['PATH'])
test.run(chdir=work_dir, arguments='-n', status=2, stderr="""
scons: *** Cannot create configure directory ".sconf_temp" within a dry-run.
-File "SConstruct", line 5, in ?
-""")
+File "%(SConstruct_path)s", line 5, in ?
+""" % locals())
test.must_not_exist([work_dir, 'config.log'])
test.subdir([work_dir, '.sconf_temp'])
+
+ conftest_0_c = os.path.join(".sconf_temp", "conftest_0.c")
test.run(chdir=work_dir, arguments='-n', status=2, stderr="""
-scons: *** Cannot update configure test "%s" within a dry-run.
-File "SConstruct", line 6, in ?
-""" % os.path.join(".sconf_temp", "conftest_0.c"))
+scons: *** Cannot update configure test "%(conftest_0_c)s" within a dry-run.
+File "%(SConstruct_path)s", line 6, in ?
+""" % locals())
test.run(chdir=work_dir)
checkLogAndStdout( ["Checking for C library %s... " % lib,
# 5.2 test the --config=<auto|force|cache> option
reset(EXACT) # exact match
- test.write([work_dir, 'SConstruct'], """
+ SConstruct_path = test.workpath(work_dir, 'SConstruct')
+
+ test.write(SConstruct_path, """
env = Environment(CPPPATH='#/include')
import os
env.AppendENVPath('PATH', os.environ['PATH'])
/* A header */
""")
+ conftest_0_c = os.path.join(".sconf_temp", "conftest_0.c")
+
test.run(chdir=work_dir, arguments='--config=cache', status=2, stderr="""
-scons: *** "%s" is not yet built and cache is forced.
-File "SConstruct", line 6, in ?
-""" % os.path.join(".sconf_temp", "conftest_0.c"))
+scons: *** "%(conftest_0_c)s" is not yet built and cache is forced.
+File "%(SConstruct_path)s", line 6, in ?
+""" % locals())
test.run(chdir=work_dir, arguments='--config=auto')
checkLogAndStdout( ["Checking for C header file non_system_header1.h... ",
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
Tool('dmd')(env)
# Now replace those suffixes with our fake-D things.
env.Replace(DPATH = ['.'],
- DC = r'%s mydc.py',
+ DC = r'%(_python_)s mydc.py',
DFLAGS = [],
DCOM = '$DC $TARGET $SOURCES',
OBJSUFFIX = '.o')
env.InstallAs('test1_d', 'test1.d')
env.InstallAs('test2_d', 'test2.d')
env.InstallAs('test3_d', 'test3.d')
-""" % (python,))
+""" % locals())
test.write('test1.d', """\
test1.d 1
test.write('foo.d', "foo.d 1\n")
-test.run(arguments='.', stdout=test.wrap_stdout("""\
-%s mydc.py test1.o test1.d
+expect = test.wrap_stdout("""\
+%(_python_)s mydc.py test1.o test1.d
Install file: "test1.d" as "test1_d"
Install file: "test2.d" as "test2_d"
Install file: "test3.d" as "test3_d"
-""" % (python,)))
+""" % locals())
+
+test.run(arguments='.', stdout=expect)
test.must_match('test1.o', """\
test1.d 1
test.write('foo.d', "foo.d 2\n")
-test.run(arguments='.', stdout=test.wrap_stdout("""\
-%s mydc.py test1.o test1.d
-""" % (python,)))
+expect = test.wrap_stdout("""\
+%(_python_)s mydc.py test1.o test1.d
+""" % locals())
+
+test.run(arguments='.', stdout=expect)
test.must_match('test1.o', """\
test1.d 1
import foo;
""")
-test.run(arguments='.', stdout=test.wrap_stdout("""\
-%s mydc.py test1.o test1.d
+expect = test.wrap_stdout("""\
+%(_python_)s mydc.py test1.o test1.d
Install file: "test3.d" as "test3_d"
-""" % (python,)))
+""" % locals())
+
+test.run(arguments='.', stdout=expect)
test.must_match('test1.o', """\
test1.d 1
import foo;
""")
-test.run(arguments='.', stdout=test.wrap_stdout("""\
-%s mydc.py test1.o test1.d
+expect = test.wrap_stdout("""\
+%(_python_)s mydc.py test1.o test1.d
Install file: "test2.d" as "test2_d"
-""" % (python,)))
+""" % locals())
+
+test.run(arguments='.', stdout=expect)
test.must_match('test1.o', """\
test1.d 1
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-env = Environment(TEX = r'%s mytex.py',
- LATEX = r'%s mylatex.py',
- DVIPDF = r'%s mydvipdf.py',
+env = Environment(TEX = r'%(_python_)s mytex.py',
+ LATEX = r'%(_python_)s mylatex.py',
+ DVIPDF = r'%(_python_)s mydvipdf.py',
tools=['latex', 'tex', 'dvipdf'])
dvi = env.DVI(target = 'test1.dvi', source = 'test1.tex')
env.DVI(target = 'test2.dvi', source = 'test2.tex')
env.PDF(target = 'test1.pdf', source = dvi)
env.PDF(target = 'test2.pdf', source = 'test2.dvi')
-""" % (python, python, python))
+""" % locals())
test.write('test1.tex', r"""This is a .dvi test.
#tex
foo = Environment(ENV = { 'PATH' : os.environ['PATH'] })
dvipdf = foo.Dictionary('DVIPDF')
bar = Environment(ENV = { 'PATH' : os.environ['PATH'] },
- DVIPDF = r'%s wrapper.py ' + dvipdf)
+ DVIPDF = r'%(_python_)s wrapper.py ' + dvipdf)
foo.PDF(target = 'foo.pdf',
source = foo.DVI(target = 'foo.dvi', source = 'foo.tex'))
bar.PDF(target = 'bar.pdf',
source = bar.DVI(target = 'bar.dvi', source = 'bar.tex'))
foo.PDF(target = 'xxx.pdf', source = 'xxx.tex')
-""" % python)
+""" % locals())
tex = r"""
This is the %s TeX file.
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(tools=['default', 'dvipdf'],
- DVIPDFCOM = r'%s mypdf.py $TARGET $SOURCES')
+ DVIPDFCOM = r'%(_python_)s mypdf.py $TARGET $SOURCES')
env.PDF(target = 'aaa', source = 'aaa.dvi')
-""" % python)
+""" % locals())
test.write('aaa.dvi', "aaa.dvi\n/*pdf*/\n")
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(tools=['default', 'dvipdf'],
- DVIPDFCOM = r'%s mypdf.py $TARGET $SOURCES',
+ DVIPDFCOM = r'%(_python_)s mypdf.py $TARGET $SOURCES',
DVIPDFCOMSTR = 'DVIPDFing $TARGET from $SOURCE')
env.PDF(target = 'aaa', source = 'aaa.dvi')
-""" % python)
+""" % locals())
test.write('aaa.dvi', "aaa.dvi\n/*pdf*/\n")
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-env = Environment(TEX = r'%s mytex.py',
- LATEX = r'%s mylatex.py',
- DVIPDF = r'%s mydvipdf.py', DVIPDFFLAGS = '-x',
+env = Environment(TEX = r'%(_python_)s mytex.py',
+ LATEX = r'%(_python_)s mylatex.py',
+ DVIPDF = r'%(_python_)s mydvipdf.py', DVIPDFFLAGS = '-x',
tools = ['tex', 'latex', 'dvipdf'])
dvi = env.DVI(target = 'test1.dvi', source = 'test1.tex')
env.DVI(target = 'test2.dvi', source = 'test2.tex')
env.PDF(target = 'test1.pdf', source = dvi)
env.PDF(target = 'test2.pdf', source = 'test2.dvi')
-""" % (python, python, python))
+""" % locals())
test.write('test1.tex', r"""This is a .dvi test.
#tex
ENV = {'PATH' : os.environ['PATH']}
foo = Environment(DVIPDFFLAGS = '-N', ENV = ENV)
dvipdf = foo.Dictionary('DVIPDF')
-bar = Environment(DVIPDF = r'%s wrapper.py ' + dvipdf, ENV = ENV)
+bar = Environment(DVIPDF = r'%(_python_)s wrapper.py ' + dvipdf, ENV = ENV)
foo.PDF(target = 'foo.pdf',
source = foo.DVI(target = 'foo.dvi', source = 'foo.tex'))
bar.PDF(target = 'bar.pdf',
source = bar.DVI(target = 'bar.dvi', source = 'bar.tex'))
foo.PDF(target = 'xxx.pdf', source = 'xxx.tex')
-""" % python)
+""" % locals())
tex = r"""
This is the %s TeX file.
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-env = Environment(TEX = r'%s mytex.py',
- LATEX = r'%s mylatex.py',
- DVIPS = r'%s mydvips.py',
+env = Environment(TEX = r'%(_python_)s mytex.py',
+ LATEX = r'%(_python_)s mylatex.py',
+ DVIPS = r'%(_python_)s mydvips.py',
tools=['tex', 'latex', 'dvips'])
dvi = env.DVI(target = 'test1.dvi', source = 'test1.tex')
env.PostScript(target = 'test1.ps', source = dvi)
env.PostScript(target = 'test2.ps', source = 'test2.tex')
env.PostScript(target = 'test3.ps', source = 'test3.ltx')
env.PostScript(target = 'test4.ps', source = 'test4.latex')
-""" % (python, python, python))
+""" % locals())
test.write('test1.tex', r"""This is a .dvi test.
#tex
ENV = { 'PATH' : os.environ['PATH'] }
foo = Environment(ENV = ENV)
dvips = foo.Dictionary('DVIPS')
-bar = Environment(ENV = ENV, DVIPS = r'%s wrapper.py ' + dvips)
+bar = Environment(ENV = ENV, DVIPS = r'%(_python_)s wrapper.py ' + dvips)
foo.PostScript(target = 'foo.ps', source = 'foo.tex')
bar.PostScript(target = 'bar1', source = 'bar1.tex')
bar.PostScript(target = 'bar2', source = 'bar2.ltx')
bar.PostScript(target = 'bar3', source = 'bar3.latex')
-""" % python)
+""" % locals())
tex = r"""
This is the %s TeX file.
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-env = Environment(TEX = r'%s mytex.py',
- LATEX = r'%s mylatex.py',
- DVIPS = r'%s mydvips.py', DVIPSFLAGS = '-x',
+env = Environment(TEX = r'%(_python_)s mytex.py',
+ LATEX = r'%(_python_)s mylatex.py',
+ DVIPS = r'%(_python_)s mydvips.py', DVIPSFLAGS = '-x',
tools=['tex', 'latex', 'dvips'])
dvi = env.DVI(target = 'test1.dvi', source = 'test1.tex')
env.PostScript(target = 'test1.ps', source = dvi)
env.PostScript(target = 'test2.ps', source = 'test2.tex')
env.PostScript(target = 'test3.ps', source = 'test3.ltx')
env.PostScript(target = 'test4.ps', source = 'test4.latex')
-""" % (python, python, python))
+""" % locals())
test.write('test1.tex', r"""This is a .dvi test.
#tex
ENV = {'PATH' : os.environ['PATH']}
foo = Environment(ENV = ENV, DVIPSFLAGS = '-N')
dvips = foo.Dictionary('DVIPS')
-bar = Environment(ENV = ENV,DVIPS = r'%s wrapper.py ' + dvips)
+bar = Environment(ENV = ENV,DVIPS = r'%(_python_)s wrapper.py ' + dvips)
foo.PostScript(target = 'foo.ps', source = 'foo.tex')
bar.PostScript(target = 'bar1', source = 'bar1.tex')
bar.PostScript(target = 'bar2', source = 'bar2.ltx')
bar.PostScript(target = 'bar3', source = 'bar3.latex')
-""" % python)
+""" % locals())
tex = r"""
This is the %s TeX file.
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(tools=['default', 'dvips'],
- PSCOM = r'%s myps.py $TARGET $SOURCES')
+ PSCOM = r'%(_python_)s myps.py $TARGET $SOURCES')
env.PostScript(target = 'aaa', source = 'aaa.dvi')
-""" % python)
+""" % locals())
test.write('aaa.dvi', "aaa.dvi\n/*ps*/\n")
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(tools=['default', 'dvips'],
- PSCOM = r'%s myps.py $TARGET $SOURCES',
+ PSCOM = r'%(_python_)s myps.py $TARGET $SOURCES',
PSCOMSTR = 'PostScripting $TARGET from $SOURCE')
env.PostScript(target = 'aaa', source = 'aaa.dvi')
-""" % python)
+""" % locals())
test.write('aaa.dvi', "aaa.dvi\n/*ps*/\n")
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
#
test.write(['one', 'SConstruct'], """
-B = Builder(action = r'%s ../build.py $TARGET $SOURCES')
+B = Builder(action = r'%(_python_)s ../build.py $TARGET $SOURCES')
env = Environment(BUILDERS = { 'B' : B })
env.B(target = 'foo.out', source = 'foo.in')
env.B(target = 'bar.out', source = 'bar.in')
Default('foo.out')
-""" % python)
+""" % locals())
test.write(['two', 'SConstruct'], """
-B = Builder(action = r'%s ../build.py $TARGET $SOURCES')
+B = Builder(action = r'%(_python_)s ../build.py $TARGET $SOURCES')
env = Environment(BUILDERS = { 'B' : B })
env.B(target = 'foo.out', source = 'foo.in')
env.B(target = 'bar.out', source = 'bar.in')
Default('foo.out', 'bar.out')
-""" % python)
+""" % locals())
test.write(['three', 'SConstruct'], """
-B = Builder(action = r'%s ../build.py $TARGET $SOURCES')
+B = Builder(action = r'%(_python_)s ../build.py $TARGET $SOURCES')
env = Environment(BUILDERS = { 'B' : B })
env.B(target = 'foo.out', source = 'foo.in')
env.B(target = 'bar.out', source = 'bar.in')
Default(Split('foo.out bar.out'))
-""" % python)
+""" % locals())
test.write(['four', 'SConstruct'], """
-B = Builder(action = r'%s ../build.py $TARGET $SOURCES')
+B = Builder(action = r'%(_python_)s ../build.py $TARGET $SOURCES')
env = Environment(BUILDERS = { 'B' : B })
env.B(target = ['foo bar'], source = 'foo.in')
env.B(target = 'foo', source = 'foo.in')
env.B(target = 'bar', source = 'bar.in')
Default(['foo bar'])
-""" % python)
+""" % locals())
test.write(['five', 'SConstruct'], """
-B = Builder(action = r'%s ../build.py $TARGET $SOURCES')
+B = Builder(action = r'%(_python_)s ../build.py $TARGET $SOURCES')
env = Environment(BUILDERS = { 'B' : B })
Default(env.B(target = 'foo.out', source = 'foo.in'))
Default(env.B(target = 'bar.out', source = 'bar.in'))
-""" % python)
+""" % locals())
for dir in ['one', 'two', 'three', 'four', 'five']:
# Test how a None Default() argument works to disable/reset default targets.
test.write(['six', 'SConstruct'], """\
-B = Builder(action = r'%s ../build.py $TARGET $SOURCES')
+B = Builder(action = r'%(_python_)s ../build.py $TARGET $SOURCES')
env = Environment(BUILDERS = { 'B' : B })
foo = env.B(target = 'foo.out', source = 'foo.in')
bar = env.B(target = 'bar.out', source = 'bar.in')
Default(None)
-""" % python)
+""" % locals())
test.run(chdir = 'six', status = 2, stderr =
"scons: *** No targets specified and no Default() targets found. Stop.\n")
test.write(['seven', 'SConstruct'], """\
-B = Builder(action = r'%s ../build.py $TARGET $SOURCES')
+B = Builder(action = r'%(_python_)s ../build.py $TARGET $SOURCES')
env = Environment(BUILDERS = { 'B' : B })
foo = env.B(target = 'foo.out', source = 'foo.in')
bar = env.B(target = 'bar.out', source = 'bar.in')
Default(foo, bar, None)
-""" % python)
+""" % locals())
test.run(chdir = 'seven', status = 2, stderr =
"scons: *** No targets specified and no Default() targets found. Stop.\n")
test.write(['eight', 'SConstruct'], """\
-B = Builder(action = r'%s ../build.py $TARGET $SOURCES')
+B = Builder(action = r'%(_python_)s ../build.py $TARGET $SOURCES')
env = Environment(BUILDERS = { 'B' : B })
foo = env.B(target = 'foo.out', source = 'foo.in')
bar = env.B(target = 'bar.out', source = 'bar.in')
Default(foo, None, bar)
-""" % python)
+""" % locals())
test.run(chdir = 'eight') # no arguments, use the Default
test.subdir('nine', ['nine', 'sub1'])
test.write(['nine', 'SConstruct'], """\
-B = Builder(action = r'%s build.py $TARGET $SOURCES')
+B = Builder(action = r'%(_python_)s build.py $TARGET $SOURCES')
env = Environment(BUILDERS = { 'B' : B })
env.B(target = 'xxx.out', source = 'xxx.in')
SConscript('sub1/SConscript')
-""" % python)
+""" % locals())
test.write(['nine', 'xxx.in'], "xxx.in\n")
test.write(['nine', 'sub1', 'SConscript'], """
-B = Builder(action = r'%s ../build.py $TARGET $SOURCES')
+B = Builder(action = r'%(_python_)s ../build.py $TARGET $SOURCES')
env = Environment(BUILDERS = { 'B' : B })
env.B(target = 'xxx.out', source = 'xxx.in')
Default('xxx.out')
-""" % python)
+""" % locals())
test.write(['nine', 'sub1', 'xxx.in'], "sub1/xxx.in\n")
test.write(['ten', 'SConstruct'], """\
Default('sub2')
-B = Builder(action = r'%s ../build.py $TARGET $SOURCES')
+B = Builder(action = r'%(_python_)s ../build.py $TARGET $SOURCES')
env = Environment(BUILDERS = { 'B' : B })
env.B(target = 'xxx.out', source = 'xxx.in')
SConscript('sub2/SConscript')
-""" % python)
+""" % locals())
test.write(['ten', 'xxx.in'], "xxx.in\n")
test.write(['ten', 'sub2', 'SConscript'], """
-B = Builder(action = r'%s ../build.py $TARGET $SOURCES')
+B = Builder(action = r'%(_python_)s ../build.py $TARGET $SOURCES')
env = Environment(BUILDERS = { 'B' : B })
env.B(target = 'xxx.out', source = 'xxx.in')
-""" % python)
+""" % locals())
test.write(['ten', 'sub2', 'xxx.in'], "sub2/xxx.in\n")
test.subdir('eleven')
test.write(['eleven', 'SConstruct'], """
-B = Builder(action = r'%s ../build.py $TARGET $SOURCES')
+B = Builder(action = r'%(_python_)s ../build.py $TARGET $SOURCES')
env = Environment(BUILDERS = { 'B' : B }, XXX = 'foo.out')
env.B(target = 'foo.out', source = 'foo.in')
env.B(target = 'bar.out', source = 'bar.in')
env.Default('$XXX')
-""" % python)
+""" % locals())
test.write(os.path.join('eleven', 'foo.in'), "eleven/foo.in\n");
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
file.close()
""")
+SUBDIR_foo_dep = os.path.join('$SUBDIR', 'foo.dep')
+SUBDIR_f3_out = os.path.join('$SUBDIR', 'f3.out')
+
test.write('SConstruct', """
-Foo = Builder(action = r"%s build.py $TARGET $SOURCES subdir/foo.dep")
-Bar = Builder(action = r"%s build.py $TARGET $SOURCES subdir/bar.dep")
+Foo = Builder(action = r'%(_python_)s build.py $TARGET $SOURCES subdir/foo.dep')
+Bar = Builder(action = r'%(_python_)s build.py $TARGET $SOURCES subdir/bar.dep')
env = Environment(BUILDERS = { 'Foo' : Foo, 'Bar' : Bar }, SUBDIR='subdir')
-env.Depends(target = ['f1.out', 'f2.out'], dependency = r'%s')
-env.Depends(target = r'%s', dependency = 'subdir/bar.dep')
+env.Depends(target = ['f1.out', 'f2.out'], dependency = r'%(SUBDIR_foo_dep)s')
+env.Depends(target = r'%(SUBDIR_f3_out)s', dependency = 'subdir/bar.dep')
env.Foo(target = 'f1.out', source = 'f1.in')
env.Foo(target = 'f2.out', source = 'f2.in')
env.Bar(target = 'subdir/f3.out', source = 'f3.in')
env.Foo(target = 'f5.out', source = 'f5.in')
env.Bar(target = 'sub2/f6.out', source = 'f6.in')
env.Depends(target = 'f5.out', dependency = 'sub2')
-""" % (python,
- python,
- os.path.join('$SUBDIR', 'foo.dep'),
- os.path.join('$SUBDIR', 'f3.out')))
+""" % locals())
test.write(['subdir', 'SConscript'], """
Import("env")
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
import os
-Bld = Builder(action = r"%s build.py $TARGET $SOURCES")
+Bld = Builder(action = r'%(_python_)s build.py $TARGET $SOURCES')
env1 = Environment(BUILDERS = { 'Bld' : Bld })
env2 = Environment(BUILDERS = { 'Bld' : Bld })
env1['ENV']['X'] = 'env1'
env2['ENV']['X'] = 'env2'
env1.Bld(target = 'env1.out', source = 'input')
env2.Bld(target = 'env2.out', source = 'input')
-""" % python)
+""" % locals())
test.write('build.py',
r"""#!/usr/bin/env python
test.write('SConstruct', """
env = Environment()
-foo = env.Command('foo', [], r'%s build.py $TARGET')
+foo = env.Command('foo', [], r'%(_python_)s build.py $TARGET')
env['ENV']['LIST'] = [foo, 'bar']
env['ENV']['FOO'] = foo
-"""%python)
+""" % locals())
test.write('build.py',
r"""
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
s = string.replace(s, 'file.in', 'file.xxx')
return orig_escape(s)
env = Environment(ESCAPE = my_escape)
-env.Command('file.out', 'file.in', "%(python)s cat.py $TARGET $SOURCES")
+env.Command('file.out', 'file.in', '%(_python_)s cat.py $TARGET $SOURCES')
""" % locals())
test.write('file.in', "file.in\n")
import TestSCons
import sys
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
env=Environment(BAR='#bar.in', BLAT='subdir/../blat blat')
target = env.Command('foo.out',
'foo.in',
- r'%s build.py $SOURCE $TARGET ${File(BAR)} ${Dir(BLAT)}')
+ r'%(_python_)s build.py $SOURCE $TARGET ${File(BAR)} ${Dir(BLAT)}')
target = target[0]
assert target == Dir('.').File('foo.out')
e2 = env.Environment(XXX='$BAR', YYY='$BLAT')
print e2['XXX']
print e2['YYY']
-"""%python)
+""" % locals())
test.write('build.py', """
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """\
-Execute("%s my_copy.py a.in a.out")
-Execute(Action("%s my_copy.py b.in b.out"))
+Execute('%(_python_)s my_copy.py a.in a.out')
+Execute(Action('%(_python_)s my_copy.py b.in b.out'))
env = Environment(COPY = 'my_copy.py')
-env.Execute("%s my_copy.py c.in c.out")
-env.Execute(Action("%s my_copy.py d.in d.out"))
-v = env.Execute("%s $COPY e.in e.out")
+env.Execute('%(_python_)s my_copy.py c.in c.out')
+env.Execute(Action('%(_python_)s my_copy.py d.in d.out'))
+v = env.Execute('%(_python_)s $COPY e.in e.out')
assert v == 0, v
-v = env.Execute(Action("%s $COPY f.in f.out"))
+v = env.Execute(Action('%(_python_)s $COPY f.in f.out'))
assert v == 0, v
-v = env.Execute("%s $COPY g.in g.out 1")
+v = env.Execute('%(_python_)s $COPY g.in g.out 1')
assert v == 1, v
-v = env.Execute(Action("%s $COPY h.in h.out 2"))
+v = env.Execute(Action('%(_python_)s $COPY h.in h.out 2'))
assert v == 2, v
import shutil
Execute(lambda target, source, env: shutil.copy('i.in', 'i.out'))
Execute(Action(lambda target, source, env: shutil.copy('j.in', 'j.out')))
env.Execute(lambda target, source, env: shutil.copy('k.in', 'k.out'))
env.Execute(Action(lambda target, source, env: shutil.copy('l.in', 'l.out')))
-""" % (python, python, python, python, python, python, python, python))
+""" % locals())
test.write('a.in', "a.in\n")
test.write('b.in', "b.in\n")
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-env = Environment(LINK = r'%s mylink.py',
+env = Environment(LINK = r'%(_python_)s mylink.py',
LINKFLAGS = [],
- F77 = r'%s myfortran.py g77',
- FORTRAN = r'%s myfortran.py fortran')
+ F77 = r'%(_python_)s myfortran.py g77',
+ FORTRAN = r'%(_python_)s myfortran.py fortran')
env.Program(target = 'test01', source = 'test01.f')
env.Program(target = 'test02', source = 'test02.F')
env.Program(target = 'test03', source = 'test03.for')
env.Program(target = 'test12', source = 'test12.F90')
env.Program(target = 'test13', source = 'test13.f95')
env.Program(target = 'test14', source = 'test14.F95')
-env2 = Environment(LINK = r'%s mylink.py',
+env2 = Environment(LINK = r'%(_python_)s mylink.py',
LINKFLAGS = [],
- F77 = r'%s myfortran.py g77')
+ F77 = r'%(_python_)s myfortran.py g77')
env2.Program(target = 'test21', source = 'test21.f')
env2.Program(target = 'test22', source = 'test22.F')
env2.Program(target = 'test23', source = 'test23.for')
env2.Program(target = 'test28', source = 'test28.FPP')
env2.Program(target = 'test29', source = 'test29.f77')
env2.Program(target = 'test30', source = 'test30.F77')
-""" % (python, python, python, python, python))
+""" % locals())
test.write('test01.f', "This is a .f file.\n#link\n#fortran\n")
test.write('test02.F', "This is a .F file.\n#link\n#fortran\n")
""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
test.write('SConstruct', """
-foo = Environment(LIBS = %s)
+foo = Environment(LIBS = %(FTN_LIB)s)
f77 = foo.Dictionary('F77')
-bar = foo.Copy(F77 = r'%s wrapper.py ' + f77)
+bar = foo.Copy(F77 = r'%(_python_)s wrapper.py ' + f77)
foo.Program(target = 'foo', source = 'foo.f')
bar.Program(target = 'bar', source = 'bar.f')
-""" % (FTN_LIB, python))
+""" % locals())
test.write('foo.f', r"""
PROGRAM FOO
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-env = Environment(LINK = r'%s mylink.py',
+env = Environment(LINK = r'%(_python_)s mylink.py',
LINKFLAGS = [],
- F77COM = r'%s myfortran.py f77 $TARGET $SOURCES',
- F77PPCOM = r'%s myfortran.py f77pp $TARGET $SOURCES',
- FORTRANCOM = r'%s myfortran.py fortran $TARGET $SOURCES',
- FORTRANPPCOM = r'%s myfortran.py fortranpp $TARGET $SOURCES')
+ F77COM = r'%(_python_)s myfortran.py f77 $TARGET $SOURCES',
+ F77PPCOM = r'%(_python_)s myfortran.py f77pp $TARGET $SOURCES',
+ FORTRANCOM = r'%(_python_)s myfortran.py fortran $TARGET $SOURCES',
+ FORTRANPPCOM = r'%(_python_)s myfortran.py fortranpp $TARGET $SOURCES')
env.Program(target = 'test01', source = 'test01.f')
env.Program(target = 'test02', source = 'test02.F')
env.Program(target = 'test03', source = 'test03.for')
env.Program(target = 'test12', source = 'test12.F90')
env.Program(target = 'test13', source = 'test13.f95')
env.Program(target = 'test14', source = 'test14.F95')
-env2 = Environment(LINK = r'%s mylink.py',
+env2 = Environment(LINK = r'%(_python_)s mylink.py',
LINKFLAGS = [],
- F77COM = r'%s myfortran.py f77 $TARGET $SOURCES',
- F77PPCOM = r'%s myfortran.py f77pp $TARGET $SOURCES')
+ F77COM = r'%(_python_)s myfortran.py f77 $TARGET $SOURCES',
+ F77PPCOM = r'%(_python_)s myfortran.py f77pp $TARGET $SOURCES')
env2.Program(target = 'test21', source = 'test21.f')
env2.Program(target = 'test22', source = 'test22.F')
env2.Program(target = 'test23', source = 'test23.for')
env2.Program(target = 'test28', source = 'test28.FPP')
env2.Program(target = 'test29', source = 'test29.f77')
env2.Program(target = 'test30', source = 'test30.F77')
-""" % (python, python, python, python, python, python, python, python))
+""" % locals())
test.write('test01.f', "This is a .f file.\n#link\n#fortran\n")
test.write('test02.F', "This is a .F file.\n#link\n#fortranpp\n")
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
-env = Environment(F77COM = r'%(python)s myfc.py f77 $TARGET $SOURCES',
+env = Environment(F77COM = r'%(_python_)s myfc.py f77 $TARGET $SOURCES',
F77COMSTR = 'Building f77 $TARGET from $SOURCES',
- F77PPCOM = r'%(python)s myfc.py f77pp $TARGET $SOURCES',
+ F77PPCOM = r'%(_python_)s myfc.py f77pp $TARGET $SOURCES',
F77PPCOMSTR = 'Building f77pp $TARGET from $SOURCES',
OBJSUFFIX='.obj')
env.Object(source = 'test01.f')
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
_exe = TestSCons._exe
test.write('SConstruct', """
-env = Environment(LINK = r'%s mylink.py',
+env = Environment(LINK = r'%(_python_)s mylink.py',
LINKFLAGS = [],
- F77 = r'%s myg77.py',
+ F77 = r'%(_python_)s myg77.py',
F77FLAGS = '-x')
env.Program(target = 'test01', source = 'test01.f')
env.Program(target = 'test02', source = 'test02.F')
env.Program(target = 'test08', source = 'test08.FPP')
env.Program(target = 'test09', source = 'test09.f77')
env.Program(target = 'test10', source = 'test10.F77')
-""" % (python, python))
+""" % locals())
test.write('test01.f', "This is a .f file.\n#link\n#g77\n")
test.write('test02.F', "This is a .F file.\n#link\n#g77\n")
""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
test.write('SConstruct', """
-foo = Environment(LIBS = %s)
+foo = Environment(LIBS = %FTN_LIBs)
f77 = foo.Dictionary('F77')
-bar = foo.Copy(F77 = r'%s wrapper.py ' + f77, F77FLAGS = '-Ix')
+bar = foo.Copy(F77 = r'%(_python_)s wrapper.py ' + f77, F77FLAGS = '-Ix')
foo.Program(target = 'foo', source = 'foo.f')
bar.Program(target = 'bar', source = 'bar.f')
-""" % (FTN_LIB, python))
+""" % locals())
test.write('foo.f', r"""
PROGRAM FOO
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-env = Environment(LINK = r'%s mylink.py',
+env = Environment(LINK = r'%(_python_)s mylink.py',
LINKFLAGS = [],
- F90 = r'%s myfortran.py f90',
- FORTRAN = r'%s myfortran.py fortran')
+ F90 = r'%(_python_)s myfortran.py f90',
+ FORTRAN = r'%(_python_)s myfortran.py fortran')
env.Program(target = 'test01', source = 'test01.f')
env.Program(target = 'test02', source = 'test02.F')
env.Program(target = 'test03', source = 'test03.for')
env.Program(target = 'test12', source = 'test12.F90')
env.Program(target = 'test13', source = 'test13.f95')
env.Program(target = 'test14', source = 'test14.F95')
-""" % (python, python, python))
+""" % locals())
test.write('test01.f', "This is a .f file.\n#link\n#fortran\n")
test.write('test02.F', "This is a .F file.\n#link\n#fortran\n")
""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
test.write('SConstruct', """
-foo = Environment(LIBS = %s)
+foo = Environment(LIBS = %(FTN_LIB)s)
f90 = foo.Dictionary('F90')
-bar = foo.Copy(F90 = r'%s wrapper.py ' + f90)
+bar = foo.Copy(F90 = r'%(_python_)s wrapper.py ' + f90)
foo.Program(target = 'foo', source = 'foo.f')
bar.Program(target = 'bar', source = 'bar.f')
-""" % (FTN_LIB, python))
+""" % locals())
test.write('foo.f', r"""
PROGRAM FOO
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-env = Environment(LINK = r'%s mylink.py',
+env = Environment(LINK = r'%(_python_)s mylink.py',
LINKFLAGS = [],
- F90COM = r'%s myfortran.py f90 $TARGET $SOURCES',
- F90PPCOM = r'%s myfortran.py f90pp $TARGET $SOURCES',
- FORTRANCOM = r'%s myfortran.py fortran $TARGET $SOURCES',
- FORTRANPPCOM = r'%s myfortran.py fortranpp $TARGET $SOURCES')
+ F90COM = r'%(_python_)s myfortran.py f90 $TARGET $SOURCES',
+ F90PPCOM = r'%(_python_)s myfortran.py f90pp $TARGET $SOURCES',
+ FORTRANCOM = r'%(_python_)s myfortran.py fortran $TARGET $SOURCES',
+ FORTRANPPCOM = r'%(_python_)s myfortran.py fortranpp $TARGET $SOURCES')
env.Program(target = 'test01', source = 'test01.f')
env.Program(target = 'test02', source = 'test02.F')
env.Program(target = 'test03', source = 'test03.for')
env.Program(target = 'test12', source = 'test12.F90')
env.Program(target = 'test13', source = 'test13.f95')
env.Program(target = 'test14', source = 'test14.F95')
-env2 = Environment(LINK = r'%s mylink.py',
+env2 = Environment(LINK = r'%(_python_)s mylink.py',
LINKFLAGS = [],
- F90COM = r'%s myfortran.py f90 $TARGET $SOURCES',
- F90PPCOM = r'%s myfortran.py f90pp $TARGET $SOURCES')
+ F90COM = r'%(_python_)s myfortran.py f90 $TARGET $SOURCES',
+ F90PPCOM = r'%(_python_)s myfortran.py f90pp $TARGET $SOURCES')
env2.Program(target = 'test21', source = 'test21.f90')
env2.Program(target = 'test22', source = 'test22.F90')
-""" % (python, python, python, python, python, python, python, python))
+""" % locals())
test.write('test01.f', "This is a .f file.\n#link\n#fortran\n")
test.write('test02.F', "This is a .F file.\n#link\n#fortranpp\n")
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
-env = Environment(F90COM = r'%(python)s myfc.py f90 $TARGET $SOURCES',
+env = Environment(F90COM = r'%(_python_)s myfc.py f90 $TARGET $SOURCES',
F90COMSTR = 'Building f90 $TARGET from $SOURCES',
- F90PPCOM = r'%(python)s myfc.py f90pp $TARGET $SOURCES',
+ F90PPCOM = r'%(_python_)s myfc.py f90pp $TARGET $SOURCES',
F90PPCOMSTR = 'Building f90pp $TARGET from $SOURCES',
OBJSUFFIX='.obj')
env.Object(source = 'test01.f90')
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
_exe = TestSCons._exe
test.write('SConstruct', """
-env = Environment(LINK = r'%s mylink.py',
+env = Environment(LINK = r'%(_python_)s mylink.py',
LINKFLAGS = [],
- F90 = r'%s myfortran.py g90',
+ F90 = r'%(_python_)s myfortran.py g90',
F90FLAGS = '-x',
- FORTRAN = r'%s myfortran.py fortran',
+ FORTRAN = r'%(_python_)s myfortran.py fortran',
FORTRANFLAGS = '-y')
env.Program(target = 'test01', source = 'test01.f')
env.Program(target = 'test02', source = 'test02.F')
env.Program(target = 'test12', source = 'test12.F90')
env.Program(target = 'test13', source = 'test13.f95')
env.Program(target = 'test14', source = 'test14.F95')
-""" % (python, python, python))
+""" % locals())
test.write('test01.f', "This is a .f file.\n#link\n#fortran\n")
test.write('test02.F', "This is a .F file.\n#link\n#fortran\n")
""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
test.write('SConstruct', """
-foo = Environment(LIBS = %s)
+foo = Environment(LIBS = %(FTN_LIB)s)
f90 = foo.Dictionary('F90')
-bar = foo.Copy(F90 = r'%s wrapper.py ' + f90, F90FLAGS = '-Ix')
+bar = foo.Copy(F90 = r'%(_python_)s wrapper.py ' + f90, F90FLAGS = '-Ix')
foo.Program(target = 'foo', source = 'foo.f')
bar.Program(target = 'bar', source = 'bar.f')
-""" % (FTN_LIB, python))
+""" % locals())
test.write('foo.f', r"""
PROGRAM FOO
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-env = Environment(LINK = r'%s mylink.py',
+env = Environment(LINK = r'%(_python_)s mylink.py',
LINKFLAGS = [],
- F95 = r'%s myfortran.py f95',
- FORTRAN = r'%s myfortran.py fortran')
+ F95 = r'%(_python_)s myfortran.py f95',
+ FORTRAN = r'%(_python_)s myfortran.py fortran')
env.Program(target = 'test01', source = 'test01.f')
env.Program(target = 'test02', source = 'test02.F')
env.Program(target = 'test03', source = 'test03.for')
env.Program(target = 'test12', source = 'test12.F90')
env.Program(target = 'test13', source = 'test13.f95')
env.Program(target = 'test14', source = 'test14.F95')
-""" % (python, python, python))
+""" % locals())
test.write('test01.f', "This is a .f file.\n#link\n#fortran\n")
test.write('test02.F', "This is a .F file.\n#link\n#fortran\n")
""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
test.write('SConstruct', """
-foo = Environment(LIBS = %s)
+foo = Environment(LIBS = %(FTN_LIB)s)
f95 = foo.Dictionary('F95')
-bar = foo.Copy(F95 = r'%s wrapper.py ' + f95)
+bar = foo.Copy(F95 = r'%(_python_)s wrapper.py ' + f95)
foo.Program(target = 'foo', source = 'foo.f')
bar.Program(target = 'bar', source = 'bar.f')
-""" % (FTN_LIB, python))
+""" % locals())
test.write('foo.f', r"""
PROGRAM FOO
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-env = Environment(LINK = r'%s mylink.py',
+env = Environment(LINK = r'%(_python_)s mylink.py',
LINKFLAGS = [],
- F95COM = r'%s myfortran.py f95 $TARGET $SOURCES',
- F95PPCOM = r'%s myfortran.py f95pp $TARGET $SOURCES',
- FORTRANCOM = r'%s myfortran.py fortran $TARGET $SOURCES',
- FORTRANPPCOM = r'%s myfortran.py fortranpp $TARGET $SOURCES')
+ F95COM = r'%(_python_)s myfortran.py f95 $TARGET $SOURCES',
+ F95PPCOM = r'%(_python_)s myfortran.py f95pp $TARGET $SOURCES',
+ FORTRANCOM = r'%(_python_)s myfortran.py fortran $TARGET $SOURCES',
+ FORTRANPPCOM = r'%(_python_)s myfortran.py fortranpp $TARGET $SOURCES')
env.Program(target = 'test01', source = 'test01.f')
env.Program(target = 'test02', source = 'test02.F')
env.Program(target = 'test03', source = 'test03.for')
env.Program(target = 'test12', source = 'test12.F90')
env.Program(target = 'test13', source = 'test13.f95')
env.Program(target = 'test14', source = 'test14.F95')
-env2 = Environment(LINK = r'%s mylink.py',
+env2 = Environment(LINK = r'%(_python_)s mylink.py',
LINKFLAGS = [],
- F95COM = r'%s myfortran.py f95 $TARGET $SOURCES',
- F95PPCOM = r'%s myfortran.py f95pp $TARGET $SOURCES')
+ F95COM = r'%(_python_)s myfortran.py f95 $TARGET $SOURCES',
+ F95PPCOM = r'%(_python_)s myfortran.py f95pp $TARGET $SOURCES')
env2.Program(target = 'test21', source = 'test21.f95')
env2.Program(target = 'test22', source = 'test22.F95')
-""" % (python, python, python, python, python, python, python, python))
+""" % locals())
test.write('test01.f', "This is a .f file.\n#link\n#fortran\n")
test.write('test02.F', "This is a .F file.\n#link\n#fortranpp\n")
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
-env = Environment(F95COM = r'%(python)s myfc.py f95 $TARGET $SOURCES',
+env = Environment(F95COM = r'%(_python_)s myfc.py f95 $TARGET $SOURCES',
F95COMSTR = 'Building f95 $TARGET from $SOURCES',
- F95PPCOM = r'%(python)s myfc.py f95pp $TARGET $SOURCES',
+ F95PPCOM = r'%(_python_)s myfc.py f95pp $TARGET $SOURCES',
F95PPCOMSTR = 'Building f95pp $TARGET from $SOURCES',
OBJSUFFIX='.obj')
env.Object(source = 'test01.f95')
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
_exe = TestSCons._exe
test.write('SConstruct', """
-env = Environment(LINK = r'%s mylink.py',
+env = Environment(LINK = r'%(_python_)s mylink.py',
LINKFLAGS = [],
- F95 = r'%s myfortran.py g95',
+ F95 = r'%(_python_)s myfortran.py g95',
F95FLAGS = '-x',
- FORTRAN = r'%s myfortran.py fortran',
+ FORTRAN = r'%(_python_)s myfortran.py fortran',
FORTRANFLAGS = '-y')
env.Program(target = 'test01', source = 'test01.f')
env.Program(target = 'test02', source = 'test02.F')
env.Program(target = 'test12', source = 'test12.F90')
env.Program(target = 'test13', source = 'test13.f95')
env.Program(target = 'test14', source = 'test14.F95')
-""" % (python, python, python))
+""" % locals())
test.write('test01.f', "This is a .f file.\n#link\n#fortran\n")
test.write('test02.F', "This is a .F file.\n#link\n#fortran\n")
""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
test.write('SConstruct', """
-foo = Environment(LIBS = %s)
+foo = Environment(LIBS = %(FTN_LIB)s)
f95 = foo.Dictionary('F95')
-bar = foo.Copy(F95 = r'%s wrapper.py ' + f95, F95FLAGS = '-Ix')
+bar = foo.Copy(F95 = r'%(_python_)s wrapper.py ' + f95, F95FLAGS = '-Ix')
foo.Program(target = 'foo', source = 'foo.f')
bar.Program(target = 'bar', source = 'bar.f')
-""" % (FTN_LIB, python))
+""" % locals())
test.write('foo.f', r"""
PROGRAM FOO
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-env = Environment(LINK = r'%s mylink.py',
+env = Environment(LINK = r'%(_python_)s mylink.py',
LINKFLAGS = [],
- FORTRAN = r'%s myg77.py')
+ FORTRAN = r'%(_python_)s myg77.py')
env.Program(target = 'test01', source = 'test01.f')
env.Program(target = 'test02', source = 'test02.F')
env.Program(target = 'test03', source = 'test03.for')
env.Program(target = 'test12', source = 'test12.F90')
env.Program(target = 'test13', source = 'test13.f95')
env.Program(target = 'test14', source = 'test14.F95')
-""" % (python, python))
+""" % locals())
test.write('test01.f', "This is a .f file.\n#link\n#g77\n")
test.write('test02.F', "This is a .F file.\n#link\n#g77\n")
""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
test.write('SConstruct', """
-foo = Environment(LIBS = %s)
+foo = Environment(LIBS = %(FTN_LIB)s)
f77 = foo.Dictionary('FORTRAN')
-bar = foo.Copy(FORTRAN = r'%s wrapper.py ' + f77)
+bar = foo.Copy(FORTRAN = r'%(_python_)s wrapper.py ' + f77)
foo.Program(target = 'foo', source = 'foo.f')
bar.Program(target = 'bar', source = 'bar.f')
-""" % (FTN_LIB, python))
+""" % locals())
test.write('foo.f', r"""
PROGRAM FOO
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-env = Environment(LINK = r'%s mylink.py',
+env = Environment(LINK = r'%(_python_)s mylink.py',
LINKFLAGS = [],
- FORTRANCOM = r'%s myfortran.py fortran $TARGET $SOURCES',
- FORTRANPPCOM = r'%s myfortran.py fortranpp $TARGET $SOURCES')
+ FORTRANCOM = r'%(_python_)s myfortran.py fortran $TARGET $SOURCES',
+ FORTRANPPCOM = r'%(_python_)s myfortran.py fortranpp $TARGET $SOURCES')
env.Program(target = 'test01', source = 'test01.f')
env.Program(target = 'test02', source = 'test02.F')
env.Program(target = 'test03', source = 'test03.for')
env.Program(target = 'test12', source = 'test12.F90')
env.Program(target = 'test13', source = 'test13.f95')
env.Program(target = 'test14', source = 'test14.F95')
-""" % (python, python, python))
+""" % locals())
test.write('test01.f', "This is a .f file.\n#link\n#fortran\n")
test.write('test02.F', "This is a .F file.\n#link\n#fortranpp\n")
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
-env = Environment(FORTRANCOM = r'%(python)s myfc.py fortran $TARGET $SOURCES',
+env = Environment(FORTRANCOM = r'%(_python_)s myfc.py fortran $TARGET $SOURCES',
FORTRANCOMSTR = 'Building fortran $TARGET from $SOURCES',
- FORTRANPPCOM = r'%(python)s myfc.py fortranpp $TARGET $SOURCES',
+ FORTRANPPCOM = r'%(_python_)s myfc.py fortranpp $TARGET $SOURCES',
FORTRANPPCOMSTR = 'Building fortranpp $TARGET from $SOURCES',
OBJSUFFIX='.obj')
env.Object(source = 'test01.f')
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
_exe = TestSCons._exe
test.write('SConstruct', """
-env = Environment(LINK = r'%s mylink.py',
+env = Environment(LINK = r'%(_python_)s mylink.py',
LINKFLAGS = [],
- FORTRAN = r'%s myfortran.py',
+ FORTRAN = r'%(_python_)s myfortran.py',
FORTRANFLAGS = '-x')
env.Program(target = 'test01', source = 'test01.f')
env.Program(target = 'test02', source = 'test02.F')
env.Program(target = 'test12', source = 'test12.F90')
env.Program(target = 'test13', source = 'test13.f95')
env.Program(target = 'test14', source = 'test14.F95')
-""" % (python, python))
+""" % locals())
test.write('test01.f', "This is a .f file.\n#link\n#fortran\n")
test.write('test02.F', "This is a .F file.\n#link\n#fortran\n")
""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
test.write('SConstruct', """
-foo = Environment(LIBS = %s)
+foo = Environment(LIBS = %(FTN_LIB)s)
f77 = foo.Dictionary('FORTRAN')
-bar = foo.Copy(FORTRAN = r'%s wrapper.py ' + f77, FORTRANFLAGS = '-Ix')
+bar = foo.Copy(FORTRAN = r'%(_python_)s wrapper.py ' + f77, FORTRANFLAGS = '-Ix')
foo.Program(target = 'foo', source = 'foo.f')
bar.Program(target = 'bar', source = 'bar.f')
-""" % (FTN_LIB, python))
+""" % locals())
test.write('foo.f', r"""
PROGRAM FOO
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-env = Environment(FORTRANCOM = r'%(python)s myfortran.py $FORTRANMODDIR $SOURCE $TARGET',
+env = Environment(FORTRANCOM = r'%(_python_)s myfortran.py $FORTRANMODDIR $SOURCE $TARGET',
FORTRANMODDIR = 'modules')
env.Object(target = 'test1.obj', source = 'test1.f')
""" % locals())
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(FORTRANPATH = ['.'],
- FORTRAN = r'%s myfc.py',
+ FORTRAN = r'%(_python_)s myfc.py',
FORTRANCOM = '$FORTRAN $TARGET $SOURCES',
OBJSUFFIX = '.o')
env.Append(FORTRANSUFFIXES = ['.x'])
env.InstallAs('test1_f', 'test1.f')
env.InstallAs('test1_h', 'test1.h')
env.InstallAs('test1_x', 'test1.x')
-""" % (python,))
+""" % locals())
test.write('test1.f', """\
test1.f 1
foo.h 1
""")
-test.run(arguments='.', stdout=test.wrap_stdout("""\
-%s myfc.py test1.o test1.f
+expect = test.wrap_stdout("""\
+%(_python_)s myfc.py test1.o test1.f
Install file: "test1.f" as "test1_f"
Install file: "test1.h" as "test1_h"
Install file: "test1.x" as "test1_x"
-""" % (python,)))
+""" % locals())
+
+test.run(arguments='.', stdout=expect)
test.must_match('test1.o', """\
test1.f 1
foo.h 2
""")
-test.run(arguments='.', stdout=test.wrap_stdout("""\
-%s myfc.py test1.o test1.f
-""" % (python,)))
+expect = test.wrap_stdout("""\
+%(_python_)s myfc.py test1.o test1.f
+""" % locals())
+
+test.run(arguments='.', stdout=expect)
test.must_match('test1.o', """\
test1.f 1
INCLUDE 'foo.h'
""")
-test.run(arguments='.', stdout=test.wrap_stdout("""\
-%s myfc.py test1.o test1.f
+expect = test.wrap_stdout("""\
+%(_python_)s myfc.py test1.o test1.f
Install file: "test1.x" as "test1_x"
-""" % (python,)))
+""" % locals())
+
+test.run(arguments='.', stdout=expect)
test.must_match('test1.o', """\
test1.f 1
INCLUDE 'foo.h'
""")
-test.run(arguments='.', stdout=test.wrap_stdout("""\
-%s myfc.py test1.o test1.f
+expect = test.wrap_stdout("""\
+%(_python_)s myfc.py test1.o test1.f
Install file: "test1.h" as "test1_h"
-""" % (python,)))
+""" % locals())
+
+test.run(arguments='.', stdout=expect)
test.must_match('test1.o', """\
test1.f 1
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_obj = TestSCons._shobj
test = TestSCons.TestSCons()
test.write('SConstruct', """
-env = Environment(SHF77 = r'%s myfortran.py g77',
- SHFORTRAN = r'%s myfortran.py fortran')
+env = Environment(SHF77 = r'%(_python_)s myfortran.py g77',
+ SHFORTRAN = r'%(_python_)s myfortran.py fortran')
env.SharedObject(target = 'test01', source = 'test01.f')
env.SharedObject(target = 'test02', source = 'test02.F')
env.SharedObject(target = 'test03', source = 'test03.for')
env.SharedObject(target = 'test12', source = 'test12.F90')
env.SharedObject(target = 'test13', source = 'test13.f95')
env.SharedObject(target = 'test14', source = 'test14.F95')
-env2 = Environment(SHF77 = r'%s myfortran.py g77')
+env2 = Environment(SHF77 = r'%(_python_)s myfortran.py g77')
env2.SharedObject(target = 'test21', source = 'test21.f')
env2.SharedObject(target = 'test22', source = 'test22.F')
env2.SharedObject(target = 'test23', source = 'test23.for')
env2.SharedObject(target = 'test26', source = 'test26.FTN')
env2.SharedObject(target = 'test27', source = 'test27.fpp')
env2.SharedObject(target = 'test28', source = 'test28.FPP')
-""" % (python, python, python))
+""" % locals())
test.write('test01.f', "This is a .f file.\n#fortran\n")
test.write('test02.F', "This is a .F file.\n#fortran\n")
test.write('SConstruct', """
foo = Environment(LIBS = 'g2c')
shf77 = foo.Dictionary('SHF77')
-bar = foo.Copy(SHF77 = r'%s wrapper.py ' + shf77)
+bar = foo.Copy(SHF77 = r'%(_python_)s wrapper.py ' + shf77)
foo.SharedObject(target = 'foo/foo', source = 'foo.f')
bar.SharedObject(target = 'bar/bar', source = 'bar.f')
-""" % python)
+""" % locals())
test.write('foo.f', r"""
PROGRAM FOO
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_obj = TestSCons._shobj
test = TestSCons.TestSCons()
test.write('SConstruct', """
-env = Environment(SHF77COM = r'%s myfortran.py f77 $TARGET $SOURCES',
- SHF77PPCOM = r'%s myfortran.py f77pp $TARGET $SOURCES',
- SHFORTRANCOM = r'%s myfortran.py fortran $TARGET $SOURCES',
- SHFORTRANPPCOM = r'%s myfortran.py fortranpp $TARGET $SOURCES')
+env = Environment(SHF77COM = r'%(_python_)s myfortran.py f77 $TARGET $SOURCES',
+ SHF77PPCOM = r'%(_python_)s myfortran.py f77pp $TARGET $SOURCES',
+ SHFORTRANCOM = r'%(_python_)s myfortran.py fortran $TARGET $SOURCES',
+ SHFORTRANPPCOM = r'%(_python_)s myfortran.py fortranpp $TARGET $SOURCES')
env.SharedObject(target = 'test01', source = 'test01.f')
env.SharedObject(target = 'test02', source = 'test02.F')
env.SharedObject(target = 'test03', source = 'test03.for')
env.SharedObject(target = 'test12', source = 'test12.F90')
env.SharedObject(target = 'test13', source = 'test13.f95')
env.SharedObject(target = 'test14', source = 'test14.F95')
-env2 = Environment(SHF77COM = r'%s myfortran.py f77 $TARGET $SOURCES',
- SHF77PPCOM = r'%s myfortran.py f77pp $TARGET $SOURCES')
+env2 = Environment(SHF77COM = r'%(_python_)s myfortran.py f77 $TARGET $SOURCES',
+ SHF77PPCOM = r'%(_python_)s myfortran.py f77pp $TARGET $SOURCES')
env2.SharedObject(target = 'test21', source = 'test21.f')
env2.SharedObject(target = 'test22', source = 'test22.F')
env2.SharedObject(target = 'test23', source = 'test23.for')
env2.SharedObject(target = 'test28', source = 'test28.FPP')
env2.SharedObject(target = 'test29', source = 'test29.f77')
env2.SharedObject(target = 'test30', source = 'test30.F77')
-""" % (python, python, python, python, python, python))
+""" % locals())
test.write('test01.f', "This is a .f file.\n#fortran\n")
test.write('test02.F', "This is a .F file.\n#fortranpp\n")
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
-env = Environment(SHF77COM = r'%(python)s myfc.py f77 $TARGET $SOURCES',
+env = Environment(SHF77COM = r'%(_python_)s myfc.py f77 $TARGET $SOURCES',
SHF77COMSTR = 'Building f77 $TARGET from $SOURCES',
- SHF77PPCOM = r'%(python)s myfc.py f77pp $TARGET $SOURCES',
+ SHF77PPCOM = r'%(_python_)s myfc.py f77pp $TARGET $SOURCES',
SHF77PPCOMSTR = 'Building f77pp $TARGET from $SOURCES',
SHOBJSUFFIX='.shobj')
env.SharedObject(source = 'test01.f')
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
if sys.platform == 'win32':
_obj = '.obj'
test.write('SConstruct', """
-env = Environment(SHF77 = r'%s myg77.py',
+env = Environment(SHF77 = r'%(_python_)s myg77.py',
SHF77FLAGS = '-x')
env.SharedObject(target = 'test01', source = 'test01.f')
env.SharedObject(target = 'test02', source = 'test02.F')
env.SharedObject(target = 'test08', source = 'test08.FPP')
env.SharedObject(target = 'test09', source = 'test09.f77')
env.SharedObject(target = 'test10', source = 'test10.F77')
-""" % (python,))
+""" % locals())
test.write('test01.f', "This is a .f file.\n#g77\n")
test.write('test02.F', "This is a .F file.\n#g77\n")
""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
test.write('SConstruct', """
-foo = Environment(LIBS = %s)
+foo = Environment(LIBS = %(FTN_LIB)s)
shf77 = foo.Dictionary('SHF77')
-bar = foo.Copy(SHF77 = r'%s wrapper.py ' + shf77, SHF77FLAGS = '-Ix')
+bar = foo.Copy(SHF77 = r'%(_python_)s wrapper.py ' + shf77, SHF77FLAGS = '-Ix')
foo.SharedLibrary(target = 'foo/foo', source = 'foo.f')
bar.SharedLibrary(target = 'bar/bar', source = 'bar.f')
-""" % (FTN_LIB, python))
+""" % locals())
test.write('foo.f', r"""
PROGRAM FOO
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_obj = TestSCons._shobj
test = TestSCons.TestSCons()
test.write('SConstruct', """
-env = Environment(SHF90 = r'%s myfortran.py g90',
- SHFORTRAN = r'%s myfortran.py fortran')
+env = Environment(SHF90 = r'%(_python_)s myfortran.py g90',
+ SHFORTRAN = r'%(_python_)s myfortran.py fortran')
env.SharedObject(target = 'test01', source = 'test01.f')
env.SharedObject(target = 'test02', source = 'test02.F')
env.SharedObject(target = 'test03', source = 'test03.for')
env.SharedObject(target = 'test12', source = 'test12.F90')
env.SharedObject(target = 'test13', source = 'test13.f95')
env.SharedObject(target = 'test14', source = 'test14.F95')
-""" % (python, python))
+""" % locals())
test.write('test01.f', "This is a .f file.\n#fortran\n")
test.write('test02.F', "This is a .F file.\n#fortran\n")
test.write('SConstruct', """
foo = Environment(LIBS = 'g2c')
shf90 = foo.Dictionary('SHF90')
-bar = foo.Copy(SHF90 = r'%s wrapper.py ' + shf90)
+bar = foo.Copy(SHF90 = r'%(_python_)s wrapper.py ' + shf90)
foo.SharedObject(target = 'foo/foo', source = 'foo.f')
bar.SharedObject(target = 'bar/bar', source = 'bar.f')
-""" % python)
+""" % locals())
test.write('foo.f', r"""
PROGRAM FOO
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_obj = TestSCons._shobj
test = TestSCons.TestSCons()
test.write('SConstruct', """
-env = Environment(SHF90COM = r'%s myfortran.py f90 $TARGET $SOURCES',
- SHF90PPCOM = r'%s myfortran.py f90pp $TARGET $SOURCES',
- SHFORTRANCOM = r'%s myfortran.py fortran $TARGET $SOURCES',
- SHFORTRANPPCOM = r'%s myfortran.py fortranpp $TARGET $SOURCES')
+env = Environment(SHF90COM = r'%(_python_)s myfortran.py f90 $TARGET $SOURCES',
+ SHF90PPCOM = r'%(_python_)s myfortran.py f90pp $TARGET $SOURCES',
+ SHFORTRANCOM = r'%(_python_)s myfortran.py fortran $TARGET $SOURCES',
+ SHFORTRANPPCOM = r'%(_python_)s myfortran.py fortranpp $TARGET $SOURCES')
env.SharedObject(target = 'test01', source = 'test01.f')
env.SharedObject(target = 'test02', source = 'test02.F')
env.SharedObject(target = 'test03', source = 'test03.for')
env.SharedObject(target = 'test12', source = 'test12.F90')
env.SharedObject(target = 'test13', source = 'test13.f95')
env.SharedObject(target = 'test14', source = 'test14.F95')
-env2 = Environment(SHF90COM = r'%s myfortran.py f90 $TARGET $SOURCES',
- SHF90PPCOM = r'%s myfortran.py f90pp $TARGET $SOURCES')
+env2 = Environment(SHF90COM = r'%(_python_)s myfortran.py f90 $TARGET $SOURCES',
+ SHF90PPCOM = r'%(_python_)s myfortran.py f90pp $TARGET $SOURCES')
env2.SharedObject(target = 'test21', source = 'test21.f90')
env2.SharedObject(target = 'test22', source = 'test22.F90')
-""" % (python, python, python, python, python, python))
+""" % locals())
test.write('test01.f', "This is a .f file.\n#fortran\n")
test.write('test02.F', "This is a .F file.\n#fortranpp\n")
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
-env = Environment(SHF90COM = r'%(python)s myfc.py f90 $TARGET $SOURCES',
+env = Environment(SHF90COM = r'%(_python_)s myfc.py f90 $TARGET $SOURCES',
SHF90COMSTR = 'Building f90 $TARGET from $SOURCES',
- SHF90PPCOM = r'%(python)s myfc.py f90pp $TARGET $SOURCES',
+ SHF90PPCOM = r'%(_python_)s myfc.py f90pp $TARGET $SOURCES',
SHF90PPCOMSTR = 'Building f90pp $TARGET from $SOURCES',
SHOBJSUFFIX='.shobj')
env.SharedObject(source = 'test01.f90')
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
if sys.platform == 'win32':
_obj = '.obj'
test.write('SConstruct', """
-env = Environment(SHF90 = r'%s myfortran.py g90',
+env = Environment(SHF90 = r'%(_python_)s myfortran.py g90',
SHF90FLAGS = '-x',
- SHFORTRAN = r'%s myfortran.py fortran',
+ SHFORTRAN = r'%(_python_)s myfortran.py fortran',
SHFORTRANFLAGS = '-y')
env.SharedObject(target = 'test01', source = 'test01.f')
env.SharedObject(target = 'test02', source = 'test02.F')
env.SharedObject(target = 'test12', source = 'test12.F90')
env.SharedObject(target = 'test13', source = 'test13.f95')
env.SharedObject(target = 'test14', source = 'test14.F95')
-""" % (python, python))
+""" % locals())
test.write('test01.f', "This is a .f file.\n#fortran\n")
test.write('test02.F', "This is a .F file.\n#fortran\n")
""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
test.write('SConstruct', """
-foo = Environment(LIBS = %s)
+foo = Environment(LIBS = %(FTN_LIB)s)
shf90 = foo.Dictionary('SHF90')
-bar = foo.Copy(SHF90 = r'%s wrapper.py ' + shf90, SHF90FLAGS = '-Ix')
+bar = foo.Copy(SHF90 = r'%(_python_)s wrapper.py ' + shf90, SHF90FLAGS = '-Ix')
foo.SharedLibrary(target = 'foo/foo', source = 'foo.f')
bar.SharedLibrary(target = 'bar/bar', source = 'bar.f')
-""" % (FTN_LIB, python))
+""" % locals())
test.write('foo.f', r"""
PROGRAM FOO
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_obj = TestSCons._shobj
test = TestSCons.TestSCons()
test.write('SConstruct', """
-env = Environment(SHF95 = r'%s myfortran.py g95',
- SHFORTRAN = r'%s myfortran.py fortran')
+env = Environment(SHF95 = r'%(_python_)s myfortran.py g95',
+ SHFORTRAN = r'%(_python_)s myfortran.py fortran')
env.SharedObject(target = 'test01', source = 'test01.f')
env.SharedObject(target = 'test02', source = 'test02.F')
env.SharedObject(target = 'test03', source = 'test03.for')
env.SharedObject(target = 'test12', source = 'test12.F90')
env.SharedObject(target = 'test13', source = 'test13.f95')
env.SharedObject(target = 'test14', source = 'test14.F95')
-""" % (python, python))
+""" % locals())
test.write('test01.f', "This is a .f file.\n#fortran\n")
test.write('test02.F', "This is a .F file.\n#fortran\n")
test.write('SConstruct', """
foo = Environment(LIBS = 'g2c')
shf95 = foo.Dictionary('SHF95')
-bar = foo.Copy(SHF95 = r'%s wrapper.py ' + shf95)
+bar = foo.Copy(SHF95 = r'%(_python_)s wrapper.py ' + shf95)
foo.SharedObject(target = 'foo/foo', source = 'foo.f')
bar.SharedObject(target = 'bar/bar', source = 'bar.f')
-""" % python)
+""" % locals())
test.write('foo.f', r"""
PROGRAM FOO
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_obj = TestSCons._shobj
test = TestSCons.TestSCons()
test.write('SConstruct', """
-env = Environment(SHF95COM = r'%s myfortran.py f95 $TARGET $SOURCES',
- SHF95PPCOM = r'%s myfortran.py f95pp $TARGET $SOURCES',
- SHFORTRANCOM = r'%s myfortran.py fortran $TARGET $SOURCES',
- SHFORTRANPPCOM = r'%s myfortran.py fortranpp $TARGET $SOURCES')
+env = Environment(SHF95COM = r'%(_python_)s myfortran.py f95 $TARGET $SOURCES',
+ SHF95PPCOM = r'%(_python_)s myfortran.py f95pp $TARGET $SOURCES',
+ SHFORTRANCOM = r'%(_python_)s myfortran.py fortran $TARGET $SOURCES',
+ SHFORTRANPPCOM = r'%(_python_)s myfortran.py fortranpp $TARGET $SOURCES')
env.SharedObject(target = 'test01', source = 'test01.f')
env.SharedObject(target = 'test02', source = 'test02.F')
env.SharedObject(target = 'test03', source = 'test03.for')
env.SharedObject(target = 'test12', source = 'test12.F90')
env.SharedObject(target = 'test13', source = 'test13.f95')
env.SharedObject(target = 'test14', source = 'test14.F95')
-env2 = Environment(SHF95COM = r'%s myfortran.py f95 $TARGET $SOURCES',
- SHF95PPCOM = r'%s myfortran.py f95pp $TARGET $SOURCES')
+env2 = Environment(SHF95COM = r'%(_python_)s myfortran.py f95 $TARGET $SOURCES',
+ SHF95PPCOM = r'%(_python_)s myfortran.py f95pp $TARGET $SOURCES')
env2.SharedObject(target = 'test21', source = 'test21.f95')
env2.SharedObject(target = 'test22', source = 'test22.F95')
-""" % (python, python, python, python, python, python))
+""" % locals())
test.write('test01.f', "This is a .f file.\n#fortran\n")
test.write('test02.F', "This is a .F file.\n#fortranpp\n")
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
-env = Environment(SHF95COM = r'%(python)s myfc.py f95 $TARGET $SOURCES',
+env = Environment(SHF95COM = r'%(_python_)s myfc.py f95 $TARGET $SOURCES',
SHF95COMSTR = 'Building f95 $TARGET from $SOURCES',
- SHF95PPCOM = r'%(python)s myfc.py f95pp $TARGET $SOURCES',
+ SHF95PPCOM = r'%(_python_)s myfc.py f95pp $TARGET $SOURCES',
SHF95PPCOMSTR = 'Building f95pp $TARGET from $SOURCES',
SHOBJSUFFIX='.shobj')
env.SharedObject(source = 'test01.f95')
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
if sys.platform == 'win32':
_obj = '.obj'
test.write('SConstruct', """
-env = Environment(SHF95 = r'%s myfortran.py g95',
+env = Environment(SHF95 = r'%(_python_)s myfortran.py g95',
SHF95FLAGS = '-x',
- SHFORTRAN = r'%s myfortran.py fortran',
+ SHFORTRAN = r'%(_python_)s myfortran.py fortran',
SHFORTRANFLAGS = '-y')
env.SharedObject(target = 'test01', source = 'test01.f')
env.SharedObject(target = 'test02', source = 'test02.F')
env.SharedObject(target = 'test12', source = 'test12.F90')
env.SharedObject(target = 'test13', source = 'test13.f95')
env.SharedObject(target = 'test14', source = 'test14.F95')
-""" % (python, python))
+""" % locals())
test.write('test01.f', "This is a .f file.\n#fortran\n")
test.write('test02.F', "This is a .F file.\n#fortran\n")
""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
test.write('SConstruct', """
-foo = Environment(LIBS = %s)
+foo = Environment(LIBS = %(FTN_LIB)s)
shf95 = foo.Dictionary('SHF95')
-bar = foo.Copy(SHF95 = r'%s wrapper.py ' + shf95, SHF95FLAGS = '-Ix')
+bar = foo.Copy(SHF95 = r'%(_python_)s wrapper.py ' + shf95, SHF95FLAGS = '-Ix')
foo.SharedLibrary(target = 'foo/foo', source = 'foo.f')
bar.SharedLibrary(target = 'bar/bar', source = 'bar.f')
-""" % (FTN_LIB, python))
+""" % locals())
test.write('foo.f', r"""
PROGRAM FOO
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_obj = TestSCons._shobj
test = TestSCons.TestSCons()
test.write('SConstruct', """
-env = Environment(SHFORTRAN = r'%s myfortran.py')
+env = Environment(SHFORTRAN = r'%(_python_)s myfortran.py')
env.SharedObject(target = 'test01', source = 'test01.f')
env.SharedObject(target = 'test02', source = 'test02.F')
env.SharedObject(target = 'test03', source = 'test03.for')
env.SharedObject(target = 'test12', source = 'test12.F90')
env.SharedObject(target = 'test13', source = 'test13.f95')
env.SharedObject(target = 'test14', source = 'test14.F95')
-""" % python)
+""" % locals())
test.write('test01.f', "This is a .f file.\n#fortran\n")
test.write('test02.F', "This is a .F file.\n#fortran\n")
test.write('SConstruct', """
foo = Environment(LIBS = 'g2c')
shfortran = foo.Dictionary('SHFORTRAN')
-bar = foo.Copy(SHFORTRAN = r'%s wrapper.py ' + shfortran)
+bar = foo.Copy(SHFORTRAN = r'%(_python_)s wrapper.py ' + shfortran)
foo.SharedObject(target = 'foo/foo', source = 'foo.f')
bar.SharedObject(target = 'bar/bar', source = 'bar.f')
-""" % python)
+""" % locals())
test.write('foo.f', r"""
PROGRAM FOO
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_obj = TestSCons._shobj
test = TestSCons.TestSCons()
test.write('SConstruct', """
-env = Environment(SHFORTRANCOM = r'%s myfortran.py fortran $TARGET $SOURCES',
- SHFORTRANPPCOM = r'%s myfortran.py fortranpp $TARGET $SOURCES')
+env = Environment(SHFORTRANCOM = r'%(_python_)s myfortran.py fortran $TARGET $SOURCES',
+ SHFORTRANPPCOM = r'%(_python_)s myfortran.py fortranpp $TARGET $SOURCES')
env.SharedObject(target = 'test01', source = 'test01.f')
env.SharedObject(target = 'test02', source = 'test02.F')
env.SharedObject(target = 'test03', source = 'test03.for')
env.SharedObject(target = 'test12', source = 'test12.F90')
env.SharedObject(target = 'test13', source = 'test13.f95')
env.SharedObject(target = 'test14', source = 'test14.F95')
-""" % (python, python))
+""" % locals())
test.write('test01.f', "This is a .f file.\n#fortran\n")
test.write('test02.F', "This is a .F file.\n#fortranpp\n")
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
-env = Environment(SHFORTRANCOM = r'%(python)s myfc.py fortran $TARGET $SOURCES',
+env = Environment(SHFORTRANCOM = r'%(_python_)s myfc.py fortran $TARGET $SOURCES',
SHFORTRANCOMSTR = 'Building fortran $TARGET from $SOURCES',
- SHFORTRANPPCOM = r'%(python)s myfc.py fortranpp $TARGET $SOURCES',
+ SHFORTRANPPCOM = r'%(_python_)s myfc.py fortranpp $TARGET $SOURCES',
SHFORTRANPPCOMSTR = 'Building fortranpp $TARGET from $SOURCES',
SHOBJSUFFIX='.shobj')
env.SharedObject(source = 'test01.f')
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
if sys.platform == 'win32':
_obj = '.obj'
test.write('SConstruct', """
-env = Environment(SHFORTRAN = r'%s myfortran.py',
+env = Environment(SHFORTRAN = r'%(_python_)s myfortran.py',
SHFORTRANFLAGS = '-x')
env.SharedObject(target = 'test01', source = 'test01.f')
env.SharedObject(target = 'test02', source = 'test02.F')
env.SharedObject(target = 'test12', source = 'test12.F90')
env.SharedObject(target = 'test13', source = 'test13.f95')
env.SharedObject(target = 'test14', source = 'test14.F95')
-""" % (python,))
+""" % locals())
test.write('test01.f', "This is a .f file.\n#fortran\n")
test.write('test02.F', "This is a .F file.\n#fortran\n")
""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
test.write('SConstruct', """
-foo = Environment(LIBS = %s)
+foo = Environment(LIBS = %(FTN_LIB)s)
shfortran = foo.Dictionary('SHFORTRAN')
-bar = foo.Copy(SHFORTRAN = r'%s wrapper.py ' + shfortran,
+bar = foo.Copy(SHFORTRAN = r'%(_python_)s wrapper.py ' + shfortran,
SHFORTRANFLAGS = '-Ix')
foo.SharedLibrary(target = 'foo/foo', source = 'foo.f')
bar.SharedLibrary(target = 'bar/bar', source = 'bar.f')
-""" % (FTN_LIB, python))
+""" % locals())
test.write('foo.f', r"""
PROGRAM FOO
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-env = Environment(FORTRANCOM = r'%(python)s myfortran.py $SOURCE $TARGET')
+env = Environment(FORTRANCOM = r'%(_python_)s myfortran.py $SOURCE $TARGET')
env.Object(target = 'test1.obj', source = 'test1.f')
""" % locals())
--- /dev/null
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Validate that $FORTRANMODDIR values get expanded correctly on Fortran
+command lines relative to the appropriate subdirectory.
+"""
+
+import os.path
+
+import TestSCons
+
+_python_ = TestSCons._python_
+
+test = TestSCons.TestSCons()
+
+test.subdir('subdir',
+ ['subdir', 'src'],
+ ['subdir', 'build'])
+
+test.write('myfortran.py', r"""
+import getopt
+import os
+import sys
+comment = '#' + sys.argv[1]
+length = len(comment)
+opts, args = getopt.getopt(sys.argv[2:], 'cM:o:')
+for opt, arg in opts:
+ if opt == '-o': out = arg
+ elif opt == '-M': modsubdir = arg
+import os
+infile = open(args[0], 'rb')
+outfile = open(out, 'wb')
+for l in infile.readlines():
+ if l[:7] == 'module ':
+ module = modsubdir + os.sep + l[7:-1] + '.mod'
+ open(module, 'wb').write('myfortran.py wrote %s\n' % module)
+ if l[:length] != comment:
+ outfile.write(l)
+sys.exit(0)
+""")
+
+test.write('myar.py', """\
+import sys
+t = open(sys.argv[1], 'wb')
+for s in sys.argv[2:]:
+ t.write(open(s, 'rb').read())
+t.close
+sys.exit(0)
+""")
+
+test.write('SConstruct', """\
+env = Environment(FORTRANMODDIRPREFIX = '-M',
+ FORTRANMODDIR = 'modules',
+ F90 = r'%(_python_)s myfortran.py f90',
+ FORTRAN = r'%(_python_)s myfortran.py fortran',
+ AR = 'myar.py',
+ ARCOM = r'%(_python_)s $AR $TARGET $SOURCES',
+ RANLIBCOM = '')
+Export('env')
+objs = SConscript('subdir/SConscript')
+env.Library('bidule', objs)
+""" % locals())
+
+test.write(['subdir', 'SConscript'], """\
+Import('env')
+
+env['FORTRANMODDIR'] = 'build'
+sources = ['src/modfile.f90']
+objs = env.Object(sources)
+Return("objs")
+""")
+
+test.write(['subdir', 'src', 'modfile.f90'], """\
+#f90 comment
+module somemodule
+
+integer :: nothing
+
+end module
+""")
+
+
+test.run(arguments = '.')
+
+somemodule = os.path.join('subdir', 'build', 'somemodule.mod')
+
+expect = "myfortran.py wrote %s\n" % somemodule
+
+test.must_match(['subdir', 'build', 'somemodule.mod'], expect)
+
+test.pass_test()
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-env = Environment(GS = r'%s mygs.py',
+env = Environment(GS = r'%(_python_)s mygs.py',
GSCOM = r'$GS $TARGET $SOURCE',
tools=['gs'])
env.PDF(target = 'test1.pdf', source = 'test1.ps')
-""" % (python))
+""" % locals())
test.write('test1.ps', r"""This is a .ps test.
#ps
foo = Environment(ENV = { 'PATH' : os.environ['PATH'] })
gs = foo.Dictionary('GS')
bar = Environment(ENV = { 'PATH' : os.environ['PATH'] },
- GS = r'%s wrapper.py ' + gs)
+ GS = r'%(_python_)s wrapper.py ' + gs)
foo.PDF(target = 'foo.pdf', source = 'foo.ps')
bar.PDF(target = 'bar.pdf', source = 'bar.ps')
-""" % python)
+""" % locals())
input = """\
%!PS-Adobe
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(tools=['default', 'gs'],
- GSCOM = r'%s mygs.py $TARGET $SOURCES')
+ GSCOM = r'%(_python_)s mygs.py $TARGET $SOURCES')
env.PDF(target = 'aaa', source = 'aaa.ps')
-""" % python)
+""" % locals())
test.write('aaa.ps', "aaa.ps\n/*gs*/\n")
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(tools=['default', 'gs'],
- GSCOM = r'%s mygs.py $TARGET $SOURCES',
+ GSCOM = r'%(_python_)s mygs.py $TARGET $SOURCES',
GSCOMSTR = 'GSing $TARGET from $SOURCE')
env.PDF(target = 'aaa', source = 'aaa.ps')
-""" % python)
+""" % locals())
test.write('aaa.ps', "aaa.ps\n/*gs*/\n")
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-env = Environment(GS = r'%s mygs.py', GSFLAGS = '-x',
+env = Environment(GS = r'%(_python_)s mygs.py', GSFLAGS = '-x',
tools = ['gs'])
env.PDF(target = 'test1.pdf', source = 'test1.ps')
-""" % (python))
+""" % locals())
test.write('test1.ps', """\
This is a .ps test.
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(tools=['default', 'midl'],
- MIDLCOM = r'%s mymidl.py $TARGET $SOURCES')
+ MIDLCOM = r'%(_python_)s mymidl.py $TARGET $SOURCES')
env.TypeLibrary(target = 'aaa', source = 'aaa.idl')
-""" % python)
+""" % locals())
test.write('aaa.idl', "aaa.idl\n/*midl*/\n")
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(tools=['default', 'midl'],
- MIDLCOM = r'%s mymidl.py $TARGET $SOURCES',
+ MIDLCOM = r'%(_python_)s mymidl.py $TARGET $SOURCES',
MIDLCOMSTR = 'MIDLing $TARGET from $SOURCE')
env.TypeLibrary(target = 'aaa', source = 'aaa.idl')
-""" % python)
+""" % locals())
test.write('aaa.idl', "aaa.idl\n/*midl*/\n")
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
file.close()
""")
+SUBDIR_f3_out = os.path.join('$SUBDIR', 'f3.out')
+SUBDIR_f3b_in = os.path.join('$SUBDIR', 'f3b.in')
+
test.write('SConstruct', """\
-Foo = Builder(action = r"%s build.py $TARGET $SOURCES")
-Bar = Builder(action = r"%s build.py $TARGET $SOURCES")
+Foo = Builder(action = r'%(_python_)s build.py $TARGET $SOURCES')
+Bar = Builder(action = r'%(_python_)s build.py $TARGET $SOURCES')
env = Environment(BUILDERS = { 'Foo' : Foo, 'Bar' : Bar }, SUBDIR='subdir')
env.Foo(target = 'f1.out', source = ['f1a.in', 'f1b.in'])
Ignore(target = 'f1.out', dependency = 'f1b.in')
SConscript('subdir/SConscript', "env")
env.Foo(target = 'subdir/f3.out', source = ['subdir/f3a.in', 'subdir/f3b.in'])
-env.Ignore(target = r'%s', dependency = r'%s')
-""" % (python,
- python,
- os.path.join('$SUBDIR', 'f3.out'),
- os.path.join('$SUBDIR', 'f3b.in')))
+env.Ignore(target = r'%(SUBDIR_f3_out)s', dependency = r'%(SUBDIR_f3b_in)s')
+""" % locals())
test.write(['subdir', 'SConscript'], """
Import("env")
f6_txt = test.workpath('outside', 'f6.txt')
f6_sep = string.replace(f6_txt, os.sep, '/')
+_SUBDIR_f4_out = os.path.join('$SUBDIR', 'f4.out')
+
test.write(['work', 'SConstruct'], """\
def cat(env, source, target):
target = str(target[0])
env4 = env1.Copy(EXPORT='export', SUBDIR='sub')
t = env4.Cat(target='sub/f4.out', source='sub/f4.in')
-env4.Install(dir='$EXPORT', source=r'%s')
-
-env1.Install('.', r'%s')
-env1.Install('export', r'%s')
-env1.Install('.', r'%s')
-env1.Install('export', r'%s')
-""" % (os.path.join('$SUBDIR', 'f4.out'),
- f5_txt, f5_txt,
- f6_sep, f6_sep))
+env4.Install(dir='$EXPORT', source=r'%(_SUBDIR_f4_out)s')
+
+env1.Install('.', r'%(f5_txt)s')
+env1.Install('export', r'%(f5_txt)s')
+env1.Install('.', r'%(f6_sep)s')
+env1.Install('export', r'%(f6_sep)s')
+""" % locals())
test.write(['work', 'f1.in'], "f1.in\n")
test.write(['work', 'f2.in'], "f2.in\n")
install_file2_out = test.workpath('install', 'file2.out')
install_file3_out = test.workpath('install', 'file3.out')
+_INSTALLDIR_file2_out = os.path.join('$INSTALLDIR', 'file2.out')
+_SUBDIR_file3_in = os.path.join('$SUBDIR', 'file3.in')
+
#
test.write('SConstruct', r"""
-env = Environment(INSTALLDIR=r'%s', SUBDIR='subdir')
-InstallAs(r'%s', 'file1.in')
-env.InstallAs([r'%s', r'%s'], ['file2.in', r'%s'])
-""" % (install,
- install_file1_out,
- os.path.join('$INSTALLDIR', 'file2.out'),
- install_file3_out,
- os.path.join('$SUBDIR', 'file3.in')))
+env = Environment(INSTALLDIR=r'%(install)s', SUBDIR='subdir')
+InstallAs(r'%(install_file1_out)s', 'file1.in')
+env.InstallAs([r'%(_INSTALLDIR_file2_out)s', r'%(install_file3_out)s'],
+ ['file2.in', r'%(_SUBDIR_file3_in)s'])
+""" % locals())
test.write('file1.in', "file1.in\n")
test.write('file2.in', "file2.in\n")
--- /dev/null
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Test using Install() on directories.
+"""
+
+import os.path
+import string
+import sys
+import time
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+test.subdir('outside',
+ 'work',
+ ['work', 'dir1'],
+ ['work', 'dir1', 'sub'],
+ ['work', 'dir2'],
+ ['work', 'dir2', 'sub'],
+ ['work', 'dir3'],
+ ['work', 'dir3', 'sub'],
+ ['work', 'dir4'],
+ ['work', 'dir4', 'sub'])
+
+test.write(['work', 'SConstruct'], """\
+Install('../outside', 'dir1')
+InstallAs('../outside/d2', 'dir2')
+
+env = Environment()
+env.Install('../outside', 'dir3')
+env.InstallAs('../outside/d4', 'dir4')
+""")
+
+test.write(['work', 'f1'], "work/f1\n")
+test.write(['work', 'dir1', 'f2'], "work/dir1/f2\n")
+test.write(['work', 'dir1', 'sub', 'f3'], "work/dir1/sub/f3\n")
+test.write(['work', 'dir2', 'f4'], "work/dir2/f4\n")
+test.write(['work', 'dir2', 'sub', 'f5'], "work/dir2/sub/f5\n")
+test.write(['work', 'dir3', 'f6'], "work/dir3/f6\n")
+test.write(['work', 'dir3', 'sub', 'f7'], "work/dir3/sub/f7\n")
+test.write(['work', 'dir4', 'f8'], "work/dir4/f8\n")
+test.write(['work', 'dir4', 'sub', 'f9'], "work/dir4/sub/f9\n")
+
+
+arguments = [
+ test.workpath('outside', 'dir1'),
+ test.workpath('outside', 'd2'),
+ test.workpath('outside', 'dir3'),
+ test.workpath('outside', 'd4'),
+]
+
+expect = test.wrap_stdout("""
+Install directory: "dir1" as "%s"
+Install directory: "dir2" as "%s"
+Install directory: "dir3" as "%s"
+Install directory: "dir4" as "%s"
+""" % tuple(arguments))
+
+test.run(chdir = 'work', arguments = arguments)
+
+test.must_match(test.workpath('outside', 'dir1', 'f2'), "work/dir1/f2\n")
+test.must_match(test.workpath('outside', 'dir1', 'sub', 'f3'), "work/dir1/sub/f3\n")
+test.must_match(test.workpath('outside', 'd2', 'f4'), "work/dir2/f4\n")
+test.must_match(test.workpath('outside', 'd2', 'sub', 'f5'), "work/dir2/sub/f5\n")
+test.must_match(test.workpath('outside', 'dir3', 'f6'), "work/dir3/f6\n")
+test.must_match(test.workpath('outside', 'dir3', 'sub', 'f7'), "work/dir3/sub/f7\n")
+test.must_match(test.workpath('outside', 'd4', 'f8'), "work/dir4/f8\n")
+test.must_match(test.workpath('outside', 'd4', 'sub', 'f9'), "work/dir4/sub/f9\n")
+
+test.pass_test()
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(tools = ['jar'],
- JAR = r'%s myjar.py')
+ JAR = r'%(_python_)s myjar.py')
env.Jar(target = 'test1.jar', source = 'test1.class')
-""" % (python))
+""" % locals())
test.write('test1.class', """\
test1.class
test.write('SConstruct', """
env = Environment(tools = ['jar'],
- JAR = r'%s myjar.py')
+ JAR = r'%(_python_)s myjar.py')
env.Jar(target = 'test2.jar', source = 'test2.CLASS')
-""" % (python))
+""" % locals())
test.write('test2.CLASS', """\
test2.CLASS
test.write('SConstruct', """
env = Environment(tools = ['jar'],
- JAR = r'%s myjar2.py',
+ JAR = r'%(_python_)s myjar2.py',
JARFLAGS='cvf')
env.Jar(target = 'classes.jar', source = [ 'testdir/bar.class',
'foo.mf' ],
TESTDIR='testdir',
JARCHDIR='$TESTDIR')
-""" % (python))
+""" % locals())
test.subdir('testdir')
test.write([ 'testdir', 'bar.class' ], 'foo')
JAVAC = r'%(where_javac)s',
JAR = r'%(where_jar)s')
jar = foo.Dictionary('JAR')
-bar = foo.Copy(JAR = r'%(python)s wrapper.py ' + jar)
+bar = foo.Copy(JAR = r'%(_python_)s wrapper.py ' + jar)
foo.Java(target = 'classes', source = 'com/sub/foo')
bar.Java(target = 'classes', source = 'com/sub/bar')
foo.Jar(target = 'foo', source = 'classes/com/sub/foo')
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(TOOLS = ['default', 'jar'],
- JARCOM = r'%(python)s myjar.py $TARGET $SOURCES')
+ JARCOM = r'%(_python_)s myjar.py $TARGET $SOURCES')
env.Jar(target = 'test1', source = ['file1.in', 'file2.in', 'file3.in'])
""" % locals())
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(TOOLS = ['default', 'jar'],
- JARCOM = r'%(python)s myjar.py $TARGET $SOURCES',
+ JARCOM = r'%(_python_)s myjar.py $TARGET $SOURCES',
JARCOMSTR = "Jar'ing up $TARGET from $SOURCES")
env.Jar(target = 'test1', source = ['file1.in', 'file2.in', 'file3.in'])
""" % locals())
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(tools = ['javac'],
- JAVAC = r'%s myjavac.py')
+ JAVAC = r'%(_python_)s myjavac.py')
env.Java(target = '.', source = '.')
-""" % (python))
+""" % locals())
test.write('test1.java', """\
test1.java
test.write('SConstruct', """\
env = Environment(tools = ['javac'],
- JAVAC = r'%s myjavac.py')
+ JAVAC = r'%(_python_)s myjavac.py')
env.Java(target = '.', source = '.')
-""" % python)
+""" % locals())
test.write('test2.JAVA', """\
test2.JAVA
test.write('SConstruct', """
foo = Environment(tools = ['javac'],
- JAVAC = r'%s')
+ JAVAC = r'%(where_javac)s')
javac = foo.Dictionary('JAVAC')
-bar = foo.Copy(JAVAC = r'%s wrapper.py ' + javac)
+bar = foo.Copy(JAVAC = r'%(_python_)s wrapper.py ' + javac)
foo.Java(target = 'class1', source = 'com/sub/foo')
bar.Java(target = 'class2', source = 'com/sub/bar')
foo.Java(target = 'class3', source = ['src1', 'src2'])
-""" % (where_javac, python))
+""" % locals())
test.subdir('com',
['com', 'sub'],
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(TOOLS = ['default', 'javac'],
- JAVACCOM = r'%(python)s myjavac.py $TARGET $SOURCES')
+ JAVACCOM = r'%(_python_)s myjavac.py $TARGET $SOURCES')
env.Java(target = 'classes', source = 'src')
""" % locals())
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(TOOLS = ['default', 'javac'],
- JAVACCOM = r'%(python)s myjavac.py $TARGET $SOURCES',
+ JAVACCOM = r'%(_python_)s myjavac.py $TARGET $SOURCES',
JAVACCOMSTR = "Compiling class(es) $TARGET from $SOURCES")
env.Java(target = 'classes', source = 'src')
""" % locals())
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(tools = ['javah'],
- JAVAH = r'%s myjavah.py')
+ JAVAH = r'%(_python_)s myjavah.py')
env.JavaH(target = File('test1.h'), source = 'test1.java')
-""" % (python))
+""" % locals())
test.write('test1.java', """\
test1.java
test.write('SConstruct', """\
env = Environment(tools = ['javah'],
- JAVAH = r'%s myjavah.py')
+ JAVAH = r'%(_python_)s myjavah.py')
env.JavaH(target = File('test2.h'), source = 'test2.JAVA')
-""" % python)
+""" % locals())
test.write('test2.JAVA', """\
test2.JAVA
JAVAC = r'%(where_javac)s',
JAVAH = r'%(where_javah)s')
javah = foo.Dictionary('JAVAH')
-bar = foo.Copy(JAVAH = r'%(python)s wrapper.py ' + javah)
+bar = foo.Copy(JAVAH = r'%(_python_)s wrapper.py ' + javah)
foo.Java(target = 'class1', source = 'com/sub/foo')
bar_classes = bar.Java(target = 'class2', source = 'com/sub/bar')
foo_classes = foo.Java(target = 'class3', source = 'src')
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(TOOLS = ['default', 'javah'],
- JAVAHCOM = r'%(python)s myjavah.py $TARGET $SOURCES')
+ JAVAHCOM = r'%(_python_)s myjavah.py $TARGET $SOURCES')
env.JavaH(target = 'out', source = 'file1.class')
env.JavaH(target = 'out', source = 'file2.class')
env.JavaH(target = 'out', source = 'file3.class')
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(TOOLS = ['default', 'javah'],
- JAVAHCOM = r'%(python)s myjavah.py $TARGET $SOURCES',
+ JAVAHCOM = r'%(_python_)s myjavah.py $TARGET $SOURCES',
JAVAHCOMSTR = 'Building javah $TARGET from $SOURCES')
env.JavaH(target = 'out', source = 'file1.class')
env.JavaH(target = 'out', source = 'file2.class')
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(tools = ['rmic'],
- RMIC = r'%s myrmic.py')
+ RMIC = r'%(_python_)s myrmic.py')
env.RMIC(target = 'outdir', source = 'test1.java')
-""" % (python))
+""" % locals())
test.write('test1.java', """\
test1.java
test.write('SConstruct', """\
env = Environment(tools = ['rmic'],
- RMIC = r'%s myrmic.py')
+ RMIC = r'%(_python_)s myrmic.py')
env.RMIC(target = 'outdir', source = 'test2.JAVA')
-""" % python)
+""" % locals())
test.write('test2.JAVA', """\
test2.JAVA
JAVACLASSDIR = 'class1')
rmic = foo.Dictionary('RMIC')
-bar = foo.Copy(RMIC = r'%(python)s wrapper.py ' + rmic)
+bar = foo.Copy(RMIC = r'%(_python_)s wrapper.py ' + rmic)
bar_classes = bar.Java(target = 'class2', source = 'com/sub/bar')
# XXX This is kind of a Python brute-force way to do what Ant
# does with its "excludes" attribute. We should probably find
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(TOOLS = ['default', 'rmic'],
- RMICCOM = r'%(python)s myrmic.py $TARGET $SOURCES')
+ RMICCOM = r'%(_python_)s myrmic.py $TARGET $SOURCES')
env.RMIC(target = 'out', source = 'file1.class')
env.RMIC(target = 'out', source = 'file2.class')
env.RMIC(target = 'out', source = 'file3.class')
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(TOOLS = ['default', 'rmic'],
- RMICCOM = r'%(python)s myrmic.py $TARGET $SOURCES',
+ RMICCOM = r'%(_python_)s myrmic.py $TARGET $SOURCES',
RMICCOMSTR = 'Building rmic $TARGET from $SOURCES')
env.RMIC(target = 'out', source = 'file1.class')
env.RMIC(target = 'out', source = 'file2.class')
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-env = Environment(LEX = r'%s mylex.py', tools=['default', 'lex'])
+env = Environment(LEX = r'%(_python_)s mylex.py', tools=['default', 'lex'])
env.Program(target = 'aaa', source = 'aaa.l')
env.Program(target = 'bbb', source = 'bbb.lex')
-""" % python)
+""" % locals())
test.write('aaa.l', r"""
int
test.write('SConstruct', """
foo = Environment()
lex = foo.Dictionary('LEX')
-bar = Environment(LEX = r'%s wrapper.py ' + lex)
+bar = Environment(LEX = r'%(_python_)s wrapper.py ' + lex)
foo.Program(target = 'foo', source = 'foo.l')
bar.Program(target = 'bar', source = 'bar.l')
-""" % python)
+""" % locals())
lex = r"""
%%%%
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(tools=['default', 'lex'],
- LEXCOM = r'%s mylex.py $TARGET $SOURCES')
+ LEXCOM = r'%(_python_)s mylex.py $TARGET $SOURCES')
env.CFile(target = 'aaa', source = 'aaa.l')
env.CFile(target = 'bbb', source = 'bbb.lex')
-""" % python)
+""" % locals())
test.write('aaa.l', "aaa.l\n/*lex*/\n")
test.write('bbb.lex', "bbb.lex\n/*lex*/\n")
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(tools=['default', 'lex'],
- LEXCOM = r'%s mylex.py $TARGET $SOURCES',
+ LEXCOM = r'%(_python_)s mylex.py $TARGET $SOURCES',
LEXCOMSTR = 'Lexing $TARGET from $SOURCE')
env.CFile(target = 'aaa', source = 'aaa.l')
env.CFile(target = 'bbb', source = 'bbb.lex')
-""" % python)
+""" % locals())
test.write('aaa.l', "aaa.l\n/*lex*/\n")
test.write('bbb.lex', "bbb.lex\n/*lex*/\n")
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-env = Environment(LEX = r'%s mylex.py', LEXFLAGS = '-x', tools=['default', 'lex'])
+env = Environment(LEX = r'%(_python_)s mylex.py',
+ LEXFLAGS = '-x',
+ tools=['default', 'lex'])
env.Program(target = 'aaa', source = 'aaa.l')
-""" % python)
+""" % locals())
test.write('aaa.l', r"""
int
""")
test.write('f1.c', r"""
+#include <stdio.h>
+
void
f1(void)
{
""")
test.write('prog.c', r"""
+#include <stdio.h>
+
void f1(void);
int
main(int argc, char *argv[])
test.fail_test(oldtime2 != os.path.getmtime(prog2))
test.write('f1.c', r"""
+#include <stdio.h>
+
void
f1(void)
{
test.up_to_date(arguments = '.', stderr=None)
test.write('f1.c', r"""
+#include <stdio.h>
+
void
f1(void)
{
""")
test.write('foo.c', r"""
+#include <stdio.h>
+
void
foo(void)
{
""")
test.write('prog.c', r"""
+#include <stdio.h>
+
void foo(void);
int
main(int argc, char *argv[])
test.write('foo5.c', foo_contents)
test.write('sl.c', """\
+#include <stdio.h>
void
sl(void)
{
""")
test.write('slprog.c', """\
+#include <stdio.h>
int
main(int argc, char *argv[])
{
""")
test.write('main.c', """\
-#include <stdio.h>
+#include <stdlib.h>
#include "message2.h"
int main (void)
""")
test.write('foo.c', r"""
+#include <stdio.h>
+
void
foo(void)
{
""")
test.write('prog.c', r"""
+#include <stdio.h>
+
void foo(void);
int
main(int argc, char *argv[])
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
test = TestSCons.TestSCons()
test.write('SConstruct', """
foo = Environment()
link = foo.subst("$LINK")
-bar = Environment(LINK = r'%s wrapper.py ' + link)
+bar = Environment(LINK = r'%(_python_)s wrapper.py ' + link)
foo.Program(target = 'foo', source = 'foo.c')
bar.Program(target = 'bar', source = 'bar.c')
-""" % python)
+""" % locals())
test.write('foo.c', r"""
+#include <stdio.h>
+#include <stdlib.h>
int
main(int argc, char *argv[])
{
""")
test.write('bar.c', r"""
+#include <stdio.h>
+#include <stdlib.h>
int
main(int argc, char *argv[])
{
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-env = Environment(LINKCOM = r'%(python)s mylink.py $TARGET $SOURCES',
+env = Environment(LINKCOM = r'%(_python_)s mylink.py $TARGET $SOURCES',
OBJSUFFIX = '.obj',
PROGSUFFIX = '.exe')
env.Program(target = 'test1', source = ['test1.obj', 'test2.obj'])
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-env = Environment(LINKCOM = r'%(python)s mylink.py $TARGET $SOURCES',
+env = Environment(LINKCOM = r'%(_python_)s mylink.py $TARGET $SOURCES',
LINKCOMSTR = 'Linking $TARGET from $SOURCES',
OBJSUFFIX = '.obj',
PROGSUFFIX = '.exe')
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
test = TestSCons.TestSCons()
test.write('SConstruct', """
foo = Environment()
-bar = Environment(LINK = foo.subst(r'%s wrapper.py $LINK'),
+bar = Environment(LINK = foo.subst(r'%(_python_)s wrapper.py $LINK'),
LINKFLAGS = foo.subst('$LINKFLAGS fake_link_flag'))
foo.Program(target = 'foo', source = 'foo.c')
bar.Program(target = 'bar', source = 'bar.c')
-""" % python)
+""" % locals())
test.write('foo.c', r"""
+#include <stdio.h>
+#include <stdlib.h>
int
main(int argc, char *argv[])
{
""")
test.write('bar.c', r"""
+#include <stdio.h>
+#include <stdlib.h>
int
main(int argc, char *argv[])
{
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
dll_ = TestSCons.dll_
_shlib = TestSCons._dll
test.write('SConstruct', """
foo = Environment()
shlink = foo.Dictionary('SHLINK')
-bar = Environment(SHLINK = r'%s wrapper.py ' + shlink)
+bar = Environment(SHLINK = r'%(_python_)s wrapper.py ' + shlink)
foo.SharedLibrary(target = 'foo', source = 'foo.c')
bar.SharedLibrary(target = 'bar', source = 'bar.c')
-""" % python)
+""" % locals())
test.write('foo.c', r"""
#include <stdio.h>
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-env = Environment(SHCCCOM = r'%(python)s mycc.py $TARGET $SOURCES',
- SHLINKCOM = r'%(python)s mylink.py $TARGET $SOURCES',
+env = Environment(SHCCCOM = r'%(_python_)s mycc.py $TARGET $SOURCES',
+ SHLINKCOM = r'%(_python_)s mylink.py $TARGET $SOURCES',
SHOBJSUFFIX = '.obj',
SHLIBPREFIX = '',
SHLIBSUFFIX = '.dll')
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-env = Environment(SHCCCOM = r'%(python)s mycc.py $TARGET $SOURCES',
- SHLINKCOM = r'%(python)s mylink.py $TARGET $SOURCES',
+env = Environment(SHCCCOM = r'%(_python_)s mycc.py $TARGET $SOURCES',
+ SHLINKCOM = r'%(_python_)s mylink.py $TARGET $SOURCES',
SHLINKCOMSTR = 'Linking shared $TARGET from $SOURCES',
SHOBJSUFFIX = '.obj',
SHLIBPREFIX = '',
""")
test.run(stdout = test.wrap_stdout("""\
-%(python)s mycc.py test1.obj test1.c
-%(python)s mycc.py test2.obj test2.c
+%(_python_)s mycc.py test1.obj test1.c
+%(_python_)s mycc.py test2.obj test2.c
Linking shared test3.dll from test1.obj test2.obj
""" % locals()))
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
lib_ = TestSCons.dll_
_shlib = TestSCons._dll
test.write('SConstruct', """
foo = Environment()
-bar = Environment(SHLINK = foo.subst(r'%s wrapper.py $SHLINK'),
+bar = Environment(SHLINK = foo.subst(r'%(_python_)s wrapper.py $SHLINK'),
SHLINKFLAGS = foo.subst('$SHLINKFLAGS fake_shlink_flag'))
foo.SharedLibrary(target = 'foo', source = 'foo.c')
bar.SharedLibrary(target = 'bar', source = 'bar.c')
-""" % python)
+""" % locals())
test.write('foo.c', r"""
#include <stdio.h>
""")
test.write('f1.c', r"""
+#include <stdio.h>
void
f1(void)
{
""")
test.write('f2a.c', r"""
+#include <stdio.h>
void
f2a(void)
{
""")
test.write('f2b.c', r"""
+#include <stdio.h>
void
f2b(void)
{
""")
test.write('f2c.c', r"""
+#include <stdio.h>
void
f2c(void)
{
""")
test.write('f3a.c', r"""
+#include <stdio.h>
void
f3a(void)
{
""")
test.write('f3b.c', r"""
+#include <stdio.h>
void
f3b(void)
{
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-env = Environment(M4 = r'%s mym4.py', tools=['default', 'm4'])
+env = Environment(M4 = r'%(_python_)s mym4.py', tools=['default', 'm4'])
env.M4(target = 'aaa.x', source = 'aaa.x.m4')
-""" % python)
+""" % locals())
test.write('aaa.x.m4', """\
line 1
test.write('SConstruct', """
foo = Environment(M4=r'%(m4)s', M4FLAGS='-DFFF=fff')
m4 = foo.Dictionary('M4')
-bar = Environment(M4 = r'%(python)s wrapper.py ' + m4, M4FLAGS='-DBBB=bbb')
+bar = Environment(M4 = r'%(_python_)s wrapper.py ' + m4, M4FLAGS='-DBBB=bbb')
foo.M4(target = 'foo.x', source = 'foo.x.m4')
bar.M4(target = 'bar', source = 'bar.m4')
""" % locals())
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(tools=['default', 'm4'],
- M4COM = r'%s mym4.py $TARGET $SOURCES')
+ M4COM = r'%(_python_)s mym4.py $TARGET $SOURCES')
env.M4(target = 'aaa.out', source = 'aaa.in')
-""" % python)
+""" % locals())
test.write('aaa.in', "aaa.in\n/*m4*/\n")
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(tools=['default', 'm4'],
- M4COM = r'%s mym4.py $TARGET $SOURCES',
+ M4COM = r'%(_python_)s mym4.py $TARGET $SOURCES',
M4COMSTR = 'M4ing $TARGET from $SOURCE')
env.M4(target = 'aaa.out', source = 'aaa.in')
-""" % python)
+""" % locals())
test.write('aaa.in', "aaa.in\n/*m4*/\n")
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(tools=['default', 'msvc'],
- PCHCOM = r'%s mypch.py $TARGET $SOURCES')
+ PCHCOM = r'%(_python_)s mypch.py $TARGET $SOURCES')
env.PCH(target = 'aaa', source = 'aaa.h')
-""" % python)
+""" % locals())
test.write('aaa.h', "aaa.h\n/*pch*/\n")
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(tools=['default', 'msvc'],
- PCHCOM = r'%s mypch.py $TARGET $SOURCES',
+ PCHCOM = r'%(_python_)s mypch.py $TARGET $SOURCES',
PCHCOMSTR = 'PCHing $TARGET from $SOURCE')
env.PCH(target = 'aaa', source = 'aaa.h')
-""" % python)
+""" % locals())
test.write('aaa.h', "aaa.h\n/*pch*/\n")
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(tools=['default', 'msvc'],
- RCCOM = r'%(python)s myrc.py $TARGET $SOURCES')
+ RCCOM = r'%(_python_)s myrc.py $TARGET $SOURCES')
env.RES(target = 'aaa', source = 'aaa.rc')
""" % locals())
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(tools=['default', 'msvc'],
- RCCOM = r'%(python)s myrc.py $TARGET $SOURCES',
+ RCCOM = r'%(_python_)s myrc.py $TARGET $SOURCES',
RCCOMSTR = 'RCing $TARGET from $SOURCE')
env.RES(target = 'aaa', source = 'aaa.rc')
""" % locals())
--- /dev/null
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Test adding a src_builder to the RES builder so that RC files can
+be generated.
+"""
+
+import TestSCons
+
+_python_ = TestSCons._python_
+
+test = TestSCons.TestSCons()
+
+fake_rc = test.workpath('fake_rc.py')
+
+test.write(fake_rc, """\
+import sys
+contents = open(sys.argv[2], 'rb').read()
+open(sys.argv[1], 'wb').write("fake_rc.py\\n" + contents)
+""")
+
+test.write('SConstruct', """
+def generate_rc(target, source, env):
+ t = str(target[0])
+ s = str(source[0])
+ tfp = open(t, 'wb')
+ tfp.write('generate_rc\\n' + open(s, 'r').read())
+
+env = Environment(tools=['msvc'],
+ RCCOM=r'%(_python_)s %(fake_rc)s $TARGET $SOURCE')
+env['BUILDERS']['GenerateRC'] = Builder(action=generate_rc,
+ suffix='.rc',
+ src_suffix='.in')
+env['BUILDERS']['RES'].src_builder.append('GenerateRC')
+
+env.RES('my.in')
+""" % locals())
+
+test.write('my.in', "my.in\n")
+
+test.run(arguments = '.')
+
+test.must_match('my.rc', "generate_rc\nmy.in\n")
+test.must_match('my.res', "fake_rc.py\ngenerate_rc\nmy.in\n")
+
+test.pass_test()
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
-import TestSCons
-import sys
-import os.path
import os
-import TestCmd
+import os.path
+import re
+import sys
import time
+import TestCmd
+import TestSCons
+
test = TestSCons.TestSCons(match = TestCmd.match_re)
if sys.platform != 'win32':
#####
# Test error reporting
-test.write('SConstruct',"""
-env=Environment()
+SConstruct_path = test.workpath('SConstruct')
+
+test.write(SConstruct_path, """\
+env = Environment()
env['PDB'] = File('test.pdb')
env['PCH'] = env.PCH('StdAfx.cpp')[0]
env.Program('test', 'test.cpp')
""")
-test.run(status=2, stderr='''
+expect_stderr = r'''
scons: \*\*\* The PCHSTOP construction must be defined if PCH is defined.
-File "SConstruct", line 5, in \?
-''')
+File "%s", line 4, in \?
+''' % re.escape(SConstruct_path)
-test.write('SConstruct',"""
-env=Environment()
+test.run(status=2, stderr=expect_stderr)
+
+test.write(SConstruct_path, """\
+env = Environment()
env['PDB'] = File('test.pdb')
env['PCHSTOP'] = File('StdAfx.h')
env['PCH'] = env.PCH('StdAfx.cpp')[0]
env.Program('test', 'test.cpp')
""")
-test.run(status=2, stderr='''
+expect_stderr = r'''
scons: \*\*\* The PCHSTOP construction variable must be a string: .+
-File "SConstruct", line 6, in \?
-''')
+File "%s", line 5, in \?
+''' % re.escape(SConstruct_path)
+
+test.run(status=2, stderr=expect_stderr)
test.pass_test()
msg = "Skipping Visual Studio test on non-Windows platform '%s'\n" % sys.platform
test.skip_test(msg)
-expected_vcprojfile = """\
+vcproj_template = """\
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
\tProjectType="Visual C++"
\t</Configurations>
\t<References>
\t</References>
-\t<Files>
-\t\t\t<Filter
-\t\t\t\tName="subdir"
-\t\t\t\tFilter="">
-\t\t\t<File
-\t\t\t\tRelativePath="subdir\\test1.cpp">
-\t\t\t</File>
-\t\t\t<File
-\t\t\t\tRelativePath="subdir\\test2.cpp">
-\t\t\t</File>
-\t\t\t</Filter>
-\t\t<File
-\t\t\tRelativePath="<SCONSCRIPT>">
-\t\t</File>
-\t</Files>
+%(sln_files)s
\t<Globals>
\t</Globals>
</VisualStudioProject>
SConscript_contents = """\
-env=Environment(MSVS_VERSION = '8.0')
+env=Environment(tools=['msvs'], MSVS_VERSION = '8.0')
-testsrc = ['subdir/test1.cpp', r'subdir\\test2.cpp']
+testsrc = %(testsrc)s
env.MSVSProject(target = 'Test.vcproj',
slnguid = '{SLNGUID}',
test.subdir('work1')
-test.write(['work1', 'SConstruct'], SConscript_contents)
+testsrc = repr([
+ 'prefix/subdir1/test1.cpp',
+ r'prefix\subdir1\test2.cpp',
+ 'prefix/subdir2/test3.cpp',
+])
+
+sln_files = """\t<Files>
+\t\t\t<Filter
+\t\t\t\tName="subdir1"
+\t\t\t\tFilter="">
+\t\t\t<File
+\t\t\t\tRelativePath="prefix\\subdir1\\test1.cpp">
+\t\t\t</File>
+\t\t\t<File
+\t\t\t\tRelativePath="prefix\\subdir1\\test2.cpp">
+\t\t\t</File>
+\t\t\t</Filter>
+\t\t\t<Filter
+\t\t\t\tName="subdir2"
+\t\t\t\tFilter="">
+\t\t\t<File
+\t\t\t\tRelativePath="prefix\\subdir2\\test3.cpp">
+\t\t\t</File>
+\t\t\t</Filter>
+\t\t<File
+\t\t\tRelativePath="<SCONSCRIPT>">
+\t\t</File>
+\t</Files>"""
+
+test.write(['work1', 'SConstruct'], SConscript_contents % locals())
test.run(chdir='work1', arguments="Test.vcproj")
test.must_exist(test.workpath('work1', 'Test.vcproj'))
vcproj = test.read(['work1', 'Test.vcproj'], 'r')
+expected_vcprojfile = vcproj_template % locals()
expect = test.msvs_substitute(expected_vcprojfile, '8.0', 'work1', 'SConstruct')
# don't compare the pickled data
assert vcproj[:len(expect)] == expect, test.diff_substr(expect, vcproj)
+test.subdir('work2')
+
+testsrc = repr([
+ 'prefix/subdir/somefile.cpp',
+])
+
+sln_files = """\t<Files>
+\t\t\t<File
+\t\t\t\tRelativePath="prefix\\subdir\\somefile.cpp">
+\t\t\t</File>
+\t\t<File
+\t\t\tRelativePath="<SCONSCRIPT>">
+\t\t</File>
+\t</Files>"""
+
+test.write(['work2', 'SConstruct'], SConscript_contents % locals())
+
+test.run(chdir='work2', arguments="Test.vcproj")
+
+test.must_exist(test.workpath('work2', 'Test.vcproj'))
+vcproj = test.read(['work2', 'Test.vcproj'], 'r')
+expected_vcprojfile = vcproj_template % locals()
+expect = test.msvs_substitute(expected_vcprojfile, '8.0', 'work2', 'SConstruct')
+# don't compare the pickled data
+assert vcproj[:len(expect)] == expect, test.diff_substr(expect, vcproj)
+
+
+
test.pass_test()
SConscript_contents = """\
-env=Environment(MSVS_VERSION = '8.0')
+env=Environment(tools=['msvs'], MSVS_VERSION = '8.0')
env.MSVSProject(target = 'Test.vcproj',
slnguid = '{SLNGUID}',
SConscript_contents = """\
-env=Environment(MSVS_VERSION = '6.0')
+env=Environment(tools=['msvs'], MSVS_VERSION = '6.0')
testsrc = ['test.c']
testincs = ['sdk.h']
test.subdir('work3')
test.write(['work3', 'SConstruct'], """\
-env=Environment(MSVS_VERSION = '6.0')
+env=Environment(tools=['msvs'], MSVS_VERSION = '6.0')
testsrc = ['test.c']
testincs = ['sdk.h']
SConscript_contents = """\
-env=Environment(MSVS_VERSION = '7.0')
+env=Environment(tools=['msvs'], MSVS_VERSION = '7.0')
testsrc = ['test1.cpp', 'test2.cpp']
testincs = ['sdk.h']
test.run(chdir='work1', arguments='Test.vcproj')
-python = os.path.join('$(PYTHON_ROOT)', os.path.split(sys.executable)[1])
+python = os.path.join('$(PYTHON_ROOT)', os.path.split(TestSCons.python)[1])
test.must_exist(test.workpath('work1', 'Test.vcproj'))
vcproj = test.read(['work1', 'Test.vcproj'], 'r')
test.subdir('work3')
test.write(['work3', 'SConstruct'], """\
-env=Environment(MSVS_VERSION = '7.0')
+env=Environment(tools=['msvs'], MSVS_VERSION = '7.0')
testsrc = ['test1.cpp', 'test2.cpp']
testincs = ['sdk.h']
SConscript_contents = """\
-env=Environment(MSVS_VERSION = '7.1')
+env=Environment(tools=['msvs'], MSVS_VERSION = '7.1')
testsrc = ['test1.cpp', 'test2.cpp']
testincs = ['sdk.h']
test.run(chdir='work1', arguments='Test.vcproj')
-python = os.path.join('$(PYTHON_ROOT)', os.path.split(sys.executable)[1])
+python = os.path.join('$(PYTHON_ROOT)', os.path.split(TestSCons.python)[1])
test.must_exist(test.workpath('work1', 'Test.vcproj'))
vcproj = test.read(['work1', 'Test.vcproj'], 'r')
test.subdir('work3')
test.write(['work3', 'SConstruct'], """\
-env=Environment(MSVS_VERSION = '7.1')
+env=Environment(tools=['msvs'], MSVS_VERSION = '7.1')
testsrc = ['test1.cpp', 'test2.cpp']
testincs = ['sdk.h']
SConscript_contents = """\
-env=Environment(MSVS_VERSION = '8.0')
+env=Environment(tools=['msvs'], MSVS_VERSION = '8.0')
testsrc = ['test1.cpp', 'test2.cpp']
testincs = ['sdk.h']
test.run(chdir='work1', arguments='Test.vcproj')
-python = os.path.join('$(PYTHON_ROOT)', os.path.split(sys.executable)[1])
+python = os.path.join('$(PYTHON_ROOT)', os.path.split(TestSCons.python)[1])
test.must_exist(test.workpath('work1', 'Test.vcproj'))
vcproj = test.read(['work1', 'Test.vcproj'], 'r')
test.subdir('work3')
test.write(['work3', 'SConstruct'], """\
-env=Environment(MSVS_VERSION = '8.0')
+env=Environment(tools=['msvs'], MSVS_VERSION = '8.0')
testsrc = ['test1.cpp', 'test2.cpp']
testincs = ['sdk.h']
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(tools=['default', 'mingw'],
- RCCOM = r'%(python)s myrc.py $TARGET $SOURCES')
+ RCCOM = r'%(_python_)s myrc.py $TARGET $SOURCES')
env.RES(target = 'aaa', source = 'aaa.rc')
""" % locals())
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(tools=['default', 'mingw'],
- RCCOM = r'%(python)s myrc.py $TARGET $SOURCES',
+ RCCOM = r'%(_python_)s myrc.py $TARGET $SOURCES',
RCCOMSTR = 'RCing $TARGET from $SOURCE')
env.RES(target = 'aaa', source = 'aaa.rc')
""" % locals())
_obj = TestSCons._obj
dll_ = TestSCons.dll_
_dll = TestSCons._dll
-
-if sys.platform == 'win32':
- fooflags = '/nologo -DFOO'
- barflags = '/nologo -DBAR'
-else:
- fooflags = '-DFOO'
- barflags = '-DBAR'
if os.name == 'posix':
os.environ['LD_LIBRARY_PATH'] = '.'
test = TestSCons.TestSCons()
+e = test.Environment()
+fooflags = e['SHCXXFLAGS'] + ' -DFOO'
+barflags = e['SHCXXFLAGS'] + ' -DBAR'
+
test.subdir('bld', 'src', ['src', 'subsrcdir'])
sconstruct = r"""
""" % (_obj, _obj, _obj, _obj, _obj, _obj))
test.write('f1.c', r"""
+#include <stdio.h>
void
f1(void)
{
""")
test.write('f3.c', r"""
+#include <stdio.h>
void
f3(void)
{
""")
test.write('f4.c', r"""
+#include <stdio.h>
void
f4(void)
{
""")
test.write('f5.c', r"""
+#include <stdio.h>
void
f5(void)
{
test = TestSCons.TestSCons()
+SConstruct_path = test.workpath('SConstruct')
+
def check(expect):
result = string.split(test.stdout(), '\n')
assert result[1:len(expect)+1] == expect, (result[1:len(expect)+1], expect)
-test.write('SConstruct', """
+test.write(SConstruct_path, """\
from SCons.Options import BoolOption
opts = Options(args=ARGUMENTS)
Default(env.Alias('dummy', None))
""")
+
+
test.run()
check(['1', '0'])
test.run(arguments='warnings=0 profile=no profile=true')
check(['0', '1'])
-test.run(arguments='warnings=irgendwas',
- stderr = """
+expect_stderr = """
scons: *** Error converting option: warnings
Invalid value for boolean option: irgendwas
-File "SConstruct", line 10, in ?
-""", status=2)
+File "%(SConstruct_path)s", line 9, in ?
+""" % locals()
+
+test.run(arguments='warnings=irgendwas', stderr = expect_stderr, status=2)
test = TestSCons.TestSCons()
+SConstruct_path = test.workpath('SConstruct')
+
def check(expect):
result = string.split(test.stdout(), '\n')
assert result[1:len(expect)+1] == expect, (result[1:len(expect)+1], expect)
-test.write('SConstruct', """
+test.write(SConstruct_path, """\
from SCons.Options import EnumOption
list_of_libs = Split('x11 gl qt ical')
test.run(); check(['no', 'gtk', 'xaver'])
+
test.run(arguments='debug=yes guilib=Motif some=xAVER')
check(['yes', 'Motif', 'xaver'])
+
test.run(arguments='debug=full guilib=KdE some=EiNs')
check(['full', 'KdE', 'eins'])
-test.run(arguments='debug=FULL',
- stderr = """
+expect_stderr = """
scons: *** Invalid value for option debug: FULL
-File "SConstruct", line 19, in ?
-""", status=2)
+File "%(SConstruct_path)s", line 18, in ?
+""" % locals()
-test.run(arguments='guilib=IrGeNdwas',
- stderr = """
+test.run(arguments='debug=FULL', stderr=expect_stderr, status=2)
+
+expect_stderr = """
scons: *** Invalid value for option guilib: irgendwas
-File "SConstruct", line 19, in ?
-""", status=2)
+File "%(SConstruct_path)s", line 18, in ?
+""" % locals()
+
+test.run(arguments='guilib=IrGeNdwas', stderr=expect_stderr, status=2)
-test.run(arguments='some=IrGeNdwas',
- stderr = """
+expect_stderr = """
scons: *** Invalid value for option some: irgendwas
-File "SConstruct", line 19, in ?
-""", status=2)
+File "%(SConstruct_path)s", line 18, in ?
+""" % locals()
+
+test.run(arguments='some=IrGeNdwas', stderr=expect_stderr, status=2)
test.pass_test()
test = TestSCons.TestSCons()
+SConstruct_path = test.workpath('SConstruct')
+
def check(expect):
result = string.split(test.stdout(), '\n')
- assert result[1:len(expect)+1] == expect, (result[1:len(expect)+1], expect)
+ r = result[1:len(expect)+1]
+ assert r == expect, (r, expect)
-test.write('SConstruct', """
+test.write(SConstruct_path, """\
from SCons.Options import ListOption
list_of_libs = Split('x11 gl qt ical')
test.run()
check(['all', '1', 'gl ical qt x11', 'gl ical qt x11'])
+
test.run(arguments='shared=none')
check(['none', '0', '', ''])
+
test.run(arguments='shared=')
check(['none', '0', '', ''])
+
test.run(arguments='shared=x11,ical')
check(['ical,x11', '1', 'ical x11', 'ical x11'])
+
test.run(arguments='shared=x11,,ical,,')
check(['ical,x11', '1', 'ical x11', 'ical x11'])
+
test.run(arguments='shared=GL')
check(['gl', '0', 'gl', 'gl'])
+
test.run(arguments='shared=QT,GL')
check(['gl,qt', '0', 'gl qt', 'gl qt'])
-test.run(arguments='shared=foo',
- stderr = """
+expect_stderr = """
scons: *** Error converting option: shared
Invalid value(s) for option: foo
-File "SConstruct", line 15, in ?
-""", status=2)
+File "%(SConstruct_path)s", line 14, in ?
+""" % locals()
+
+test.run(arguments='shared=foo', stderr=expect_stderr, status=2)
# be paranoid in testing some more combinations
-test.run(arguments='shared=foo,ical',
- stderr = """
+expect_stderr = """
scons: *** Error converting option: shared
Invalid value(s) for option: foo
-File "SConstruct", line 15, in ?
-""", status=2)
+File "%(SConstruct_path)s", line 14, in ?
+""" % locals()
+
+test.run(arguments='shared=foo,ical', stderr=expect_stderr, status=2)
-test.run(arguments='shared=ical,foo',
- stderr = """
+expect_stderr = """
scons: *** Error converting option: shared
Invalid value(s) for option: foo
-File "SConstruct", line 15, in ?
-""", status=2)
+File "%(SConstruct_path)s", line 14, in ?
+""" % locals()
-test.run(arguments='shared=ical,foo,x11',
- stderr = """
+test.run(arguments='shared=ical,foo', stderr=expect_stderr, status=2)
+
+expect_stderr = """
scons: *** Error converting option: shared
Invalid value(s) for option: foo
-File "SConstruct", line 15, in ?
-""", status=2)
+File "%(SConstruct_path)s", line 14, in ?
+""" % locals()
+
+test.run(arguments='shared=ical,foo,x11', stderr=expect_stderr, status=2)
-test.run(arguments='shared=foo,x11,,,bar',
- stderr = """
+expect_stderr = """
scons: *** Error converting option: shared
Invalid value(s) for option: foo,bar
-File "SConstruct", line 15, in ?
-""", status=2)
+File "%(SConstruct_path)s", line 14, in ?
+""" % locals()
+
+test.run(arguments='shared=foo,x11,,,bar', stderr=expect_stderr, status=2)
+
+
test.write('SConstruct', """
from SCons.Options import ListOption
test = TestSCons.TestSCons()
+SConstruct_path = test.workpath('SConstruct')
+
def check(expect):
result = string.split(test.stdout(), '\n')
assert result[1:len(expect)+1] == expect, (result[1:len(expect)+1], expect)
-test.write('SConstruct', """
+test.write(SConstruct_path, """\
from SCons.Options import PackageOption
opts = Options(args=ARGUMENTS)
test.run(arguments='x11=0'); check(['0'])
test.run(arguments=['x11=%s' % test.workpath()]); check([test.workpath()])
-test.run(arguments='x11=/non/existing/path/',
- stderr = """
+expect_stderr = """
scons: *** Path does not exist for option x11: /non/existing/path/
-File "SConstruct", line 11, in ?
-""", status=2)
+File "%(SConstruct_path)s", line 10, in ?
+""" % locals()
+
+test.run(arguments='x11=/non/existing/path/', stderr=expect_stderr, status=2)
test = TestSCons.TestSCons()
+SConstruct_path = test.workpath('SConstruct')
+
def check(expect):
result = string.split(test.stdout(), '\n')
assert result[1:len(expect)+1] == expect, (result[1:len(expect)+1], expect)
workpath = test.workpath()
libpath = os.path.join(workpath, 'lib')
-test.write('SConstruct', """
+test.write(SConstruct_path, """\
from SCons.Options import PathOption
qtdir = r'%s'
check([qtpath, libpath, libpath])
qtpath = os.path.join(workpath, 'non', 'existing', 'path')
-test.run(arguments=['qtdir=%s' % qtpath],
- stderr = """
-scons: *** Path for option qtdir does not exist: %s
-File "SConstruct", line 12, in ?
-""" % qtpath, status=2)
-test.run(arguments=['qt_libraries=%s' % qtpath],
- stderr = """
-scons: *** Path for option qt_libraries does not exist: %s
-File "SConstruct", line 12, in ?
-""" % qtpath, status=2)
+expect_stderr = """
+scons: *** Path for option qtdir does not exist: %(qtpath)s
+File "%(SConstruct_path)s", line 11, in ?
+""" % locals()
+
+test.run(arguments=['qtdir=%s' % qtpath], stderr=expect_stderr, status=2)
+
+expect_stderr = """
+scons: *** Path for option qt_libraries does not exist: %(qtpath)s
+File "%(SConstruct_path)s", line 11, in ?
+""" % locals()
+
+test.run(arguments=['qt_libraries=%s' % qtpath], stderr=expect_stderr, status=2)
-test.write('SConstruct', """\
+test.write(SConstruct_path, """\
opts = Options(args=ARGUMENTS)
opts.AddOptions(
PathOption('X', 'X variable', r'%s', validator=PathOption.PathIsFile),
Default(env.Alias('dummy', None))
""" % default_file)
-test.run(status=2,
- stderr="""
-scons: *** File path for option X does not exist: %s
-File "SConstruct", line 6, in ?
-""" % default_file)
+expect_stderr = """
+scons: *** File path for option X does not exist: %(default_file)s
+File "%(SConstruct_path)s", line 6, in ?
+""" % locals()
+
+test.run(status=2, stderr=expect_stderr)
test.write(default_file, "default_file\n")
test.run()
check([default_file])
-test.run(arguments=['X=%s' % existing_subdir],
- status=2,
- stderr="""
-scons: *** File path for option X is a directory: %s
-File "SConstruct", line 6, in ?
-""" % existing_subdir)
+expect_stderr = """
+scons: *** File path for option X is a directory: %(existing_subdir)s
+File "%(SConstruct_path)s", line 6, in ?
+""" % locals()
+
+test.run(arguments=['X=%s' % existing_subdir], status=2, stderr=expect_stderr)
test.run(arguments=['X=%s' % existing_file])
check([existing_file])
-test.run(arguments=['X=%s' % non_existing_file],
- status=2,
- stderr="""
-scons: *** File path for option X does not exist: %s
-File "SConstruct", line 6, in ?
-""" % non_existing_file)
+expect_stderr = """
+scons: *** File path for option X does not exist: %(non_existing_file)s
+File "%(SConstruct_path)s", line 6, in ?
+""" % locals()
+
+test.run(arguments=['X=%s' % non_existing_file], status=2, stderr=expect_stderr)
Default(env.Alias('dummy', None))
""" % default_subdir)
-test.run(status=2,
- stderr="""
-scons: *** Directory path for option X does not exist: %s
-File "SConstruct", line 6, in ?
-""" % default_subdir)
+expect_stderr = """
+scons: *** Directory path for option X does not exist: %(default_subdir)s
+File "%(SConstruct_path)s", line 6, in ?
+""" % locals()
+
+test.run(status=2, stderr=expect_stderr)
test.subdir(default_subdir)
test.run()
check([default_subdir])
+expect_stderr = """
+scons: *** Directory path for option X is a file: %(existing_file)s
+File "%(SConstruct_path)s", line 6, in ?
+""" % locals()
+
test.run(arguments=['X=%s' % existing_file],
status=2,
- stderr="""
-scons: *** Directory path for option X is a file: %s
-File "SConstruct", line 6, in ?
-""" % existing_file)
+ stderr=expect_stderr)
test.run(arguments=['X=%s' % existing_subdir])
check([existing_subdir])
+expect_stderr = """
+scons: *** Directory path for option X does not exist: %(non_existing_subdir)s
+File "%(SConstruct_path)s", line 6, in ?
+""" % locals()
+
test.run(arguments=['X=%s' % non_existing_subdir],
status=2,
- stderr="""
-scons: *** Directory path for option X does not exist: %s
-File "SConstruct", line 6, in ?
-""" % non_existing_subdir)
+ stderr=expect_stderr)
test.run()
check([default_subdir])
-test.run(arguments=['X=%s' % existing_file],
- status=2,
- stderr="""
-scons: *** Path for option X is a file, not a directory: %s
-File "SConstruct", line 6, in ?
-""" % existing_file)
+expect_stderr = """
+scons: *** Path for option X is a file, not a directory: %(existing_file)s
+File "%(SConstruct_path)s", line 6, in ?
+""" % locals()
+
+test.run(arguments=['X=%s' % existing_file], status=2, stderr=expect_stderr)
test.run(arguments=['X=%s' % existing_subdir])
check([existing_subdir])
import TestCmd
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(CPPPATH = [], LIBPATH = [], LIBS = [], CCFLAGS = '')
-env.ParseConfig([r"%(python)s", r"%(test_config1)s", "--libs --cflags"])
-env.ParseConfig([r"%(python)s", r"%(test_config2)s", "--libs --cflags"])
+env.ParseConfig([r'%(_python_)s', r"%(test_config1)s", "--libs --cflags"])
+env.ParseConfig([r'%(_python_)s', r"%(test_config2)s", "--libs --cflags"])
print env['CPPPATH']
print env['LIBPATH']
print map(lambda x: str(x), env['LIBS'])
test.write('SConstruct2', """
env = Environment(CPPPATH = [], LIBPATH = [], LIBS = [], CCFLAGS = '',
- PYTHON = '%(python)s')
+ PYTHON = '%(_python_)s')
env.ParseConfig(r"$PYTHON %(test_config1)s --libs --cflags")
env.ParseConfig(r"$PYTHON %(test_config2)s --libs --cflags")
print env['CPPPATH']
test.write('SConstruct3', """
env = Environment(CPPPATH = [], LIBPATH = [], LIBS = [], CCFLAGS = '',
- PYTHON = '%(python)s')
+ PYTHON = '%(_python_)s')
env.ParseConfig(r"$PYTHON %(test_config3)s --libs --cflags")
print env['CPPPATH']
print env['LIBPATH']
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-Foo = Builder(action = r"%s build.py $TARGET $SOURCES subdir/foo.dep")
-Bar = Builder(action = r"%s build.py $TARGET $SOURCES subdir/bar.dep")
+Foo = Builder(action = r'%(_python_)s build.py $TARGET $SOURCES subdir/foo.dep')
+Bar = Builder(action = r'%(_python_)s build.py $TARGET $SOURCES subdir/bar.dep')
env = Environment(BUILDERS = { 'Foo' : Foo, 'Bar' : Bar }, SUBDIR='subdir')
env.ParseDepends('foo.d')
env.ParseDepends('bar.d')
SConscript('subdir/SConscript', "env")
env.Foo(target = 'f5.out', source = 'f5.in')
env.Bar(target = 'sub2/f6.out', source = 'f6.in')
-""" % (python, python))
+""" % locals())
test.write('foo.d', "f1.out f2.out: %s\n" % os.path.join('subdir', 'foo.dep'))
test.write('bar.d', "%s: %s\nf5.out: sub2" % (os.path.join('subdir', 'f3.out'),
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
f.close()
env = Environment(TOOLS = ['default', 'Perforce'],
BUILDERS={'Cat':Builder(action=cat)},
- P4COM='%(python)s my-p4.py $TARGET')
+ P4COM='%(_python_)s my-p4.py $TARGET')
env.Cat('aaa.out', 'aaa.in')
env.Cat('bbb.out', 'bbb.in')
env.Cat('ccc.out', 'ccc.in')
test.run(arguments = '.',
stdout = test.wrap_stdout(read_str = """\
-%(python)s my-p4.py %(sub_SConscript)s
+%(_python_)s my-p4.py %(sub_SConscript)s
""" % locals(),
build_str = """\
-%(python)s my-p4.py aaa.in
+%(_python_)s my-p4.py aaa.in
cat(["aaa.out"], ["aaa.in"])
cat(["bbb.out"], ["bbb.in"])
-%(python)s my-p4.py ccc.in
+%(_python_)s my-p4.py ccc.in
cat(["ccc.out"], ["ccc.in"])
cat(["all"], ["aaa.out", "bbb.out", "ccc.out"])
-%(python)s my-p4.py %(sub_ddd_in)s
+%(_python_)s my-p4.py %(sub_ddd_in)s
cat(["%(sub_ddd_out)s"], ["%(sub_ddd_in)s"])
cat(["%(sub_eee_out)s"], ["%(sub_eee_in)s"])
-%(python)s my-p4.py %(sub_fff_in)s
+%(_python_)s my-p4.py %(sub_fff_in)s
cat(["%(sub_fff_out)s"], ["%(sub_fff_in)s"])
cat(["%(sub_all)s"], ["%(sub_ddd_out)s", "%(sub_eee_out)s", "%(sub_fff_out)s"])
""" % locals()))
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
f.close()
env = Environment(TOOLS = ['default', 'Perforce'],
BUILDERS={'Cat':Builder(action=cat)},
- P4COM='%(python)s my-p4.py $TARGET',
+ P4COM='%(_python_)s my-p4.py $TARGET',
P4COMSTR='Checking out $TARGET from our fake Perforce')
env.Cat('aaa.out', 'aaa.in')
env.Cat('bbb.out', 'bbb.in')
"""
import os
-import socket
import string
import TestSCons
def __init__(self, *args, **kw):
apply(TestSCons.TestSCons.__init__, (self,)+args, kw)
- self._p4prog = self.where_is('p4')
- if not self._p4prog:
+ self.p4path = self.where_is('p4')
+ if not self.p4path:
self.skip_test("Could not find 'p4'; skipping test(s).\n")
- self.host = socket.gethostname()
+ #import socket
+ #self.host = socket.gethostname()
+ self.host = '127.0.0.1'
self.user = os.environ.get('USER')
if not self.user:
arguments = args[0]
args = args[1:]
kw['arguments'] = string.join(self.p4portflags + [arguments])
- kw['program'] = self._p4prog
+ kw['program'] = self.p4path
return apply(self.run, args, kw)
def substitute(self, s, **kw):
Owner: %(user)s
-Host: %(host)s
-
Description:
Created by %(user)s.
for src in source:
f.write(open(src, "rb").read())
f.close()
-env = Environment(BUILDERS={'Cat':Builder(action=cat)},
+env = Environment(tools = ['default', 'Perforce'],
+ BUILDERS={'Cat':Builder(action=cat)},
+ P4=r'%(p4path)s',
P4FLAGS='%(portflag)s -c testclient2')
env.Cat('aaa.out', 'foo/aaa.in')
env.Cat('bbb.out', 'foo/bbb.in')
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
sys.exit(0)
""")
+SUBDIR_f4_out = os.path.join('$SUBDIR', 'f4.out')
+
test.write('SConstruct', """\
-B = Builder(action = r"%s build.py $TARGET $SOURCES")
+B = Builder(action = r'%(_python_)s build.py $TARGET $SOURCES')
env = Environment(BUILDERS = { 'B' : B }, SUBDIR = 'subdir')
f1 = env.B(target = 'f1.out', source = 'f1.in')
env.B(target = 'f2.out', source = 'f2.in')
env.B(target = 'f3.out', source = 'f3.in')
env.B(target = 'subdir/f4.out', source = 'f4.in')
-env.Precious(f1, 'f2.out', r'%s')
+env.Precious(f1, 'f2.out', r'%(SUBDIR_f4_out)s')
SConscript('subdir/SConscript', "env")
-""" % (python,
- os.path.join('$SUBDIR', 'f4.out')))
+""" % locals())
test.write(['subdir', 'SConscript'], """
Import("env")
""")
test.write('f1.c', r"""
+#include <stdio.h>
+#include <stdlib.h>
int
main(int argc, char *argv[])
{
""")
test.write('f2.c', r"""
+#include <stdio.h>
+#include <stdlib.h>
+
int
main(int argc, char *argv[])
{
test.write('f3.c', r"""
+#include <stdio.h>
+#include <stdlib.h>
int
main(int argc, char *argv[])
{
""")
test.write('f4.c', r"""
+#include <stdio.h>
+#include <stdlib.h>
int
main(int argc, char *argv[])
{
""")
test.write('f1.c', r"""
+#include <stdio.h>
+#include <stdlib.h>
int
main(int argc, char *argv[])
{
""")
test.write('f2a.c', r"""
+#include <stdio.h>
+#include <stdlib.h>
void
f2a(void)
{
""")
test.write('f2b.c', r"""
+#include <stdio.h>
void
f2b(void)
{
""")
test.write('f2c.c', r"""
+#include <stdio.h>
+#include <stdlib.h>
extern void f2a(void);
extern void f2b(void);
int
""")
test.write('f3a.c', r"""
+#include <stdio.h>
void
f3a(void)
{
""")
test.write('f3b.c', r"""
+#include <stdio.h>
void
f3b(void)
{
""")
test.write('f3c.c', r"""
+#include <stdio.h>
+#include <stdlib.h>
extern void f3a(void);
extern void f3b(void);
int
""")
test.write('f4.c', r"""
+#include <stdio.h>
+#include <stdlib.h>
int
main(int argc, char *argv[])
{
""")
test.write('foo5.c', r"""
+#include <stdio.h>
+#include <stdlib.h>
int
main(int argc, char *argv[])
{
test.up_to_date(arguments = '.')
test.write('f1.c', r"""
+#include <stdio.h>
+#include <stdlib.h>
int
main(int argc, char *argv[])
{
""")
test.write('f3b.c', r"""
+#include <stdio.h>
void
f3b(void)
{
""")
test.write('f4.c', r"""
+#include <stdio.h>
+#include <stdlib.h>
int
main(int argc, char *argv[])
{
""")
test.write('foo5.c', r"""
+#include <stdio.h>
+#include <stdlib.h>
int
main(int argc, char *argv[])
{
test.fail_test(oldtime5 != os.path.getmtime(foo5))
test.write('f1.c', r"""
+#include <stdio.h>
+#include <stdlib.h>
int
main(int argc, char *argv[])
{
""")
test.write('f3b.c', r"""
+#include <stdio.h>
+#include <stdlib.h>
void
f3b(void)
{
""")
test.write('f4.c', r"""
+#include <stdio.h>
+#include <stdlib.h>
int
main(int argc, char *argv[])
{
""")
test.write('foo5.c', r"""
+#include <stdio.h>
+#include <stdlib.h>
int
main(int argc, char *argv[])
{
test.up_to_date(arguments = foo_args)
test.write('f1.c', r"""
+#include <stdio.h>
+#include <stdlib.h>
int
main(int argc, char *argv[])
{
""")
test.write('f3b.c', r"""
+#include <stdio.h>
+#include <stdlib.h>
void
f3b(void)
{
""")
test.write('f4.c', r"""
+#include <stdio.h>
+#include <stdlib.h>
int
main(int argc, char *argv[])
{
""")
test.write('foo5.c', r"""
+#include <stdio.h>
+#include <stdlib.h>
int
main(int argc, char *argv[])
{
import TestSCons
import os.path
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
test = TestSCons.TestSCons()
QT = test.workpath('qt')
QT_LIB = 'myqt'
-QT_MOC = '%s %s' % (python, test.workpath('qt','bin','mymoc.py'))
-QT_UIC = '%s %s' % (python, test.workpath('qt','bin','myuic.py'))
+QT_MOC = '%s %s' % (_python_, test.workpath('qt','bin','mymoc.py'))
+QT_UIC = '%s %s' % (_python_, test.workpath('qt','bin','myuic.py'))
def createSConstruct(test,place,overrides):
test.write(place, """
Create a moc file from a header file.
"""
+import os
+
import TestSCons
test = TestSCons.TestSCons()
test.Qt_dummy_installation()
+# We'll run some test programs later that need to find our dummy
+# Qt library.
+os.environ['LD_LIBRARY_PATH'] = test.QT_LIB_DIR
+
##############################################################################
aaa_exe = 'aaa' + TestSCons._exe
"""
import os
+import re
import string
import TestSCons
test = TestSCons.TestSCons()
+SConstruct_path = test.workpath('SConstruct')
+
test.Qt_dummy_installation()
-test.Qt_create_SConstruct('SConstruct')
+test.Qt_create_SConstruct(SConstruct_path)
test.write('aaa.cpp', r"""
#include "my_qobject.h"
moc = test.where_is('moc')
if moc:
import os.path
+ qtdir = os.path.dirname(os.path.dirname(moc))
+ qtdir = string.replace(qtdir, '\\', '\\\\' )
+
expect = """
scons: warning: Could not detect qt, using moc executable as a hint \(QTDIR=%s\)
-File "SConstruct", line \d+, in \?
-""" % string.replace( os.path.dirname(os.path.dirname(moc)), '\\', '\\\\' )
+File "%s", line \d+, in \?
+""" % (qtdir, re.escape(SConstruct_path))
else:
+
expect = """
scons: warning: Could not detect qt, using empty QTDIR
-File "SConstruct", line \d+, in \?
-"""
+File "%s", line \d+, in \?
+""" % re.escape(SConstruct_path)
test.fail_test(not test.match_re(test.stderr(), expect))
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
foo = Environment(LIBS = ['foo'], LIBPATH = ['.'])
ranlib = foo.Dictionary('RANLIB')
bar = Environment(LIBS = ['bar'], LIBPATH = ['.'],
- RANLIB = r'%s wrapper.py ' + ranlib)
+ RANLIB = r'%(_python_)s wrapper.py ' + ranlib)
foo.Library(target = 'foo', source = 'foo.c')
bar.Library(target = 'bar', source = 'bar.c')
foo.Program(target = 'f', source = main)
bar.Program(target = 'b', source = main)
-""" % python)
+""" % locals())
test.write('foo.c', r"""
+#include <stdio.h>
void
library_function(void)
{
""")
test.write('bar.c', r"""
+#include <stdio.h>
+
void
library_function(void)
{
""")
test.write('main.c', r"""
+#include <stdlib.h>
int
main(int argc, char *argv[])
{
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(tools=['default', 'ar'],
- ARCOM = r'%s myar.py $TARGET $SOURCES',
- RANLIBCOM = r'%s myranlib.py $TARGET',
+ ARCOM = r'%(_python_)s myar.py $TARGET $SOURCES',
+ RANLIBCOM = r'%(_python_)s myranlib.py $TARGET',
LIBPREFIX = '',
LIBSUFFIX = '.lib')
env.Library(target = 'output', source = ['file.1', 'file.2'])
-""" % (python, python))
+""" % locals())
test.write('file.1', "file.1\n/*ar*/\n/*ranlib*/\n")
test.write('file.2', "file.2\n/*ar*/\n/*ranlib*/\n")
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(tools=['default', 'ar'],
- ARCOM = r'%s myar.py $TARGET $SOURCES',
- RANLIBCOM = r'%s myranlib.py $TARGET',
+ ARCOM = r'%(_python_)s myar.py $TARGET $SOURCES',
+ RANLIBCOM = r'%(_python_)s myranlib.py $TARGET',
RANLIBCOMSTR = 'Indexing $TARGET',
LIBPREFIX = '',
LIBSUFFIX = '.lib')
env.Library(target = 'output', source = ['file.1', 'file.2'])
-""" % (python, python))
+""" % locals())
test.write('file.1', "file.1\n/*ar*/\n/*ranlib*/\n")
test.write('file.2', "file.2\n/*ar*/\n/*ranlib*/\n")
-test.run(stdout = test.wrap_stdout("""\
-%s myar.py output.lib file.1 file.2
+expect = test.wrap_stdout("""\
+%(_python_)s myar.py output.lib file.1 file.2
Indexing output.lib
-""" % python))
+""" % locals())
+
+test.run(stdout = expect)
test.must_match('output.lib', "file.1\nfile.2\n")
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
test = TestSCons.TestSCons()
test.write('SConstruct', """
foo = Environment(LIBS = ['foo'], LIBPATH = ['.'])
bar = Environment(LIBS = ['bar'], LIBPATH = ['.'], RANLIB = '',
- RANLIBFLAGS = foo.subst(r'%s wrapper.py $RANLIB $RANLIBFLAGS'))
+ RANLIBFLAGS = foo.subst(r'%(_python_)s wrapper.py $RANLIB $RANLIBFLAGS'))
foo.Library(target = 'foo', source = 'foo.c')
bar.Library(target = 'bar', source = 'bar.c')
foo.Program(target = 'f', source = main)
bar.Program(target = 'b', source = main)
-""" % python)
+""" % locals())
test.write('foo.c', r"""
+#include <stdlib.h>
+#include <stdio.h>
+
void
library_function(void)
{
""")
test.write('bar.c', r"""
+#include <stdlib.h>
+#include <stdio.h>
void
library_function(void)
{
""")
test.write('main.c', r"""
+#include <stdlib.h>
+
int
main(int argc, char *argv[])
{
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
f.close()
env = Environment(TOOLS = ['default', 'RCS'],
BUILDERS={'Cat':Builder(action=cat)},
- RCS_COCOM='%(python)s my-rcs-co.py $TARGET')
+ RCS_COCOM='%(_python_)s my-rcs-co.py $TARGET')
env.Cat('aaa.out', 'aaa.in')
env.Cat('bbb.out', 'bbb.in')
env.Cat('ccc.out', 'ccc.in')
test.run(arguments = '.',
stdout = test.wrap_stdout(read_str = """\
-%(python)s my-rcs-co.py %(sub_SConscript)s
+%(_python_)s my-rcs-co.py %(sub_SConscript)s
""" % locals(),
build_str = """\
-%(python)s my-rcs-co.py aaa.in
+%(_python_)s my-rcs-co.py aaa.in
cat(["aaa.out"], ["aaa.in"])
cat(["bbb.out"], ["bbb.in"])
-%(python)s my-rcs-co.py ccc.in
+%(_python_)s my-rcs-co.py ccc.in
cat(["ccc.out"], ["ccc.in"])
cat(["all"], ["aaa.out", "bbb.out", "ccc.out"])
-%(python)s my-rcs-co.py %(sub_ddd_in)s
+%(_python_)s my-rcs-co.py %(sub_ddd_in)s
cat(["%(sub_ddd_out)s"], ["%(sub_ddd_in)s"])
cat(["%(sub_eee_out)s"], ["%(sub_eee_in)s"])
-%(python)s my-rcs-co.py %(sub_fff_in)s
+%(_python_)s my-rcs-co.py %(sub_fff_in)s
cat(["%(sub_fff_out)s"], ["%(sub_fff_in)s"])
cat(["%(sub_all)s"], ["%(sub_ddd_out)s", "%(sub_eee_out)s", "%(sub_fff_out)s"])
""" % locals()))
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
f.close()
env = Environment(TOOLS = ['default', 'RCS'],
BUILDERS={'Cat':Builder(action=cat)},
- RCS_COCOM='%(python)s my-rcs-co.py $TARGET',
+ RCS_COCOM='%(_python_)s my-rcs-co.py $TARGET',
RCS_COCOMSTR='Checking out $TARGET from our fake RCS')
env.Cat('aaa.out', 'aaa.in')
env.Cat('bbb.out', 'bbb.in')
test.write(['sub', 'eee.in'], "checked-out sub/eee.in\n")
+
expect = """\
scons: warning: Ignoring missing SConscript '%s'
-File "SConstruct", line 23, in ?
+File "%s", line 23, in ?
scons: *** Source `aaa.in' not found, needed by target `aaa.out'. Stop.
-""" % os.path.join('sub', 'SConscript')
+""" % (os.path.join('sub', 'SConscript'), test.workpath('SConstruct'))
test.run(status=2, stderr=expect)
test.subdir('RCS')
test.write('foo.c', """\
+#include <stdio.h>
+
#include "foo.h"
int
main(int argc, char *argv[]) {
""")
test.write('foo.c', """\
+#include <stdlib.h>
int main() {
void bar();
bar();
""")
test.write(['repository', 'foo.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
#include <foo.h>
int
main(int argc, char *argv[])
""")
test.write(['work', 'aaa.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
int
main(int argc, char *argv[])
{
""")
test.write(['work', 'bbb.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
int
main(int argc, char *argv[])
{
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
sys.exit(0)
""")
+mym4_py = test.workpath('mym4.py')
opts = "-Y " + test.workpath('repository')
test.write(['repository', 'SConstruct'], """\
-env = Environment(M4 = r'%s %s', tools=['default', 'm4'])
+env = Environment(M4 = r'%(_python_)s %(mym4_py)s', tools=['default', 'm4'])
env.M4(target = 'aaa.x', source = 'aaa.x.m4')
SConscript('src/SConscript', "env", build_dir="build")
-""" % (python, test.workpath('mym4.py')))
+""" % locals())
test.write(['repository', 'aaa.x.m4'], """\
line 1
""" % repository)
test.write(['repository', 'aaa.c'], r"""
+#include <stdio.h>
void
aaa(void)
{
""")
test.write(['repository', 'bbb.c'], r"""
+#include <stdio.h>
void
bbb(void)
{
""")
test.write(['repository', 'foo.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
+
extern void aaa(void);
extern void bbb(void);
int
#
test.write(['work1', 'bbb.c'], r"""
+#include <stdio.h>
void
bbb(void)
{
#
test.write(['work1', 'aaa.c'], r"""
+#include <stdio.h>
void
aaa(void)
{
""")
test.write(['work1', 'foo.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
extern void aaa(void);
extern void bbb(void);
int
""" % (repository_new, repository_old))
test.write(['repository.old', 'aaa.c'], r"""
+#include <stdio.h>
void
aaa(void)
{
""")
test.write(['repository.old', 'bbb.c'], r"""
+#include <stdio.h>
void
bbb(void)
{
""")
test.write(['repository.old', 'foo.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
extern void aaa(void);
extern void bbb(void);
int
test.writable('repository.new', 1)
test.write(['repository.new', 'aaa.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
void
aaa(void)
{
""")
test.write(['work2', 'bbb.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
void
bbb(void)
{
#
test.write(['work2', 'aaa.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
void
aaa(void)
{
""")
test.write(['work2', 'foo.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
extern void aaa(void);
extern void bbb(void);
int
""")
test.write(['repository', 'aaa.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
void
aaa(void)
{
""")
test.write(['repository', 'bbb.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
void
bbb(void)
{
""")
test.write(['repository', 'foo.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
extern void aaa(void);
extern void bbb(void);
int
test.up_to_date(chdir = 'work1', options = opts, arguments = ".")
test.write(['work1', 'bbb.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
void
bbb(void)
{
test.up_to_date(chdir = 'work2', options = opts, arguments = ".")
test.write(['work2', 'bbb.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
void
bbb(void)
{
test.up_to_date(chdir = 'work3', options = opts, arguments = ".")
test.write(['work3', 'foo.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
extern void aaa(void);
extern void bbb(void);
int
""" % subdir_aaa_c)
test.write(['repository', 'src', 'aaa.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
void
src_aaa(void)
{
""")
test.write(['subdir', 'aaa.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
void
subdir_aaa(void)
{
""")
test.write(['repository', 'src', 'foo.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
extern void src_aaa(void);
extern void subdir_aaa(void);
int
""")
test.write(['repository', 'foo.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
#include <foo.h>
int
main(int argc, char *argv[])
#
test.write(['work', 'foo.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
#include <foo.h>
int
main(int argc, char *argv[])
""" % workpath_repository)
test.write(['repository', 'aaa.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
void
aaa(void)
{
""")
test.write(['repository', 'bbb.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
void
bbb(void)
{
""")
test.write(['repository', 'foo.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
extern void aaa(void);
extern void bbb(void);
int
#
test.write(['work', 'bbb.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
void
bbb(void)
{
""")
test.write(['repository', 'src', 'main.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
#include <include.h>
int
main(int argc, char *argv[])
test.write(['src', 'foo.c'], """\
#include <stdio.h>
+#include <stdlib.h>
#include "foo.h"
int
main(int argc, char *argv[])
""" % no_repository)
test.write(['work', 'aaa.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
void
aaa(void)
{
""")
test.write(['work', 'bbb.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
void
bbb(void)
{
""")
test.write(['work', 'foo.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
extern void aaa(void);
extern void bbb(void);
int
test.write(['repository', 'bar.h'], bar_h_contents)
test.write(['repository', 'foo.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
#include <foo.h>
#include <bar.h>
int
""")
test.write(['repository', 'src', 'aaa.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
void
src_aaa(void)
{
""")
test.write(['repository', 'subdir', 'aaa.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
void
subdir_aaa(void)
{
""")
test.write(['repository', 'src', 'foo.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
extern void src_aaa(void);
extern void subdir_aaa(void);
int
""")
test.write(['repository', 'src1', 'aaa.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
#include <iii.h>
void
aaa(void)
""")
test.write(['repository', 'src1', 'bbb.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
#include <iii.h>
void
bbb(void)
""")
test.write(['repository', 'src1', 'main.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
#include <iii.h>
extern void aaa(void);
extern void bbb(void);
""")
test.write(['repository', 'src2', 'xxx', 'main.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
#include <include.h>
#ifdef FOO
#define MAIN_OS "FOO"
""" % workpath_repository)
test.write(['repository', 'aaa.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
void
aaa(void)
{
""")
test.write(['repository', 'bbb.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
void
bbb(void)
{
""")
test.write(['repository', 'foo.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
extern void aaa(void);
extern void bbb(void);
int
""")
test.write(['repository', 'src', 'aaa.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
void
aaa(void)
{
""")
test.write(['repository', 'src', 'bbb.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
void
bbb(void)
{
""")
test.write(['repository', 'src', 'bar.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
extern void aaa(void);
extern void bbb(void);
int
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """\
-env = Environment(RPCGEN = r'%s myrpcgen.py', tools=['default', 'rpcgen'])
+env = Environment(RPCGEN = r'%(_python_)s myrpcgen.py',
+ tools=['default', 'rpcgen'])
env.RPCGenHeader('rpcif')
env.RPCGenClient('rpcif')
env.RPCGenService('rpcif')
env.RPCGenXDR('rpcif')
-""" % (python,))
+""" % locals())
test.write('rpcif.x', """\
RPCGEN
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """\
-env = Environment(RPCGEN = r'%s myrpcgen.py',
+env = Environment(RPCGEN = r'%(_python_)s myrpcgen.py',
RPCGENCLIENTFLAGS = '-x',
tools=['default', 'rpcgen'])
env.RPCGenHeader('rpcif')
env.RPCGenClient('rpcif')
env.RPCGenService('rpcif')
env.RPCGenXDR('rpcif')
-""" % (python,))
+""" % locals())
test.write('rpcif.x', """\
RPCGEN
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """\
-env = Environment(RPCGEN = r'%s myrpcgen.py',
+env = Environment(RPCGEN = r'%(_python_)s myrpcgen.py',
RPCGENFLAGS = '-x',
tools=['default', 'rpcgen'])
env.RPCGenHeader('rpcif')
env.RPCGenClient('rpcif')
env.RPCGenService('rpcif')
env.RPCGenXDR('rpcif')
-""" % (python,))
+""" % locals())
test.write('rpcif.x', """\
RPCGEN
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """\
-env = Environment(RPCGEN = r'%s myrpcgen.py',
+env = Environment(RPCGEN = r'%(_python_)s myrpcgen.py',
RPCGENHEADERFLAGS = '-x',
tools=['default', 'rpcgen'])
env.RPCGenHeader('rpcif')
env.RPCGenClient('rpcif')
env.RPCGenService('rpcif')
env.RPCGenXDR('rpcif')
-""" % (python,))
+""" % locals())
test.write('rpcif.x', """\
RPCGEN
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """\
-env = Environment(RPCGEN = r'%s myrpcgen.py',
+env = Environment(RPCGEN = r'%(_python_)s myrpcgen.py',
RPCGENSERVICEFLAGS = '-x',
tools=['default', 'rpcgen'])
env.RPCGenHeader('rpcif')
env.RPCGenClient('rpcif')
env.RPCGenService('rpcif')
env.RPCGenXDR('rpcif')
-""" % (python,))
+""" % locals())
test.write('rpcif.x', """\
RPCGEN
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """\
-env = Environment(RPCGEN = r'%s myrpcgen.py',
+env = Environment(RPCGEN = r'%(_python_)s myrpcgen.py',
RPCGENXDRFLAGS = '-x',
tools=['default', 'rpcgen'])
env.RPCGenHeader('rpcif')
env.RPCGenClient('rpcif')
env.RPCGenService('rpcif')
env.RPCGenXDR('rpcif')
-""" % (python,))
+""" % locals())
test.write('rpcif.x', """\
RPCGEN
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
f.close()
env = Environment(TOOLS = ['default', 'SCCS'],
BUILDERS={'Cat':Builder(action=cat)},
- SCCSCOM='%(python)s my-sccs-get.py $TARGET')
+ SCCSCOM='%(_python_)s my-sccs-get.py $TARGET')
env.Cat('aaa.out', 'aaa.in')
env.Cat('bbb.out', 'bbb.in')
env.Cat('ccc.out', 'ccc.in')
test.run(arguments = '.',
stdout = test.wrap_stdout(read_str = """\
-%(python)s my-sccs-get.py %(sub_SConscript)s
+%(_python_)s my-sccs-get.py %(sub_SConscript)s
""" % locals(),
build_str = """\
-%(python)s my-sccs-get.py aaa.in
+%(_python_)s my-sccs-get.py aaa.in
cat(["aaa.out"], ["aaa.in"])
cat(["bbb.out"], ["bbb.in"])
-%(python)s my-sccs-get.py ccc.in
+%(_python_)s my-sccs-get.py ccc.in
cat(["ccc.out"], ["ccc.in"])
cat(["all"], ["aaa.out", "bbb.out", "ccc.out"])
-%(python)s my-sccs-get.py %(sub_ddd_in)s
+%(_python_)s my-sccs-get.py %(sub_ddd_in)s
cat(["%(sub_ddd_out)s"], ["%(sub_ddd_in)s"])
cat(["%(sub_eee_out)s"], ["%(sub_eee_in)s"])
-%(python)s my-sccs-get.py %(sub_fff_in)s
+%(_python_)s my-sccs-get.py %(sub_fff_in)s
cat(["%(sub_fff_out)s"], ["%(sub_fff_in)s"])
cat(["%(sub_all)s"], ["%(sub_ddd_out)s", "%(sub_eee_out)s", "%(sub_fff_out)s"])
""" % locals()))
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
f.close()
env = Environment(TOOLS = ['default', 'SCCS'],
BUILDERS={'Cat':Builder(action=cat)},
- SCCSCOM='%(python)s my-sccs-get.py $TARGET',
+ SCCSCOM='%(_python_)s my-sccs-get.py $TARGET',
SCCSCOMSTR='Checking out $TARGET from our fake SCCS')
env.Cat('aaa.out', 'aaa.in')
env.Cat('bbb.out', 'bbb.in')
Test transparent checkouts from SCCS files in an SCCS subdirectory.
"""
+import os.path
import string
import TestSCons
expect = """\
-scons: warning: Ignoring missing SConscript 'sub/SConscript'
-File "SConstruct", line 17, in ?
+scons: warning: Ignoring missing SConscript '%s'
+File "%s", line 17, in ?
scons: *** Source `aaa.in' not found, needed by target `aaa.out'. Stop.
-"""
+""" % (os.path.join('sub', 'SConscript'), test.workpath('SConstruct'))
test.run(status=2, stderr=expect)
stdout = test.wrap_stdout(read_str = 'SConstruct %s\nSConscript %s\n' % (wpath, wpath),
build_str = "scons: `.' is up to date.\n"))
-# Test exporting all global variables as a list of keys:
-test.write("SConstruct", """
-x = 'x'
-y = 'zoom'
-Export(globals().keys())
-SConscript('SConscript')
-""")
-
-test.write("SConscript", """
-Import(['x', 'y'])
-assert x == 'x'
-assert y == 'zoom'
-""")
-
-test.run(arguments = ".")
-
-# Test exporting all global variables as a list of keys in SConscript call:
-test.write("SConstruct", """
-x = 'x'
-y = 'zoom'
-SConscript('SConscript', globals().keys())
-""")
-
-test.write("SConscript", """
-Import(['x', 'y'])
-assert x == 'x'
-assert y == 'zoom'
-""")
-
-test.run(arguments = ".")
-
-# Test exporting all global variables as a dictionary:
-test.write("SConstruct", """
-x = 'x'
-y = 'zoom'
-Export(globals())
-SConscript('SConscript')
-""")
-
-test.write("SConscript", """
-Import(['x', 'y'])
-assert x == 'x'
-assert y == 'zoom'
-""")
-
-test.run(arguments = ".")
-
-# Test exporting all global variables as dictionary in SConscript call:
-test.write("SConstruct", """
-x = 'x'
-y = 'zoom'
-SConscript('SConscript', globals())
-""")
-
-test.write("SConscript", """
-Import(['x', 'y'])
-assert x == 'x'
-assert y == 'zoom'
-""")
-
-test.run(arguments = ".")
-
-# Test export of local variables:
-test.write("SConstruct", """
-def f():
- x = 'x'
- y = 'zoom'
- Export('x', 'y')
-
-f()
-SConscript('SConscript')
-""")
-
-test.write("SConscript", """
-Import(['x', 'y'])
-assert x == 'x'
-assert y == 'zoom'
-""")
-
-test.run(arguments = ".")
-
-# Test export of local variables in SConscript call:
-test.write("SConstruct", """
-def f():
- x = 'x'
- y = 'zoom'
- SConscript('SConscript', ['x', 'y'])
-f()
-""")
-
-test.write("SConscript", """
-Import(['x', 'y'])
-assert x == 'x'
-assert y == 'zoom'
-""")
-
-test.run(arguments = ".")
-
-# Test export of local variables as a dictionary:
-test.write("SConstruct", """
-def f():
- x = 'x'
- y = 'zoom'
- Export(locals())
-
-f()
-SConscript('SConscript')
-""")
-
-test.write("SConscript", """
-Import(['x', 'y'])
-assert x == 'x'
-assert y == 'zoom'
-""")
-
-test.run(arguments = ".")
-
-# Test importing all variables:
-test.write("SConstruct", """
-x = 'x'
-y = 'zoom'
-Export('x')
-SConscript('SConscript', 'y')
-""")
-
-test.write("SConscript", """
-Import('*')
-assert x == 'x'
-assert y == 'zoom'
-""")
-
-test.run(arguments = ".")
-
-# Test white space
-test.subdir('white space')
-test.write("SConstruct", """\
-SConscript('white space/SConscript')
-""")
-
-test.write(['white space', 'SConscript'], """\
-print "`white space/SConscript'"
-""")
-
-test.run(arguments = ".",
- stdout = test.wrap_stdout(read_str = "`white space/SConscript'\n",
- build_str = "scons: `.' is up to date.\n"))
-
-# Test calling SConscript through a construction environment.
-test.subdir('sub1', 'sub2')
-
-test.write("SConstruct", """\
-env = Environment(SUB1='sub1', SUB2='sub2')
-print "SConstruct"
-x = 'xxx'
-y = 'yyy'
-env.Export(["x", "y"])
-env.SConscript('$SUB1/SConscript')
-env.SConscript(dirs=['$SUB2'])
-SConscript(['s1', 's2'])
-env.SConscript(['s3', 's4'])
-""")
-
-test.write(['sub1', 'SConscript'], """\
-env = Environment()
-env.Import("x")
-print "sub1/SConscript"
-print "x =", x
-""")
-
-test.write(['sub2', 'SConscript'], """\
-env = Environment()
-env.Import("y")
-print "sub2/SConscript"
-print "y =", y
-""")
-
-test.write('s1', "\n")
-test.write('s2', "\n")
-test.write('s3', "\n")
-test.write('s4', "\n")
-
-expect = """\
-SConstruct
-sub1/SConscript
-x = xxx
-sub2/SConscript
-y = yyy
-"""
-
-test.run(arguments = ".",
- stdout = test.wrap_stdout(read_str = expect,
- build_str = "scons: `.' is up to date.\n"))
-
-test.write("SConstruct", """\
-def builder(target, source, env):
- import SCons.Script.SConscript
- assert SCons.Script.SConscript.sconscript_reading == 0
-env = Environment(BUILDERS={'builder':Builder(action=builder)})
-env.builder('test',[])
-import SCons.Script.SConscript
-assert SCons.Script.SConscript.sconscript_reading == 1
-""")
-
test.pass_test()
--- /dev/null
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import sys
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+test.subdir('dir1', 'dir2', 'dir3', 'dir4', 'dir5')
+
+test.write('SConstruct', """
+env = Environment()
+SConscript('dir1/SConscript')
+SConscriptChdir(1)
+SConscript('dir2/SConscript')
+SConscriptChdir(0)
+SConscript('dir3/SConscript')
+env.SConscriptChdir(1)
+SConscript('dir4/SConscript')
+env.SConscriptChdir(0)
+SConscript('dir5/SConscript')
+""")
+
+test.write(['dir1', 'SConscript'], """
+execfile("create_test.py")
+""")
+
+test.write(['dir2', 'SConscript'], """
+execfile("create_test.py")
+""")
+
+test.write(['dir3', 'SConscript'], """
+import os.path
+name = os.path.join('dir3', 'create_test.py')
+execfile(name)
+""")
+
+test.write(['dir4', 'SConscript'], """
+execfile("create_test.py")
+""")
+
+test.write(['dir5', 'SConscript'], """
+import os.path
+name = os.path.join('dir5', 'create_test.py')
+execfile(name)
+""")
+
+for dir in ['dir1', 'dir2', 'dir3','dir4', 'dir5']:
+ test.write([dir, 'create_test.py'], r"""
+f = open("test.txt", "ab")
+f.write("This is the %s test.\n")
+f.close()
+""" % dir)
+
+test.run(arguments=".", stderr=None)
+
+test.fail_test(test.read(['dir1', 'test.txt']) != "This is the dir1 test.\n")
+test.fail_test(test.read(['dir2', 'test.txt']) != "This is the dir2 test.\n")
+test.fail_test(test.read('test.txt') != "This is the dir3 test.\nThis is the dir5 test.\n")
+test.fail_test(test.read(['dir4', 'test.txt']) != "This is the dir4 test.\n")
+
+test.pass_test()
--- /dev/null
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Test calling SConscript through a construction environment.
+"""
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+test.subdir('sub1', 'sub2')
+
+test.write("SConstruct", """\
+env = Environment(SUB1='sub1', SUB2='sub2')
+print "SConstruct"
+x = 'xxx'
+y = 'yyy'
+env.Export(["x", "y"])
+env.SConscript('$SUB1/SConscript')
+env.SConscript(dirs=['$SUB2'])
+SConscript(['s1', 's2'])
+env.SConscript(['s3', 's4'])
+""")
+
+test.write(['sub1', 'SConscript'], """\
+env = Environment()
+env.Import("x")
+print "sub1/SConscript"
+print "x =", x
+""")
+
+test.write(['sub2', 'SConscript'], """\
+env = Environment()
+env.Import("y")
+print "sub2/SConscript"
+print "y =", y
+""")
+
+test.write('s1', "\n")
+test.write('s2', "\n")
+test.write('s3', "\n")
+test.write('s4', "\n")
+
+expect = """\
+SConstruct
+sub1/SConscript
+x = xxx
+sub2/SConscript
+y = yyy
+"""
+
+test.run(arguments = ".",
+ stdout = test.wrap_stdout(read_str = expect,
+ build_str = "scons: `.' is up to date.\n"))
+
+test.write("SConstruct", """\
+def builder(target, source, env):
+ import SCons.Script.SConscript
+ assert SCons.Script.SConscript.sconscript_reading == 0
+env = Environment(BUILDERS={'builder':Builder(action=builder)})
+env.builder('test',[])
+import SCons.Script.SConscript
+assert SCons.Script.SConscript.sconscript_reading == 1
+""")
+
+test.pass_test()
--- /dev/null
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Test that the SConscript() src_dir argument.
+
+Test case contributed by Dobes Vandermeer.
+"""
+
+import TestSCons
+
+_exe = TestSCons._exe
+
+test = TestSCons.TestSCons()
+
+test.subdir(['build'],
+ ['samples'],
+ ['src'])
+
+test.write(['SConstruct'], """\
+env = Environment()
+
+for src_dir in ['src','samples']:
+ SConscript('build/glob_build.py',
+ src_dir=src_dir,
+ build_dir='build/output/'+src_dir,
+ duplicate=0,
+ exports=['env'])
+""")
+
+test.write(['build', 'glob_build.py'], """\
+from glob import glob
+from os.path import join
+from os.path import basename
+Import('env')
+
+sources = map(basename, glob(join(str(env.Dir('.').srcnode()),'*.c')))
+
+# Trivial example; really I read the configuration file
+# their build system uses to generate the vcproj files
+for source in sources:
+ env.Program(source)
+""")
+
+test.write(['samples', 'goodbye.c'], """\
+#include <stdio.h>
+
+int main(int argc, char *argv[])
+{
+ printf("Goodbye, world!\\n");
+ exit(0);
+}
+""")
+
+test.write(['src', 'hello.c'], """\
+#include <stdio.h>
+
+int main(int argc, char *argv[])
+{
+ printf("Hello, world!\\n");
+ exit(0);
+}
+""")
+
+test.run()
+
+goodbye = test.workpath('build', 'output', 'samples', 'goodbye')
+hello = test.workpath('build', 'output', 'src', 'hello')
+
+test.run(program = goodbye, stdout = "Goodbye, world!\n")
+
+test.run(program = hello, stdout = "Hello, world!\n")
+
+test.pass_test()
--- /dev/null
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Test importing and exporting variables between SConscript files.
+"""
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+
+# Test exporting all global variables as a list of keys:
+test.write("SConstruct", """
+x = 'x'
+y = 'zoom'
+Export(globals().keys())
+SConscript('SConscript')
+""")
+
+test.write("SConscript", """
+Import(['x', 'y'])
+assert x == 'x'
+assert y == 'zoom'
+""")
+
+test.run(arguments = ".")
+
+# Test exporting all global variables as a list of keys in SConscript call:
+test.write("SConstruct", """
+x = 'x'
+y = 'zoom'
+SConscript('SConscript', globals().keys())
+""")
+
+test.write("SConscript", """
+Import(['x', 'y'])
+assert x == 'x'
+assert y == 'zoom'
+""")
+
+test.run(arguments = ".")
+
+# Test exporting all global variables as a dictionary:
+test.write("SConstruct", """
+x = 'x'
+y = 'zoom'
+Export(globals())
+SConscript('SConscript')
+""")
+
+test.write("SConscript", """
+Import(['x', 'y'])
+assert x == 'x'
+assert y == 'zoom'
+""")
+
+test.run(arguments = ".")
+
+# Test exporting all global variables as dictionary in SConscript call:
+test.write("SConstruct", """
+x = 'x'
+y = 'zoom'
+SConscript('SConscript', globals())
+""")
+
+test.write("SConscript", """
+Import(['x', 'y'])
+assert x == 'x'
+assert y == 'zoom'
+""")
+
+test.run(arguments = ".")
+
+# Test export of local variables:
+test.write("SConstruct", """
+def f():
+ x = 'x'
+ y = 'zoom'
+ Export('x', 'y')
+
+f()
+SConscript('SConscript')
+""")
+
+test.write("SConscript", """
+Import(['x', 'y'])
+assert x == 'x'
+assert y == 'zoom'
+""")
+
+test.run(arguments = ".")
+
+# Test export of local variables in SConscript call:
+test.write("SConstruct", """
+def f():
+ x = 'x'
+ y = 'zoom'
+ SConscript('SConscript', ['x', 'y'])
+f()
+""")
+
+test.write("SConscript", """
+Import(['x', 'y'])
+assert x == 'x'
+assert y == 'zoom'
+""")
+
+test.run(arguments = ".")
+
+# Test export of local variables as a dictionary:
+test.write("SConstruct", """
+def f():
+ x = 'x'
+ y = 'zoom'
+ Export(locals())
+
+f()
+SConscript('SConscript')
+""")
+
+test.write("SConscript", """
+Import(['x', 'y'])
+assert x == 'x'
+assert y == 'zoom'
+""")
+
+test.run(arguments = ".")
+
+# Test importing all variables:
+test.write("SConstruct", """
+x = 'x'
+y = 'zoom'
+Export('x')
+SConscript('SConscript', 'y')
+""")
+
+test.write("SConscript", """
+Import('*')
+assert x == 'x'
+assert y == 'zoom'
+""")
+
+test.run(arguments = ".")
+
+test.pass_test()
--- /dev/null
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Test handling of white space in an SConscript path name.
+"""
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+test.subdir('white space')
+test.write("SConstruct", """\
+SConscript('white space/SConscript')
+""")
+
+test.write(['white space', 'SConscript'], """\
+print "`white space/SConscript'"
+""")
+
+expect = test.wrap_stdout(read_str = "`white space/SConscript'\n",
+ build_str = "scons: `.' is up to date.\n")
+
+test.run(arguments = ".", stdout = expect)
+
+
+test.pass_test()
import TestSCons
import os.path
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
#
test.write(['work1', 'SConstruct'], """
SConsignFile()
-B = Builder(action = "%s ../build.py $TARGETS $SOURCES")
+B = Builder(action = '%(_python_)s ../build.py $TARGETS $SOURCES')
env = Environment(BUILDERS = { 'B' : B })
env.B(target = 'f1.out', source = 'f1.in')
env.B(target = 'f2.out', source = 'f2.in')
env.B(target = 'subdir/f3.out', source = 'subdir/f3.in')
env.B(target = 'subdir/f4.out', source = 'subdir/f4.in')
-""" % python)
+""" % locals())
test.write(['work1', 'f1.in'], "work1/f1.in\n")
test.write(['work1', 'f2.in'], "work1/f2.in\n")
test.write(['work2', 'SConstruct'], """
e = Environment(XXX = 'scons')
e.SConsignFile('my_${XXX}ign')
-B = Builder(action = "%s ../build.py $TARGETS $SOURCES")
+B = Builder(action = '%(_python_)s ../build.py $TARGETS $SOURCES')
env = Environment(BUILDERS = { 'B' : B })
env.B(target = 'f5.out', source = 'f5.in')
env.B(target = 'f6.out', source = 'f6.in')
env.B(target = 'subdir/f7.out', source = 'subdir/f7.in')
env.B(target = 'subdir/f8.out', source = 'subdir/f8.in')
-""" % python)
+""" % locals())
test.write(['work2', 'f5.in'], "work2/f5.in\n")
test.write(['work2', 'f6.in'], "work2/f6.in\n")
import TestSCons
python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """\
env = Environment(SHELL = r'%(my_shell)s')
-env.Command('file.out', 'file.in', "%(python)s fake_cat_program $TARGET $SOURCES")
+env.Command('file.out', 'file.in',
+ 'r%(_python_)s fake_cat_program $TARGET $SOURCES')
""" % locals())
test.write('file.in', "file.in\n")
""")
test.write('foo.c', r"""
+#include <stdio.h>
void
foo(void)
{
""")
test.write('foo.c', r"""
+#include <stdio.h>
void
foo(void)
{
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
import os
import string
+import sys
def my_spawn(sh, escape, cmd, args, env):
- os.system(string.join(args + ['extra.txt']))
+ s = string.join(args + ['extra.txt'])
+ if sys.platform in ['win32']:
+ s = '"' + s + '"'
+ os.system(s)
env = Environment(SPAWN = my_spawn)
-env.Command('file.out', 'file.in', "%(python)s cat.py $TARGET $SOURCES")
+env.Command('file.out', 'file.in', '%(_python_)s cat.py $TARGET $SOURCES')
env = Environment()
""" % locals())
# so we link to a framework version. However, testing must also
# use the same version, or else you get interpreter errors.
python = "/System/Library/Frameworks/Python.framework/Versions/Current/bin/python"
+ _python_ = '"' + python + '"'
else:
python = TestSCons.python
+ _python_ = TestSCons._python_
_exe = TestSCons._exe
_obj = TestSCons._obj
""")
test.write('SConstruct', """
-env = Environment(tools=['default', 'swig'], SWIG = r'%s myswig.py')
+env = Environment(tools=['default', 'swig'], SWIG = r'%(_python_)s myswig.py')
env.Program(target = 'test1', source = 'test1.i')
env.CFile(target = 'test2', source = 'test2.i')
env.Copy(SWIGFLAGS = '-c++').Program(target = 'test3', source = 'test3.i')
-""" % (python))
+""" % locals())
test.write('test1.i', r"""
int
test.write('SConstruct', """
foo = Environment(SWIGFLAGS='-python',
CPPPATH='%(platform_sys_prefix)s/include/python%(version)s/',
- SHCCFLAGS='',
LDMODULEPREFIX='%(ldmodule_prefix)s',
LDMODULESUFFIX='%(_dll)s',
FRAMEWORKSFLAGS='%(frameworks)s',
)
swig = foo.Dictionary('SWIG')
-bar = foo.Copy(SWIG = r'%(python)s wrapper.py ' + swig)
+bar = foo.Copy(SWIG = r'%(_python_)s wrapper.py ' + swig)
foo.LoadableModule(target = 'foo', source = ['foo.c', 'foo.i'])
bar.LoadableModule(target = 'bar', source = ['bar.c', 'bar.i'])
""" % locals())
test.write('SConstruct', """
foo = Environment(SWIGFLAGS='-python',
CPPPATH='%(platform_sys_prefix)s/include/python%(version)s/',
- SHCCFLAGS='',
LDMODULEPREFIX='%(ldmodule_prefix)s',
LDMODULESUFFIX='%(_dll)s',
FRAMEWORKSFLAGS='%(frameworks)s',
test.write('SConstruct', """
foo = Environment(SWIGFLAGS='-python',
CPPPATH='%(platform_sys_prefix)s/include/python%(version)s/',
- SHCCFLAGS='',
LDMODULEPREFIX='%(ldmodule_prefix)s',
LDMODULESUFFIX='%(_dll)s',
FRAMEWORKSFLAGS='%(frameworks)s',
)
swig = foo.Dictionary('SWIG')
-bar = foo.Copy(SWIG = r'%(python)s wrapper.py ' + swig)
+bar = foo.Copy(SWIG = r'%(_python_)s wrapper.py ' + swig)
foo.CFile(target = 'dependent', source = ['dependent.i'])
""" % locals())
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(tools=['default', 'swig'],
- SWIGCOM = r'%s myswig.py $TARGET $SOURCES')
+ SWIGCOM = r'%(_python_)s myswig.py $TARGET $SOURCES')
env.CFile(target = 'aaa', source = 'aaa.i')
env.CXXFile(target = 'bbb', source = 'bbb.i', SWIGFLAGS='-c++')
-""" % python)
+""" % locals())
test.write('aaa.i', "aaa.i\n/*swig*/\n")
test.write('bbb.i', "bbb.i\n/*swig*/\n")
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(tools=['default', 'swig'],
- SWIGCOM = r'%s myswig.py $TARGET $SOURCES',
+ SWIGCOM = r'%(_python_)s myswig.py $TARGET $SOURCES',
SWIGCOMSTR = 'Swigging $TARGET from $SOURCE')
env.CFile(target = 'aaa', source = 'aaa.i')
env.CXXFile(target = 'bbb', source = 'bbb.i', SWIGFLAGS='-c++')
-""" % python)
+""" % locals())
test.write('aaa.i', "aaa.i\n/*swig*/\n")
test.write('bbb.i', "bbb.i\n/*swig*/\n")
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
-import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
env = Environment()
env.Append(SCANNERS = kscan)
-env.Command('foo', 'foo.k', r'%(python)s build.py $SOURCES $TARGET')
+env.Command('foo', 'foo.k', r'%(_python_)s build.py $SOURCES $TARGET')
##########################################################
# Test resetting the environment scanners (and specifying as a list).
env2 = env.Copy()
env2.Append(SCANNERS = [k2scan])
-env2.Command('junk', 'junk.k2', r'%(python)s build.py $SOURCES $TARGET')
+env2.Command('junk', 'junk.k2', r'%(_python_)s build.py $SOURCES $TARGET')
##########################################################
# Test specifying a specific source scanner for a target Node
-barbld = Builder(action=r'%(python)s build.py $SOURCES $TARGET',
+barbld = Builder(action=r'%(_python_)s build.py $SOURCES $TARGET',
source_scanner=kscan)
env.Append(BUILDERS={'BarBld':barbld})
bar = env.BarBld(target='bar', source='bar.in')
open(str(target[0]), 'wb').write(
string.replace(source[0].get_contents(), 'getfile', 'MISSEDME'))
-kbld = Builder(action=r'%(python)s build.py $SOURCES $TARGET',
+kbld = Builder(action=r'%(_python_)s build.py $SOURCES $TARGET',
src_suffix='.lork',
suffix='.blork',
source_scanner=kscan)
ork = env.BLORK(blork)
Alias('make_ork', ork)
-""" % {'python': python})
+""" % locals())
test.write('foo.k',
"""foo.k 1 line 1
test.write('yyy', "yyy 1\n")
test.write('zzz', "zzz 1\n")
-test.run(arguments = '.',
- stdout=test.wrap_stdout("""\
-%(python)s build.py bar.in bar
-%(python)s build.py foo.k foo
-%(python)s build.py junk.k2 junk
-%(python)s build.py moo.lork moo.blork
+expect = test.wrap_stdout("""\
+%(_python_)s build.py bar.in bar
+%(_python_)s build.py foo.k foo
+%(_python_)s build.py junk.k2 junk
+%(_python_)s build.py moo.lork moo.blork
blork(["moo.ork"], ["moo.blork"])
-""" % {'python':python}))
+""" % locals())
+
+test.run(arguments = '.', stdout=expect)
test.must_match('foo', "foo.k 1 line 1\nxxx 1\nyyy 1\nfoo.k 1 line 4\n")
test.must_match('bar', "yyy 1\nbar.in 1 line 2\nbar.in 1 line 3\nzzz 1\n")
test.write('xxx', "xxx 2\n")
-test.run(arguments = '.',
- stdout=test.wrap_stdout("""\
-%(python)s build.py foo.k foo
-%(python)s build.py moo.lork moo.blork
+expect = test.wrap_stdout("""\
+%(_python_)s build.py foo.k foo
+%(_python_)s build.py moo.lork moo.blork
blork(["moo.ork"], ["moo.blork"])
-""" % {'python':python}))
+""" % locals())
+
+test.run(arguments = '.', stdout=expect)
test.must_match('foo', "foo.k 1 line 1\nxxx 2\nyyy 1\nfoo.k 1 line 4\n")
test.must_match('bar', "yyy 1\nbar.in 1 line 2\nbar.in 1 line 3\nzzz 1\n")
test.write('yyy', "yyy 2\n")
-test.run(arguments = '.',
- stdout=test.wrap_stdout("""\
-%(python)s build.py bar.in bar
-%(python)s build.py foo.k foo
-%(python)s build.py junk.k2 junk
-%(python)s build.py moo.lork moo.blork
+expect = test.wrap_stdout("""\
+%(_python_)s build.py bar.in bar
+%(_python_)s build.py foo.k foo
+%(_python_)s build.py junk.k2 junk
+%(_python_)s build.py moo.lork moo.blork
blork(["moo.ork"], ["moo.blork"])
-""" % {'python':python}))
+""" % locals())
+
+test.run(arguments = '.', stdout=expect)
test.must_match('foo', "foo.k 1 line 1\nxxx 2\nyyy 2\nfoo.k 1 line 4\n")
test.must_match('bar', "yyy 2\nbar.in 1 line 2\nbar.in 1 line 3\nzzz 1\n")
test.write('zzz', "zzz 2\n")
-test.run(arguments = '.',
- stdout=test.wrap_stdout("""\
-%(python)s build.py bar.in bar
-%(python)s build.py junk.k2 junk
-""" % {'python':python}))
+expect = test.wrap_stdout("""\
+%(_python_)s build.py bar.in bar
+%(_python_)s build.py junk.k2 junk
+""" % locals())
+
+test.run(arguments = '.', stdout=expect)
test.must_match('foo', "foo.k 1 line 1\nxxx 2\nyyy 2\nfoo.k 1 line 4\n")
test.must_match('bar', "yyy 2\nbar.in 1 line 2\nbar.in 1 line 3\nzzz 2\n")
test.up_to_date(arguments = 'foo')
-# Now make sure that using the same source file in different
-# environments will get the proper scanner for the environment being
-# used.
-
-test.write('SConstruct2', """
-import re
-
-include_re = re.compile(r'^include\s+(\S+)$', re.M)
-input_re = re.compile(r'^input\s+(\S+)$', re.M)
-
-scan1 = Scanner(name = 'Include',
- function = lambda N,E,P,A: A.findall(N.get_contents()),
- argument = include_re,
- skeys = ['.inp'])
-
-scan2 = Scanner(name = 'Input',
- function = lambda N,E,P,A: A.findall(N.get_contents()),
- argument = input_re,
- skeys = ['.inp'])
-
-env1 = Environment()
-env2 = Environment()
-
-env1.Append(SCANNERS=scan1)
-env2.Append(SCANNERS=scan2)
-
-env1.Command('frog.1', 'frog.inp', r'%(python)s do_incl.py $TARGET $SOURCES')
-env2.Command('frog.2', 'frog.inp', r'%(python)s do_inp.py $TARGET $SOURCES')
-
-"""%{'python':python})
-
-process = r"""
-import sys
-
-def process(infp, outfp):
- prefix = '%(command)s '
- l = len(prefix)
- for line in infp.readlines():
- if line[:l] == prefix:
- process(open(line[l:-1], 'rb'), outfp)
- else:
- outfp.write(line)
-
-process(open(sys.argv[2], 'rb'),
- open(sys.argv[1], 'wb'))
-sys.exit(0)
-"""
-
-test.write('do_incl.py', process % { 'command' : 'include' })
-test.write('do_inp.py', process % { 'command' : 'input' })
-
-test.write('frog.inp', """\
-include sound1
-input sound2
-""")
-
-test.write('sound1', 'croak\n')
-test.write('sound2', 'ribbet\n')
-
-test.run(arguments='-f SConstruct2 .',
-stdout=test.wrap_stdout("""\
-%(python)s do_incl.py frog.1 frog.inp
-%(python)s do_inp.py frog.2 frog.inp
-""" % { 'python':python }))
-
-test.must_match('frog.1', 'croak\ninput sound2\n')
-test.must_match('frog.2', 'include sound1\nribbet\n')
-
-test.write('sound2', 'rudeep\n')
-
-test.run(arguments='-f SConstruct2 .',
-stdout=test.wrap_stdout("""\
-%(python)s do_inp.py frog.2 frog.inp
-""" % { 'python':python }))
-
-test.must_match('frog.1', 'croak\ninput sound2\n')
-test.must_match('frog.2', 'include sound1\nrudeep\n')
-
test.pass_test()
--- /dev/null
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Verify that Scanners are not called if a previous --implicit-cache
+run stored an empty list of implicit dependencies.
+"""
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+test.write('SConstruct', r"""
+import os.path
+
+def scan(node, env, envkey, arg):
+ print 'XScanner: node =', os.path.split(str(node))[1]
+ return []
+
+def exists_check(node, env):
+ return os.path.exists(str(node))
+
+XScanner = Scanner(name = 'XScanner',
+ function = scan,
+ argument = None,
+ scan_check = exists_check,
+ skeys = ['.x'])
+
+def echo(env, target, source):
+ t = os.path.split(str(target[0]))[1]
+ s = os.path.split(str(source[0]))[1]
+ print 'create %s from %s' % (t, s)
+ open(t, 'wb').write(open(s, 'rb').read())
+
+Echo = Builder(action = Action(echo, None),
+ src_suffix = '.x',
+ suffix = '.x')
+
+env = Environment(BUILDERS = {'Echo':Echo}, SCANNERS = [XScanner])
+
+f1 = env.Echo(source=['f1_in'], target=['f1_out'])
+""")
+
+test.write('f1_in.x', 'f1_in.x\n')
+
+expect = test.wrap_stdout("""\
+XScanner: node = f1_in.x
+create f1_out.x from f1_in.x
+""")
+
+test.run(arguments = '--implicit-cache .', stdout = expect)
+
+# Run it again, and the output must contain only the "up to date" message,
+# *not* the line printed by the XScanner function.
+
+test.up_to_date(options = '--implicit-cache', arguments = '.')
+
+test.pass_test()
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-"""
-This test verifies that Scanners are called just once.
-
-This is actually a shotgun marriage of two separate tests, the simple
-test originally created for this, plus a more complicated test based
-on a real-life bug report submitted by Scott Lystig Fritchie. Both
-have value: the simple test will be easier to debug if there are basic
-scanning problems, while Scott's test has a lot of cool real-world
-complexity that is valuable in its own right, including scanning of
-generated .h files.
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
"""
+Verify that we only scan generated .h files once.
-__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+This originated as a real-life bug report submitted by Scott Lystig
+Fritchie. It's been left as-is, rather than stripped down to bear
+minimum, partly because it wasn't completely clear what combination of
+factors triggered the bug Scott saw, and partly because the real-world
+complexity is valuable in its own right.
+"""
import os.path
import sys
test = TestSCons.TestSCons()
-test.subdir('simple',
- 'SLF',
- ['SLF', 'reftree'], ['SLF', 'reftree', 'include'],
- ['SLF', 'src'], ['SLF', 'src', 'lib_geng'])
+test.subdir('reftree',
+ ['reftree', 'include'],
+ 'src',
+ ['src', 'lib_geng'])
test.write('SConstruct', """\
-SConscript('simple/SConscript')
-SConscript('SLF/SConscript')
-""")
-
-test.write(['simple', 'SConscript'], r"""
-import os.path
-
-def scan(node, env, envkey, arg):
- print 'XScanner: node =', os.path.split(str(node))[1]
- return []
-
-def exists_check(node, env):
- return os.path.exists(str(node))
-
-XScanner = Scanner(name = 'XScanner',
- function = scan,
- argument = None,
- scan_check = exists_check,
- skeys = ['.x'])
-
-def echo(env, target, source):
- t = os.path.split(str(target[0]))[1]
- s = os.path.split(str(source[0]))[1]
- print 'create %s from %s' % (t, s)
-
-Echo = Builder(action = Action(echo, None),
- src_suffix = '.x',
- suffix = '.x')
-
-env = Environment(BUILDERS = {'Echo':Echo}, SCANNERS = [XScanner])
-
-f1 = env.Echo(source=['file1'], target=['file2'])
-f2 = env.Echo(source=['file2'], target=['file3'])
-f3 = env.Echo(source=['file3'], target=['file4'])
-""")
-
-test.write(['simple', 'file1.x'], 'simple/file1.x\n')
-
-test.write(['SLF', 'SConscript'], """\
###
### QQQ !@#$!@#$! I need to move the SConstruct file to be "above"
### both the source and install dirs, or the install dependencies
env.Append(LIBPATH = [e["REF_LIB"]])
Mylib.Subdirs(env, "src")
-""" % test.workpath('SLF'))
+""" % test.workpath())
-test.write(['SLF', 'Mylib.py'], """\
+test.write('Mylib.py', """\
import os
import string
import re
""")
-test.write(['SLF', 'reftree', 'include', 'lib_a.h'], """\
+test.write(['reftree', 'include', 'lib_a.h'], """\
char *a_letter(void);
""")
-test.write(['SLF', 'reftree', 'include', 'lib_b.h'], """\
+test.write(['reftree', 'include', 'lib_b.h'], """\
char *b_letter(void);
""")
-test.write(['SLF', 'reftree', 'include', 'lib_ja.h'], """\
+test.write(['reftree', 'include', 'lib_ja.h'], """\
char *j_letter_a(void);
""")
-test.write(['SLF', 'reftree', 'include', 'lib_jb.h.intentionally-moved'], """\
+test.write(['reftree', 'include', 'lib_jb.h.intentionally-moved'], """\
char *j_letter_b(void);
""")
-test.write(['SLF', 'src', 'SConscript'], """\
+test.write(['src', 'SConscript'], """\
# --- Begin SConscript boilerplate ---
import Mylib
Import("env")
""")
-test.write(['SLF', 'src', 'lib_geng', 'SConscript'], """\
+test.write(['src', 'lib_geng', 'SConscript'], """\
# --- Begin SConscript boilerplate ---
import string
import sys
Mylib.AddCFlags(env, "-DGOOFY_DEMO")
Mylib.AddIncludeDirs(env, ".")
-# Not part of SLF's original stuff: On Windows, it's import to use the
-# original test environment when we invoke SCons recursively.
+# Not part of Scott Lystig Fritchies's original stuff:
+# On Windows, it's import to use the original test environment
+# when we invoke SCons recursively.
import os
recurse_env = env.Copy()
recurse_env["ENV"] = os.environ
Mylib.ExportHeader(env, exported_hdrs)
Mylib.ExportLib(env, lib_fullname)
-# The following were the original commands from SLF, making use of
-# a shell script and a Makefile to build the library. These have
-# been preserved, commented out below, but in order to make this
-# test portable, we've replaced them with a Python script and a
+# The following were the original commands from Scott Lystic Fritchie,
+# making use of a shell script and a Makefile to build the library.
+# These have been preserved, commented out below, but in order to make
+# this test portable, we've replaced them with a Python script and a
# recursive invocation of SCons (!).
#cmd_both = "cd %s ; make generated ; make" % Dir(".")
#cmd_generated = "cd %s ; sh MAKE-HEADER.sh" % Dir(".")
s = '"' + s + '"'
return s
-cmd_generated = "%s $SOURCE" % (escape(sys.executable),)
-cmd_justlib = "%s %s -C ${SOURCES[0].dir}" % ((sys.executable),
+cmd_generated = "%s $SOURCE" % escape(sys.executable)
+cmd_justlib = "%s %s -C ${SOURCES[0].dir}" % (escape(sys.executable),
escape(sys.argv[0]))
##### Deps appear correct ... but wacky scanning?
cmd_justlib)
""")
-test.write(['SLF', 'src', 'lib_geng', 'MAKE-HEADER.py'], """\
+test.write(['src', 'lib_geng', 'MAKE-HEADER.py'], """\
#!/usr/bin/env python
import os
open(h, 'w').write('')
""")
-test.write(['SLF', 'src', 'lib_geng', 'SConstruct'], """\
+test.write(['src', 'lib_geng', 'SConstruct'], """\
import os
Scanned = {}
# bug report. We're not using them--in order to make this script as
# portable as possible, we're using a Python script and a recursive
# invocation of SCons--but we're preserving them here for history.
-#test.write(['SLF', 'src', 'lib_geng', 'MAKE-HEADER.sh'], """\
+#test.write(['src', 'lib_geng', 'MAKE-HEADER.sh'], """\
##!/bin/sh
#
#exec touch $*
#""")
#
-#test.write(['SLF', 'src', 'lib_geng', 'Makefile'], """\
+#test.write(['src', 'lib_geng', 'Makefile'], """\
#all: libg.a
#
#GEN_HDRS = libg_gx.h libg_gy.h libg_gz.h
# -rm -f libg.a *.o core core.*
#""")
-test.write(['SLF', 'src', 'lib_geng', 'libg_w.h'], """\
+test.write(['src', 'lib_geng', 'libg_w.h'], """\
""")
-test.write(['SLF', 'src', 'lib_geng', 'libg_1.c'], """\
+test.write(['src', 'lib_geng', 'libg_1.c'], """\
#include <libg_w.h>
#include <libg_gx.h>
}
""")
-test.write(['SLF', 'src', 'lib_geng', 'libg_2.c'], """\
+test.write(['src', 'lib_geng', 'libg_2.c'], """\
#include <libg_w.h>
#include <libg_gx.h>
#include <libg_gy.h>
}
""")
-test.write(['SLF', 'src', 'lib_geng', 'libg_3.c'], """\
+test.write(['src', 'lib_geng', 'libg_3.c'], """\
#include <libg_w.h>
#include <libg_gx.h>
}
""")
-test.run(arguments = 'simple',
- stdout = test.wrap_stdout("""\
-XScanner: node = file1.x
-create file2.x from file1.x
-create file3.x from file2.x
-create file4.x from file3.x
-"""))
-
-test.write(['simple', 'file2.x'], 'simple/file2.x\n')
-
-test.run(arguments = 'simple',
- stdout = test.wrap_stdout("""\
-XScanner: node = file1.x
-XScanner: node = file2.x
-create file3.x from file2.x
-create file4.x from file3.x
-"""))
-
-test.write(['simple', 'file3.x'], 'simple/file3.x\n')
-
-test.run(arguments = 'simple',
- stdout = test.wrap_stdout("""\
-XScanner: node = file1.x
-XScanner: node = file2.x
-XScanner: node = file3.x
-create file4.x from file3.x
-"""))
-
-test.run(arguments = 'SLF',
- stderr=TestSCons.noisy_ar,
+test.run(stderr=TestSCons.noisy_ar,
match=TestSCons.match_re_dotall)
# XXX Note that the generated .h files still get scanned twice,
--- /dev/null
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+
+"""
+Verifies that using the same source file in different environments
+will get the proper scanner for the environment being used.
+"""
+
+import TestSCons
+
+_python_ = TestSCons._python_
+
+test = TestSCons.TestSCons()
+
+
+test.write('SConstruct', """
+import re
+
+include_re = re.compile(r'^include\s+(\S+)$', re.M)
+input_re = re.compile(r'^input\s+(\S+)$', re.M)
+
+scan1 = Scanner(name = 'Include',
+ function = lambda N,E,P,A: A.findall(N.get_contents()),
+ argument = include_re,
+ skeys = ['.inp'])
+
+scan2 = Scanner(name = 'Input',
+ function = lambda N,E,P,A: A.findall(N.get_contents()),
+ argument = input_re,
+ skeys = ['.inp'])
+
+env1 = Environment()
+env2 = Environment()
+
+env1.Append(SCANNERS=scan1)
+env2.Append(SCANNERS=scan2)
+
+env1.Command('frog.1', 'frog.inp', r'%(_python_)s do_incl.py $TARGET $SOURCES')
+env2.Command('frog.2', 'frog.inp', r'%(_python_)s do_inp.py $TARGET $SOURCES')
+
+""" % locals())
+
+process = r"""
+import sys
+
+def process(infp, outfp):
+ prefix = '%(command)s '
+ l = len(prefix)
+ for line in infp.readlines():
+ if line[:l] == prefix:
+ process(open(line[l:-1], 'rb'), outfp)
+ else:
+ outfp.write(line)
+
+process(open(sys.argv[2], 'rb'),
+ open(sys.argv[1], 'wb'))
+sys.exit(0)
+"""
+
+test.write('do_incl.py', process % { 'command' : 'include' })
+test.write('do_inp.py', process % { 'command' : 'input' })
+
+test.write('frog.inp', """\
+include sound1
+input sound2
+""")
+
+test.write('sound1', 'croak\n')
+test.write('sound2', 'ribbet\n')
+
+expect = test.wrap_stdout("""\
+%(_python_)s do_incl.py frog.1 frog.inp
+%(_python_)s do_inp.py frog.2 frog.inp
+""" % locals())
+
+test.run(arguments='.', stdout=expect)
+
+test.must_match('frog.1', 'croak\ninput sound2\n')
+test.must_match('frog.2', 'include sound1\nribbet\n')
+
+test.write('sound2', 'rudeep\n')
+
+expect = test.wrap_stdout("""\
+%(_python_)s do_inp.py frog.2 frog.inp
+""" % locals())
+
+test.run(arguments='.', stdout=expect)
+
+test.must_match('frog.1', 'croak\ninput sound2\n')
+test.must_match('frog.2', 'include sound1\nrudeep\n')
+
+test.pass_test()
--- /dev/null
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Verify that Scanners are called just once.
+"""
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+test.write('SConstruct', r"""
+import os.path
+
+def scan(node, env, envkey, arg):
+ print 'XScanner: node =', os.path.split(str(node))[1]
+ return []
+
+def exists_check(node, env):
+ return os.path.exists(str(node))
+
+XScanner = Scanner(name = 'XScanner',
+ function = scan,
+ argument = None,
+ scan_check = exists_check,
+ skeys = ['.x'])
+
+def echo(env, target, source):
+ t = os.path.split(str(target[0]))[1]
+ s = os.path.split(str(source[0]))[1]
+ print 'create %s from %s' % (t, s)
+
+Echo = Builder(action = Action(echo, None),
+ src_suffix = '.x',
+ suffix = '.x')
+
+env = Environment(BUILDERS = {'Echo':Echo}, SCANNERS = [XScanner])
+
+f1 = env.Echo(source=['file1'], target=['file2'])
+f2 = env.Echo(source=['file2'], target=['file3'])
+f3 = env.Echo(source=['file3'], target=['file4'])
+""")
+
+test.write('file1.x', 'file1.x\n')
+
+test.run(stdout = test.wrap_stdout("""\
+XScanner: node = file1.x
+create file2.x from file1.x
+create file3.x from file2.x
+create file4.x from file3.x
+"""))
+
+test.write('file2.x', 'file2.x\n')
+
+test.run(stdout = test.wrap_stdout("""\
+XScanner: node = file1.x
+XScanner: node = file2.x
+create file3.x from file2.x
+create file4.x from file3.x
+"""))
+
+test.write('file3.x', 'file3.x\n')
+
+test.run(stdout = test.wrap_stdout("""\
+XScanner: node = file1.x
+XScanner: node = file2.x
+XScanner: node = file3.x
+create file4.x from file3.x
+"""))
+
+test.pass_test()
""")
test.write('f2a.c', r"""
+#include <stdio.h>
+
void
f2a(void)
{
""")
test.write('f2b.c', r"""
+#include <stdio.h>
void
f2b(void)
{
""")
test.write('f3a.c', r"""
+#include <stdio.h>
void
f3a(void)
{
""")
test.write('f3b.c', r"""
+#include <stdio.h>
void
f3b(void)
{
""")
test.write('prog.c', r"""
+#include <stdio.h>
void f1(void);
void f2a(void);
void f2b(void);
""")
test.write('progbar.c', r"""
+#include <stdio.h>
void f4(void);
int
main(int argc, char *argv[])
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-env = Environment(tools = ['tar'], TAR = r'%s mytar.py')
+env = Environment(tools = ['tar'], TAR = r'%(_python_)s mytar.py')
env.Tar(target = 'aaa.tar', source = ['file1', 'file2'])
env.Tar(target = 'aaa.tar', source = 'file3')
env.Tar(target = 'bbb', source = 'sub1')
env.Tar(target = 'bbb', source = 'file4')
-""" % python)
+""" % locals())
test.write('file1', "file1\n")
test.write('file2', "file2\n")
test.write('SConstruct', """
foo = Environment()
tar = foo.Dictionary('TAR')
-bar = Environment(TAR = r'%s wrapper.py ' + tar)
+bar = Environment(TAR = r'%(_python_)s wrapper.py ' + tar)
f3 = Environment(TARFLAGS = '-c -z', TARSUFFIX = '.tar.gz')
f4 = Environment(TARFLAGS = '-c -z', TARSUFFIX = '.tgz')
f5 = Environment(TARFLAGS = '-c -z')
f4.Tar(target = 'f4', source = ['file20', 'file21'])
f5.Tar(target = 'f5.tgz', source = 'file22')
f5.Tar(target = 'f5.tgz', source = ['file23', 'file24'])
-""" % python)
+""" % locals())
for f in ['file10', 'file11', 'file12',
'file13', 'file14', 'file15',
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(TOOLS = ['tar'],
- TARCOM = r'%(python)s mytar.py $TARGET $SOURCE')
+ TARCOM = r'%(_python_)s mytar.py $TARGET $SOURCE')
env.Tar('test1.tar', 'test1.in')
""" % locals())
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(tools=['tar'],
- TARCOM = r'%s mytar.py $TARGET $SOURCES',
+ TARCOM = r'%(_python_)s mytar.py $TARGET $SOURCES',
TARCOMSTR = 'Taring $TARGET from $SOURCE')
env.Tar('aaa.tar', 'aaa.in')
-""" % python)
+""" % locals())
test.write('aaa.in', "aaa.in\n/*tar*/\n")
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-env = Environment(tools = ['tar'], TAR = r'%s mytar.py', TARFLAGS = '-x')
+env = Environment(tools = ['tar'],
+ TAR = r'%(_python_)s mytar.py',
+ TARFLAGS = '-x')
env.Tar(target = 'aaa.tar', source = ['file1', 'file2'])
env.Tar(target = 'aaa.tar', source = 'file3')
env.Tar(target = 'bbb', source = 'sub1')
env.Tar(target = 'bbb', source = 'file4')
-""" % python)
+""" % locals())
test.write('file1', "file1\n")
test.write('file2', "file2\n")
foo = Environment()
tar = foo['TAR']
bar = Environment(TAR = '',
- TARFLAGS = r'%s wrapper.py ' + tar + ' -c -b 1')
+ TARFLAGS = r'%(_python_)s wrapper.py ' + tar + ' -c -b 1')
foo.Tar(target = 'foo.tar', source = ['file10', 'file11'])
foo.Tar(target = 'foo.tar', source = 'file12')
bar.Tar(target = 'bar.tar', source = ['file13', 'file14'])
bar.Tar(target = 'bar.tar', source = 'file15')
-""" % python)
+""" % locals())
test.write('file10', "file10\n")
test.write('file11', "file11\n")
""")
test.write(['src', 'foo.c'], """\
+#include <stdio.h>
+#include <stdlib.h>
+
#include <foo.h>
int
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-env = Environment(LATEX = r'%s mylatex.py', tools=['latex'])
+env = Environment(LATEX = r'%(_python_)s mylatex.py', tools=['latex'])
env.DVI(target = 'test1.dvi', source = 'test1.ltx')
env.DVI(target = 'test2.dvi', source = 'test2.latex')
-""" % python)
+""" % locals())
test.write('test1.ltx', r"""This is a .ltx test.
\end
latex = foo.Dictionary('LATEX')
makeindex = foo.Dictionary('MAKEINDEX')
bar = Environment(ENV = ENV,
- LATEX = r'%s wrapper.py ' + latex,
+ LATEX = r'%(_python_)s wrapper.py ' + latex,
MAKEINDEX = r' wrapper.py ' + makeindex)
foo.DVI(target = 'foo.dvi', source = 'foo.ltx')
bar.DVI(target = 'bar', source = 'bar.latex')
bar.DVI(target = 'makeindex', source = 'makeindex.tex')
foo.DVI(target = 'latexi', source = 'latexi.tex')
-""" % python)
+""" % locals())
latex = r"""
\documentclass{letter}
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(TOOLS = ['latex'],
- LATEXCOM = r'%(python)s mylatex.py $TARGET $SOURCE')
+ LATEXCOM = r'%(_python_)s mylatex.py $TARGET $SOURCE')
env.DVI('test1', 'test1.latex')
""" % locals())
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(TOOLS = ['latex'],
- LATEXCOM = r'%(python)s mylatex.py $TARGET $SOURCE',
+ LATEXCOM = r'%(_python_)s mylatex.py $TARGET $SOURCE',
LATEXCOMSTR = 'Building $TARGET from $SOURCE')
env.DVI('test1', 'test1.latex')
""" % locals())
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-env = Environment(LATEX = r'%s mylatex.py', LATEXFLAGS = '-x', tools=['latex'])
+env = Environment(LATEX = r'%(_python_)s mylatex.py',
+ LATEXFLAGS = '-x',
+ tools=['latex'])
env.DVI(target = 'test1.dvi', source = 'test1.ltx')
env.Copy(LATEXFLAGS = '-t').DVI(target = 'test2.dvi', source = 'test2.latex')
-""" % python)
+""" % locals())
test.write('test1.ltx', r"""This is a .ltx test.
\end
ENV = { 'PATH' : os.environ['PATH'] }
foo = Environment(ENV = ENV, LATEXFLAGS = '--output-comment Commentary')
latex = foo.Dictionary('LATEX')
-bar = Environment(ENV = ENV, LATEX = r'%s wrapper.py ' + latex)
+bar = Environment(ENV = ENV, LATEX = r'%(_python_)s wrapper.py ' + latex)
foo.DVI(target = 'foo.dvi', source = 'foo.ltx')
bar.DVI(target = 'bar', source = 'bar.latex')
-""" % python)
+""" % locals())
latex = r"""
\documentclass{letter}
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-env = Environment(PDFLATEX = r'%s mypdflatex.py', tools=['pdflatex'])
+env = Environment(PDFLATEX = r'%(_python_)s mypdflatex.py', tools=['pdflatex'])
env.PDF(target = 'test1.pdf', source = 'test1.ltx')
env.PDF(target = 'test2.pdf', source = 'test2.latex')
-""" % python)
+""" % locals())
test.write('test1.ltx', r"""This is a .ltx test.
\end
ENV = { 'PATH' : os.environ['PATH'] }
foo = Environment(ENV = ENV)
pdflatex = foo.Dictionary('PDFLATEX')
-bar = Environment(ENV = ENV, PDFLATEX = r'%s wrapper.py ' + pdflatex)
+bar = Environment(ENV = ENV, PDFLATEX = r'%(_python_)s wrapper.py ' + pdflatex)
foo.PDF(target = 'foo.pdf', source = 'foo.ltx')
bar.PDF(target = 'bar', source = 'bar.latex')
-""" % python)
+""" % locals())
latex = r"""
\documentclass{letter}
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(TOOLS = ['pdflatex'],
- PDFLATEXCOM = r'%(python)s mypdflatex.py $TARGET $SOURCE')
+ PDFLATEXCOM = r'%(_python_)s mypdflatex.py $TARGET $SOURCE')
env.PDF('test1', 'test1.latex')
""" % locals())
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(TOOLS = ['pdflatex'],
- PDFLATEXCOM = r'%(python)s mypdflatex.py $TARGET $SOURCE',
+ PDFLATEXCOM = r'%(_python_)s mypdflatex.py $TARGET $SOURCE',
PDFLATEXCOMSTR = 'Building $TARGET from $SOURCE')
env.PDF('test1', 'test1.latex')
""" % locals())
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-env = Environment(PDFLATEX = r'%s mypdflatex.py', PDFLATEXFLAGS = '-x', tools=['pdflatex'])
+env = Environment(PDFLATEX = r'%(_python_)s mypdflatex.py',
+ PDFLATEXFLAGS = '-x',
+ tools=['pdflatex'])
env.PDF(target = 'test1.pdf', source = 'test1.ltx')
env.Copy(PDFLATEXFLAGS = '-t').PDF(target = 'test2.pdf', source = 'test2.latex')
-""" % python)
+""" % locals())
test.write('test1.ltx', r"""This is a .ltx test.
\end
ENV = { 'PATH' : os.environ['PATH'] }
foo = Environment(ENV = ENV, PDFLATEXFLAGS = '--output-comment Commentary')
pdflatex = foo.Dictionary('PDFLATEX')
-bar = Environment(ENV = ENV, PDFLATEX = r'%s wrapper.py ' + pdflatex)
+bar = Environment(ENV = ENV, PDFLATEX = r'%(_python_)s wrapper.py ' + pdflatex)
foo.PDF(target = 'foo.pdf', source = 'foo.ltx')
bar.PDF(target = 'bar', source = 'bar.latex')
-""" % python)
+""" % locals())
latex = r"""
\documentclass{letter}
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-env = Environment(PDFTEX = r'%s mypdftex.py', tools=['pdftex'])
+env = Environment(PDFTEX = r'%(_python_)s mypdftex.py', tools=['pdftex'])
env.PDF(target = 'test.pdf', source = 'test.tex')
-""" % python)
+""" % locals())
test.write('test.tex', r"""This is a test.
\end
ENV = { 'PATH' : os.environ['PATH'] }
foo = Environment(ENV = ENV)
pdftex = foo.Dictionary('PDFTEX')
-bar = Environment(ENV = ENV, PDFTEX = r'%s wrapper.py ' + pdftex)
+bar = Environment(ENV = ENV, PDFTEX = r'%(_python_)s wrapper.py ' + pdftex)
foo.PDF(target = 'foo.pdf', source = 'foo.tex')
bar.PDF(target = 'bar', source = 'bar.tex')
-""" % python)
+""" % locals())
tex = r"""
This is the %s TeX file.
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(TOOLS = ['pdftex'],
- PDFTEXCOM = r'%(python)s mypdftex.py $TARGET $SOURCE')
+ PDFTEXCOM = r'%(_python_)s mypdftex.py $TARGET $SOURCE')
env.PDF('test1')
""" % locals())
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(TOOLS = ['pdftex'],
- PDFTEXCOM = r'%(python)s mypdftex.py $TARGET $SOURCE',
+ PDFTEXCOM = r'%(_python_)s mypdftex.py $TARGET $SOURCE',
PDFTEXCOMSTR = 'Building $TARGET from $SOURCE')
env.PDF('test1')
""" % locals())
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-env = Environment(PDFTEX = r'%s mypdftex.py', PDFTEXFLAGS = '-x', tools=['pdftex'])
+env = Environment(PDFTEX = r'%(_python_)s mypdftex.py',
+ PDFTEXFLAGS = '-x',
+ tools=['pdftex'])
env.PDF(target = 'test.pdf', source = 'test.tex')
-""" % python)
+""" % locals())
test.write('test.tex', r"""This is a test.
\end
ENV = { 'PATH' : os.environ['PATH'] }
foo = Environment(ENV = ENV, PDFTEXFLAGS = '--output-comment Commentary')
pdftex = foo.Dictionary('PDFTEX')
-bar = Environment(ENV = ENV, PDFTEX = r'%s wrapper.py ' + pdftex)
+bar = Environment(ENV = ENV, PDFTEX = r'%(_python_)s wrapper.py ' + pdftex)
foo.PDF(target = 'foo.pdf', source = 'foo.tex')
bar.PDF(target = 'bar', source = 'bar.tex')
-""" % python)
+""" % locals())
tex = r"""
This is the %s TeX file.
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-env = Environment(TEX = r'%s mytex.py', tools=['tex'])
+env = Environment(TEX = r'%(_python_)s mytex.py', tools=['tex'])
env.DVI(target = 'test.dvi', source = 'test.tex')
-""" % python)
+""" % locals())
test.write('test.tex', r"""This is a test.
\end
ENV = { 'PATH' : os.environ['PATH'] }
foo = Environment(ENV = ENV)
tex = foo.Dictionary('TEX')
-bar = Environment(ENV = ENV, TEX = r'%s wrapper.py ' + tex)
+bar = Environment(ENV = ENV, TEX = r'%(_python_)s wrapper.py ' + tex)
foo.DVI(target = 'foo.dvi', source = 'foo.tex')
foo.DVI(target = 'foo-latex.dvi', source = 'foo-latex.tex')
bar.DVI(target = 'bar', source = 'bar.tex')
bar.DVI(target = 'bar-latex', source = 'bar-latex.tex')
foo.DVI('rerun.tex')
foo.DVI('bibtex-test.tex')
-""" % python)
+""" % locals())
tex = r"""
This is the %s TeX file.
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(TOOLS = ['tex'],
- TEXCOM = r'%(python)s mytex.py $TARGET $SOURCE')
+ TEXCOM = r'%(_python_)s mytex.py $TARGET $SOURCE')
env.DVI('test1')
""" % locals())
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(TOOLS = ['tex'],
- TEXCOM = r'%(python)s mytex.py $TARGET $SOURCE',
+ TEXCOM = r'%(_python_)s mytex.py $TARGET $SOURCE',
TEXCOMSTR = 'Building $TARGET from $SOURCE')
env.DVI('test1')
""" % locals())
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-env = Environment(TEX = r'%s mytex.py', TEXFLAGS = '-x', tools=['tex'])
+env = Environment(TEX = r'%(_python_)s mytex.py',
+ TEXFLAGS = '-x',
+ tools=['tex'])
env.DVI(target = 'test.dvi', source = 'test.tex')
-""" % python)
+""" % locals())
test.write('test.tex', r"""This is a test.
\end
ENV = { 'PATH' : os.environ['PATH'] }
foo = Environment(ENV = ENV, TEXFLAGS = '--output-comment Commentary')
tex = foo.Dictionary('TEX')
-bar = Environment(ENV = ENV, TEX = r'%s wrapper.py ' + tex)
+bar = Environment(ENV = ENV, TEX = r'%(_python_)s wrapper.py ' + tex)
foo.DVI(target = 'foo.dvi', source = 'foo.tex')
bar.DVI(target = 'bar', source = 'bar.tex')
-""" % python)
+""" % locals())
tex = r"""
This is the %s TeX file.
import TestSCons
import TestCmd
+_python_ = TestSCons._python_
+
test = TestSCons.TestSCons(match=TestCmd.match_re)
# Run all of the tests with both types of source signature
env = Environment()
env['BUILDERS']['B'] = Builder(action = create)
-env['BUILDERS']['S'] = Builder(action = "%(python)s put $SOURCES into $TARGET")
+env['BUILDERS']['S'] = Builder(action = '%(_python_)s put $SOURCES into $TARGET')
env.B('f1.out', Value(P))
env.B('f2.out', env.Value(L))
env.B('f3.out', Value(C))
env.S('f4.out', Value(L))
-""" % {'source_signature':source_signature,
- 'python':TestSCons.python})
+
+def create_value (target, source, env):
+ target[0].write(source[0].get_contents ())
+
+def create_value_file (target, source, env):
+ open(str(target[0]), 'wb').write(source[0].read())
+
+env['BUILDERS']['B2'] = Builder(action = create_value)
+env['BUILDERS']['B3'] = Builder(action = create_value_file)
+
+V = Value('my value')
+env.B2(V, 'f3.out')
+env.B3('f5.out', V)
+""" % locals())
test.write('put', """
import os
test.run(arguments='-c')
test.run()
+ out7 = """create_value(["'my value'"], ["f3.out"])"""
+ out8 = """create_value_file(["f5.out"], ["'my value'"])"""
+
out1 = """create(["f1.out"], ["'/usr/local'"])"""
out2 = """create(["f2.out"], ["10"])"""
out3 = """create\\(\\["f3.out"\\], \\["<.*.Custom instance at """
#" <- unconfuses emacs syntax highlighting
+
test.fail_test(string.find(test.stdout(), out1) == -1)
test.fail_test(string.find(test.stdout(), out2) == -1)
+ test.fail_test(string.find(test.stdout(), out7) == -1)
+ test.fail_test(string.find(test.stdout(), out8) == -1)
test.fail_test(re.search(out3, test.stdout()) == None)
test.must_match('f1.out', "/usr/local")
test.must_match('f2.out', "10")
test.must_match('f3.out', "C=/usr/local")
test.must_match('f4.out', '10')
+ test.must_match('f5.out', "C=/usr/local")
test.up_to_date(arguments='.')
test.fail_test(string.find(test.stdout(), out4) == -1)
test.fail_test(string.find(test.stdout(), out5) != -1)
+ test.fail_test(string.find(test.stdout(), out7) == -1)
+ test.fail_test(string.find(test.stdout(), out8) == -1)
test.fail_test(re.search(out6, test.stdout()) == None)
test.up_to_date('prefix=/var', '.')
test.must_match('f2.out', "4")
test.must_match('f3.out', "C=/var")
test.must_match('f4.out', "4")
+ test.must_match('f5.out', "C=/var")
test.pass_test()
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
if sys.platform == 'win32':
test.write('SConstruct', """
-env = Environment(YACC = r'%s myyacc.py', tools=['default', 'yacc'])
+env = Environment(YACC = r'%(_python_)s myyacc.py', tools=['default', 'yacc'])
env.Program(target = 'aaa', source = 'aaa.y')
env.Program(target = 'bbb', source = 'bbb.yacc')
-""" % python)
+""" % locals())
test.write('aaa.y', r"""
int
test.write('SConstruct', """
foo = Environment(YACCFLAGS='-d')
yacc = foo.Dictionary('YACC')
-bar = Environment(YACC = r'%s wrapper.py ' + yacc)
+bar = Environment(YACC = r'%(_python_)s wrapper.py ' + yacc)
foo.Program(target = 'foo', source = 'foo.y')
bar.Program(target = 'bar', source = 'bar.y')
foo.Program(target = 'hello', source = ['hello.cpp'])
foo.CXXFile(target = 'file.cpp', source = ['file.yy'], YACCFLAGS='-d')
foo.CFile(target = 'not_foo', source = 'foo.y')
-""" % python)
+""" % locals())
yacc = r"""
%%{
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(tools=['default', 'yacc'],
- YACCCOM = r'%s myyacc.py $TARGET $SOURCES')
+ YACCCOM = r'%(_python_)s myyacc.py $TARGET $SOURCES')
env.CFile(target = 'aaa', source = 'aaa.y')
env.CFile(target = 'bbb', source = 'bbb.yacc')
-""" % python)
+""" % locals())
test.write('aaa.y', "aaa.y\n/*yacc*/\n")
test.write('bbb.yacc', "bbb.yacc\n/*yacc*/\n")
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(tools=['default', 'yacc'],
- YACCCOM = r'%s myyacc.py $TARGET $SOURCES',
+ YACCCOM = r'%(_python_)s myyacc.py $TARGET $SOURCES',
YACCCOMSTR = 'Yaccing $TARGET from $SOURCE')
env.CFile(target = 'aaa', source = 'aaa.y')
env.CFile(target = 'bbb', source = 'bbb.yacc')
-""" % python)
+""" % locals())
test.write('aaa.y', "aaa.y\n/*yacc*/\n")
test.write('bbb.yacc', "bbb.yacc\n/*yacc*/\n")
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
if sys.platform == 'win32':
""")
test.write('SConstruct', """
-env = Environment(YACC = r'%s myyacc.py', YACCFLAGS = '-x', tools=['yacc', '%s', '%s'])
+env = Environment(YACC = r'%(_python_)s myyacc.py',
+ YACCFLAGS = '-x',
+ tools=['yacc', '%(linker)s', '%(compiler)s'])
env.Program(target = 'aaa', source = 'aaa.y')
-""" % (python, linker, compiler))
+""" % locals())
test.write('aaa.y', r"""
int
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(tools=['default', 'yacc'],
- YACC = r'%s myyacc.py',
+ YACC = r'%(_python_)s myyacc.py',
YACCFLAGS = '-d',
YACCHFILESUFFIX = '.hsuffix')
env.CFile(target = 'aaa', source = 'aaa.y')
env.CFile(target = 'bbb', source = 'bbb.yacc')
-""" % python)
+""" % locals())
test.write('aaa.y', "aaa.y\n/*yacc*/\n")
test.write('bbb.yacc', "bbb.yacc\n/*yacc*/\n")
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(tools=['default', 'yacc'],
- YACC = r'%s myyacc.py',
+ YACC = r'%(_python_)s myyacc.py',
YACCFLAGS = '-d',
YACCHXXFILESUFFIX = '.hxxsuffix')
env.CXXFile(target = 'aaa', source = 'aaa.yy')
-""" % python)
+""" % locals())
test.write('aaa.yy', "aaa.yy\n/*yacc*/\n")
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(tools = ['zip'],
- ZIPCOM = r'%s myzip.py $TARGET $SOURCES')
+ ZIPCOM = r'%(_python_)s myzip.py $TARGET $SOURCES')
env.Zip(target = 'aaa.zip', source = ['file1', 'file2'])
env.Zip(target = 'aaa.zip', source = 'file3')
env.Zip(target = 'bbb', source = 'sub1')
env.Zip(target = 'bbb', source = 'file4')
-""" % python)
+""" % locals())
test.write('file1', "file1\n")
test.write('file2', "file2\n")
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(TOOLS = ['zip'],
- ZIPCOM = r'%(python)s myzip.py $TARGET $SOURCE')
+ ZIPCOM = r'%(_python_)s myzip.py $TARGET $SOURCE')
env.Zip('test1.zip', 'test1.in')
""" % locals())
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
env = Environment(tools=['zip'],
- ZIPCOM = r'%s myzip.py $TARGET $SOURCES',
+ ZIPCOM = r'%(_python_)s myzip.py $TARGET $SOURCES',
ZIPCOMSTR = 'Zipping $TARGET from $SOURCE')
env.Zip('aaa.zip', 'aaa.in')
-""" % python)
+""" % locals())
test.write('aaa.in', "aaa.in\n/*zip*/\n")
test = TestSCons.TestSCons()
-test.write('SConstruct', """\
+SConstruct_path = test.workpath('SConstruct')
+SConscript_path = test.workpath('SConscript')
+
+test.write(SConstruct_path, """\
env = Environment()
env['foo-bar'] = 1
""")
-test.run(arguments = '.', status = 2, stderr="""
+expect_stderr = """
scons: *** Illegal construction variable `foo-bar'
-File "SConstruct", line 2, in ?
-""")
+File "%(SConstruct_path)s", line 2, in ?
+""" % locals()
+
+test.run(arguments='.', status=2, stderr=expect_stderr)
+
-test.write('SConstruct', """\
+
+test.write(SConstruct_path, """\
SConscript('SConscript')
""")
env['foo(bar)'] = 1
""")
-test.run(arguments = '.', status = 2, stderr="""
+expect_stderr = """
scons: *** Illegal construction variable `foo(bar)'
-File "SConscript", line 2, in ?
-""")
+File "%(SConscript_path)s", line 2, in ?
+""" % locals()
+
+test.run(arguments='.', status=2, stderr=expect_stderr)
test.pass_test()
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
""")
test.write(['one', 'SConstruct'], """
-B0 = Builder(action = r'%s ../build.py 0 $TARGET $SOURCES')
-B1 = Builder(action = r'%s ../build.py 1 $TARGET $SOURCES')
+B0 = Builder(action = r'%(_python_)s ../build.py 0 $TARGET $SOURCES')
+B1 = Builder(action = r'%(_python_)s ../build.py 1 $TARGET $SOURCES')
env = Environment(BUILDERS = { 'B0' : B0, 'B1' : B1 })
env.B1(target = 'f1.out', source = 'f1.in')
env.B0(target = 'f2.out', source = 'f2.in')
env.B0(target = 'f3.out', source = 'f3.in')
-""" % (python, python))
+""" % locals())
test.write(['one', 'f1.in'], "one/f1.in\n")
test.write(['one', 'f2.in'], "one/f2.in\n")
test.fail_test(os.path.exists(test.workpath('f3.out')))
test.write(['two', 'SConstruct'], """
-B0 = Builder(action = r'%s ../build.py 0 $TARGET $SOURCES')
-B1 = Builder(action = r'%s ../build.py 1 $TARGET $SOURCES')
+B0 = Builder(action = r'%(_python_)s ../build.py 0 $TARGET $SOURCES')
+B1 = Builder(action = r'%(_python_)s ../build.py 1 $TARGET $SOURCES')
env = Environment(BUILDERS = { 'B0': B0, 'B1' : B1 })
env.B0(target = 'f1.out', source = 'f1.in')
env.B1(target = 'f2.out', source = 'f2.in')
env.B0(target = 'f3.out', source = 'f3.in')
-""" % (python, python))
+""" % locals())
test.write(['two', 'f1.in'], "two/f1.in\n")
test.write(['two', 'f2.in'], "two/f2.in\n")
test.fail_test(os.path.exists(test.workpath('f3.out')))
test.write(['three', 'SConstruct'], """
-B0 = Builder(action = r'%s ../build.py 0 $TARGET $SOURCES')
-B1 = Builder(action = r'%s ../build.py 1 $TARGET $SOURCES')
+B0 = Builder(action = r'%(_python_)s ../build.py 0 $TARGET $SOURCES')
+B1 = Builder(action = r'%(_python_)s ../build.py 1 $TARGET $SOURCES')
env = Environment(BUILDERS = { 'B0' : B0, 'B1': B1 })
env.B0(target = 'f1.out', source = 'f1.in')
env.B0(target = 'f2.out', source = 'f2.in')
env.B1(target = 'f3.out', source = 'f3.in')
-""" % (python, python))
+""" % locals())
test.write(['three', 'f1.in'], "three/f1.in\n")
test.write(['three', 'f2.in'], "three/f2.in\n")
test.fail_test(string.find(err, 'Exception') != -1 or \
string.find(err, 'Traceback') != -1)
+
+# Test ETOOLONG (arg list too long). This is not in exitvalmap,
+# but that shouldn't cause a scons traceback.
+long_cmd = 'xyz ' + "foobarxyz" * 100000
+test.write('SConstruct', """
+env=Environment()
+if env['PLATFORM'] == 'posix':
+ from SCons.Platform.posix import fork_spawn
+ env['SPAWN'] = fork_spawn
+env.Command(target='longcmd.out', source=[], action='echo %s')
+"""%long_cmd)
+
+test.run(status=2, stderr=None)
+err = test.stderr()
+test.fail_test(string.find(err, 'Exception') != -1 or \
+ string.find(err, 'Traceback') != -1)
+# Python 1.5.2 on a FC3 system doesn't even get to the exitvalmap
+# because it fails with "No such file or directory." Just comment
+# this out for now, there are plenty of other good tests below.
+#test.fail_test(string.find(err, "too long") == -1 and # posix
+# string.find(err, "nvalid argument") == -1) # win32
+
+
+# Test bad shell ('./one' is a dir, so it can't be used as a shell).
+# This will also give an exit status not in exitvalmap,
+# with error "Permission denied".
+test.write('SConstruct', """
+env=Environment()
+if env['PLATFORM'] == 'posix':
+ from SCons.Platform.posix import fork_spawn
+ env['SPAWN'] = fork_spawn
+env['SHELL'] = 'one'
+env.Command(target='badshell.out', source=[], action='foo')
+""")
+
+test.run(status=2, stderr=None)
+err = test.stderr()
+test.fail_test(string.find(err, 'Exception') != -1 or \
+ string.find(err, 'Traceback') != -1)
+test.fail_test(string.find(err, "ermission") == -1 and \
+ string.find(err, "such file") == -1)
+
+
+# Test command with exit status -1.
+# Should not give traceback.
+test.write('SConstruct', """
+import os
+env = Environment(ENV = os.environ)
+env.Command('dummy.txt', None, ['python -c "import sys; sys.exit(-1)"'])
+""")
+
+test.run(status=2, stderr=None)
+err = test.stderr()
+test.fail_test(string.find(err, 'Exception') != -1 or \
+ string.find(err, 'Traceback') != -1)
+
+
+# No tests failed; OK.
test.pass_test()
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
""")
test.write(['work1', 'SConstruct'], """
-cat_command = r"%(python)s %(cat_py)s ${TARGET.file} ${SOURCE.file}"
+cat_command = r'%(_python_)s %(cat_py)s ${TARGET.file} ${SOURCE.file}'
no_chdir_act = Action(cat_command)
chdir_sub4_act = Action(cat_command, chdir=1)
work2_sub_f2_out = test.workpath('work2', 'sub', 'f2.out')
test.write(['work2', 'SConstruct'], """\
-cat_command = r"%(python)s %(cat_py)s ${TARGET.file} ${SOURCE.file}"
+cat_command = r'%(_python_)s %(cat_py)s ${TARGET.file} ${SOURCE.file}'
env = Environment()
env.Command('sub/f1.out', 'sub/f1.in', cat_command,
chdir=1)
env.Command('sub/f2.out', 'sub/f2.in',
[
- r"%(python)s %(cat_py)s .temp ${SOURCE.file}",
- r"%(python)s %(cat_py)s ${TARGET.file} .temp",
+ r'%(_python_)s %(cat_py)s .temp ${SOURCE.file}',
+ r'%(_python_)s %(cat_py)s ${TARGET.file} .temp',
],
chdir=1)
""" % locals())
expect = test.wrap_stdout("""\
os.chdir('sub')
-%(python)s %(cat_py)s f1.out f1.in
+%(_python_)s %(cat_py)s f1.out f1.in
os.chdir(%(work2)s)
os.chdir('sub')
-%(python)s %(cat_py)s .temp f2.in
+%(_python_)s %(cat_py)s .temp f2.in
os.chdir(%(work2)s)
os.chdir('sub')
-%(python)s %(cat_py)s f2.out .temp
+%(_python_)s %(cat_py)s f2.out .temp
os.chdir(%(work2)s)
""" % locals())
""")
test.write('f1.c', r"""
+#include <stdio.h>
void
f1(void)
{
import string
import sys
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons(match = TestCmd.match_re_dotall)
test.run(status = 2, stderr = """\
AttributeError: 'int' object has no attribute 'append':
- File "SConstruct", line 2:
+ File ".+SConstruct", line 2:
a.append\(2\)
""")
test.run(status = 2, stderr = """\
NameError: [^\n]*
- File "SConstruct", line 1:
+ File ".+SConstruct", line 1:
a == 1
""")
""")
test.run(stdout = "scons: Reading SConscript files ...\n",
- stderr = """ File "SConstruct", line 2
+ stderr = """ File ".+SConstruct", line 2
a ! x
test.run(status = 2, stderr = """\
TypeError: object does not support item assignment:
- File "SConstruct", line 2:
+ File ".+SConstruct", line 2:
a\[2\] = 3
""")
test.run(stdout = "scons: Reading SConscript files ...\n",
stderr = """
scons: \*\*\* Depends\(\) require both sources and targets.
-File "SConstruct", line 4, in \?
+File ".+SConstruct", line 4, in \?
""", status=2)
File ".+", line \d+, in .+
File ".+", line \d+, in .+
File ".+", line \d+, in .+
- File "SConstruct", line \d+, in \?
+ File ".+SConstruct", line \d+, in \?
raise InternalError, 'error inside'
InternalError: error inside
""", status=2)
# Test ...
test.write('SConstruct', """
env=Environment()
-Default(env.Command(['one.out', 'two.out'], ['foo.in'], action=r'%s build.py'))
-"""%python)
+Default(env.Command(['one.out', 'two.out'],
+ ['foo.in'],
+ action=r'%(_python_)s build.py'))
+""" % locals())
test.run(status=2, stderr="scons: \\*\\*\\* \\[one.out\\] Error 2\n")
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import os
+import re
import string
import sys
import TestSCons
import TestCmd
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons(match = TestCmd.match_re_dotall)
-test.write('SConstruct', """
+SConstruct_path = test.workpath('SConstruct')
+
+test.write(SConstruct_path, """\
def func(source = None, target = None, env = None):
raise "func exception"
B = Builder(action = func)
)*( File ".+", line \d+, in \S+
)*( File ".+", line \d+, in \S+
[^\n]+
-)* File "SConstruct", line 3, in func
+)* File "%s", line 2, in func
raise "func exception"
func exception
-"""
+""" % re.escape(SConstruct_path)
test.run(arguments = "foo.out", stderr = expected_stderr, status = 2)
sys.exit(1)
""")
-test.write('SConstruct', """
-Fail = Builder(action = r'%s myfail.py $TARGETS $SOURCE')
+test.write(SConstruct_path, """
+Fail = Builder(action = r'%(_python_)s myfail.py $TARGETS $SOURCE')
env = Environment(BUILDERS = { 'Fail' : Fail })
env.Fail(target = 'f1', source = 'f1.in')
-""" % (python))
+""" % locals())
test.write('f1.in', "f1.in\n")
# even if the exception is raised during the Task.prepare()
# [Node.prepare()]
-test.write('SConstruct', """
-Fail = Builder(action = r'%s myfail.py $TARGETS $SOURCE')
+test.write(SConstruct_path, """
+Fail = Builder(action = r'%(_python_)s myfail.py $TARGETS $SOURCE')
env = Environment(BUILDERS = { 'Fail' : Fail })
env.Fail(target = 'f1', source = 'f1.in')
env.Fail(target = 'f2', source = 'f2.in')
env.Fail(target = 'f3', source = 'f3.in')
-""" % (python))
+""" % locals())
# f2.in is not created to cause a Task.prepare exception
test.write('f3.in', 'f3.in\n')
os.path.join('$SUBDIR', 'foo4.c')))
test.write(['sub', 'f1.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
int
main(int argc, char *argv[])
{
""")
test.write('f2.c', r"""
+#include <stdio.h>
+#include <stdlib.h>
int
main(int argc, char *argv[])
{
""")
test.write(['sub', 'f3.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
int
main(int argc, char *argv[])
{
""")
test.write(['sub', 'foo4.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
int
main(int argc, char *argv[])
{
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
argument = None,
skeys = ['.k'])
-cat = Builder(action = r"%s %s $TARGET $SOURCES")
+cat = Builder(action = r'%(_python_)s %(cat_py)s $TARGET $SOURCES')
env = Environment()
env.Append(BUILDERS = {'Cat':cat},
env.InstallAs('../inc/bbb.k', 'bbb.k')
env.Install('../inc', 'ddd')
env.InstallAs('../inc/eee', 'eee.in')
-""" % (python, cat_py)
+""" % locals()
args = '--debug=explain .'
env.Cat('file1', 'file1.in')
env.Cat('file2', 'file2.k')
env.Cat('file3', ['xxx', 'yyy', 'zzz'])
-env.Command('file4', 'file4.in', r"%s %s $TARGET $FILE4FLAG $SOURCES", FILE4FLAG="-")
+env.Command('file4', 'file4.in',
+ r'%(_python_)s %(cat_py)s $TARGET $FILE4FLAG $SOURCES',
+ FILE4FLAG='-')
env.Cat('file5', 'file5.k')
env.Cat('subdir/file6', 'subdir/file6.in')
-""" % (python, cat_py))
+""" % locals())
test.write(['work1', 'src', 'aaa'], "aaa 1\n")
test.write(['work1', 'src', 'bbb.k'], """\
work1_inc_bbb_k = test.workpath('work1', 'inc', 'bbb.k')
#
-test.run(chdir='work1/src', arguments=args, stdout=test.wrap_stdout("""\
+expect = test.wrap_stdout("""\
scons: building `file1' because it doesn't exist
-%(python)s %(cat_py)s file1 file1.in
+%(_python_)s %(cat_py)s file1 file1.in
scons: building `file2' because it doesn't exist
-%(python)s %(cat_py)s file2 file2.k
+%(_python_)s %(cat_py)s file2 file2.k
scons: building `file3' because it doesn't exist
-%(python)s %(cat_py)s file3 xxx yyy zzz
+%(_python_)s %(cat_py)s file3 xxx yyy zzz
scons: building `file4' because it doesn't exist
-%(python)s %(cat_py)s file4 - file4.in
+%(_python_)s %(cat_py)s file4 - file4.in
scons: building `%(work1_inc_aaa)s' because it doesn't exist
Install file: "aaa" as "%(work1_inc_aaa)s"
scons: building `%(work1_inc_ddd)s' because it doesn't exist
scons: building `%(work1_inc_bbb_k)s' because it doesn't exist
Install file: "bbb.k" as "%(work1_inc_bbb_k)s"
scons: building `file5' because it doesn't exist
-%(python)s %(cat_py)s file5 file5.k
+%(_python_)s %(cat_py)s file5 file5.k
scons: building `%(subdir_file6)s' because it doesn't exist
-%(python)s %(cat_py)s %(subdir_file6)s %(subdir_file6_in)s
-""" % locals()))
+%(_python_)s %(cat_py)s %(subdir_file6)s %(subdir_file6_in)s
+""" % locals())
+
+test.run(chdir='work1/src', arguments=args, stdout=expect)
test.must_match(['work1', 'src', 'file1'], "file1.in 1\n")
test.must_match(['work1', 'src', 'file2'], """\
test.write(['work1', 'src', 'zzz'], "zzz 2\n")
test.write(['work1', 'src', 'bbb.k'], "bbb.k 2\ninclude ccc\n")
-test.run(chdir='work1/src', arguments=args, stdout=test.wrap_stdout("""\
+expect = test.wrap_stdout("""\
scons: rebuilding `file1' because `file1.in' changed
-%(python)s %(cat_py)s file1 file1.in
+%(_python_)s %(cat_py)s file1 file1.in
scons: rebuilding `file2' because `yyy' changed
-%(python)s %(cat_py)s file2 file2.k
+%(_python_)s %(cat_py)s file2 file2.k
scons: rebuilding `file3' because:
`yyy' changed
`zzz' changed
-%(python)s %(cat_py)s file3 xxx yyy zzz
+%(_python_)s %(cat_py)s file3 xxx yyy zzz
scons: rebuilding `%(work1_inc_bbb_k)s' because:
`%(work1_inc_ddd)s' is no longer a dependency
`%(work1_inc_eee)s' is no longer a dependency
`bbb.k' changed
Install file: "bbb.k" as "%(work1_inc_bbb_k)s"
scons: rebuilding `file5' because `%(work1_inc_bbb_k)s' changed
-%(python)s %(cat_py)s file5 file5.k
-""" % locals()))
+%(_python_)s %(cat_py)s file5 file5.k
+""" % locals())
+
+test.run(chdir='work1/src', arguments=args, stdout=expect)
test.must_match(['work1', 'src', 'file1'], "file1.in 2\n")
test.must_match(['work1', 'src', 'file2'], """\
env.Cat('file3', ['xxx', 'yyy'])
""")
-test.run(chdir='work1/src', arguments=args, stdout=test.wrap_stdout("""\
+expect = test.wrap_stdout("""\
scons: rebuilding `file3' because `zzz' is no longer a dependency
-%(python)s %(cat_py)s file3 xxx yyy
-""" % locals()))
+%(_python_)s %(cat_py)s file3 xxx yyy
+""" % locals())
+
+test.run(chdir='work1/src', arguments=args, stdout=expect)
test.must_match(['work1', 'src', 'file3'], "xxx 1\nyyy 2\n")
env.Cat('file3', ['xxx', 'yyy', 'zzz'])
""")
-test.run(chdir='work1/src', arguments=args, stdout=test.wrap_stdout("""\
+expect = test.wrap_stdout("""\
scons: rebuilding `file3' because `zzz' is a new dependency
-%(python)s %(cat_py)s file3 xxx yyy zzz
-""" % locals()))
+%(_python_)s %(cat_py)s file3 xxx yyy zzz
+""" % locals())
+
+test.run(chdir='work1/src', arguments=args, stdout=expect)
test.must_match(['work1', 'src', 'file3'], "xxx 1\nyyy 2\nzzz 2\n")
env.Cat('file3', ['zzz', 'yyy', 'xxx'])
""")
-test.run(chdir='work1/src', arguments=args, stdout=test.wrap_stdout("""\
+expect = test.wrap_stdout("""\
scons: rebuilding `file3' because the dependency order changed:
old: ['xxx', 'yyy', 'zzz']
new: ['zzz', 'yyy', 'xxx']
-%(python)s %(cat_py)s file3 zzz yyy xxx
-""" % locals()))
+%(_python_)s %(cat_py)s file3 zzz yyy xxx
+""" % locals())
+
+test.run(chdir='work1/src', arguments=args, stdout=expect)
test.must_match(['work1', 'src', 'file3'], "zzz 2\nyyy 2\nxxx 1\n")
Import("env")
f3 = File('file3')
env.Cat(f3, ['zzz', 'yyy', 'xxx'])
-env.AddPostAction(f3, r"%(python)s %(cat_py)s ${TARGET}.yyy $SOURCES yyy")
-env.AddPreAction(f3, r"%(python)s %(cat_py)s ${TARGET}.alt $SOURCES")
+env.AddPostAction(f3, r'%(_python_)s %(cat_py)s ${TARGET}.yyy $SOURCES yyy')
+env.AddPreAction(f3, r'%(_python_)s %(cat_py)s ${TARGET}.alt $SOURCES')
""" % locals())
-test.run(chdir='work1/src', arguments=args, stdout=test.wrap_stdout("""\
+expect = test.wrap_stdout("""\
scons: rebuilding `file3' because the build action changed:
- old: %(python)s %(cat_py)s $TARGET $SOURCES
- new: %(python)s %(cat_py)s ${TARGET}.alt $SOURCES
- %(python)s %(cat_py)s $TARGET $SOURCES
- %(python)s %(cat_py)s ${TARGET}.yyy $SOURCES yyy
-%(python)s %(cat_py)s file3.alt zzz yyy xxx
-%(python)s %(cat_py)s file3 zzz yyy xxx
-%(python)s %(cat_py)s file3.yyy zzz yyy xxx yyy
-""" % locals()))
+ old: %(_python_)s %(cat_py)s $TARGET $SOURCES
+ new: %(_python_)s %(cat_py)s ${TARGET}.alt $SOURCES
+ %(_python_)s %(cat_py)s $TARGET $SOURCES
+ %(_python_)s %(cat_py)s ${TARGET}.yyy $SOURCES yyy
+%(_python_)s %(cat_py)s file3.alt zzz yyy xxx
+%(_python_)s %(cat_py)s file3 zzz yyy xxx
+%(_python_)s %(cat_py)s file3.yyy zzz yyy xxx yyy
+""" % locals())
+
+test.run(chdir='work1/src', arguments=args, stdout=expect)
test.must_match(['work1', 'src', 'file3'], "zzz 2\nyyy 2\nxxx 1\n")
test.must_match(['work1', 'src', 'file3.alt'], "zzz 2\nyyy 2\nxxx 1\n")
Import("env")
f3 = File('file3')
env.Cat(f3, ['zzz', 'yyy', 'xxx'])
-env.AddPostAction(f3, r"%(python)s %(cat_py)s ${TARGET}.yyy $SOURCES xxx")
-env.AddPreAction(f3, r"%(python)s %(cat_py)s ${TARGET}.alt $SOURCES")
+env.AddPostAction(f3, r'%(_python_)s %(cat_py)s ${TARGET}.yyy $SOURCES xxx')
+env.AddPreAction(f3, r'%(_python_)s %(cat_py)s ${TARGET}.alt $SOURCES')
""" % locals())
-test.run(chdir='work1/src', arguments=args, stdout=test.wrap_stdout("""\
+expect = test.wrap_stdout("""\
scons: rebuilding `file3' because the build action changed:
- old: %(python)s %(cat_py)s ${TARGET}.alt $SOURCES
- %(python)s %(cat_py)s $TARGET $SOURCES
- %(python)s %(cat_py)s ${TARGET}.yyy $SOURCES yyy
- new: %(python)s %(cat_py)s ${TARGET}.alt $SOURCES
- %(python)s %(cat_py)s $TARGET $SOURCES
- %(python)s %(cat_py)s ${TARGET}.yyy $SOURCES xxx
-%(python)s %(cat_py)s file3.alt zzz yyy xxx
-%(python)s %(cat_py)s file3 zzz yyy xxx
-%(python)s %(cat_py)s file3.yyy zzz yyy xxx xxx
-""" % locals()))
+ old: %(_python_)s %(cat_py)s ${TARGET}.alt $SOURCES
+ %(_python_)s %(cat_py)s $TARGET $SOURCES
+ %(_python_)s %(cat_py)s ${TARGET}.yyy $SOURCES yyy
+ new: %(_python_)s %(cat_py)s ${TARGET}.alt $SOURCES
+ %(_python_)s %(cat_py)s $TARGET $SOURCES
+ %(_python_)s %(cat_py)s ${TARGET}.yyy $SOURCES xxx
+%(_python_)s %(cat_py)s file3.alt zzz yyy xxx
+%(_python_)s %(cat_py)s file3 zzz yyy xxx
+%(_python_)s %(cat_py)s file3.yyy zzz yyy xxx xxx
+""" % locals())
+
+test.run(chdir='work1/src', arguments=args, stdout=expect)
test.must_match(['work1', 'src', 'file3'], "zzz 2\nyyy 2\nxxx 1\n")
test.must_match(['work1', 'src', 'file3.alt'], "zzz 2\nyyy 2\nxxx 1\n")
#
test.write(['work1', 'src', 'SConscript'], """\
Import("env")
-env.Command('file4', 'file4.in', r"%(python)s %(cat_py)s $TARGET $FILE4FLAG $SOURCES", FILE4FLAG="")
+env.Command('file4', 'file4.in',
+ r'%(_python_)s %(cat_py)s $TARGET $FILE4FLAG $SOURCES',
+ FILE4FLAG='')
""" % locals())
-test.run(chdir='work1/src',arguments=args, stdout=test.wrap_stdout("""\
+expect = test.wrap_stdout("""\
scons: rebuilding `file4' because the contents of the build action changed
- action: %(python)s %(cat_py)s $TARGET $FILE4FLAG $SOURCES
-%(python)s %(cat_py)s file4 file4.in
-""" % locals()))
+ action: %(_python_)s %(cat_py)s $TARGET $FILE4FLAG $SOURCES
+%(_python_)s %(cat_py)s file4 file4.in
+""" % locals())
+
+test.run(chdir='work1/src',arguments=args, stdout=expect)
test.must_match(['work1', 'src', 'file4'], "file4.in 1\n")
env.Cat('file1', 'file1.in')
env.Cat('file2', 'file2.k')
env.Cat('file3', ['xxx', 'yyy', 'zzz'])
-env.Command('file4', 'file4.in', r"%(python)s %(cat_py)s $TARGET - $SOURCES")
+env.Command('file4', 'file4.in', r'%(_python_)s %(cat_py)s $TARGET - $SOURCES')
env.Cat('file5', 'file5.k')
env.Cat('subdir/file6', 'subdir/file6.in')
""" % locals())
test.run(chdir='work4/src', arguments=args, stdout=test.wrap_stdout("""\
scons: rebuilding `file1' because `file1.in' changed
-%(python)s %(cat_py)s file1 file1.in
+%(_python_)s %(cat_py)s file1 file1.in
scons: rebuilding `file2' because `yyy' changed
-%(python)s %(cat_py)s file2 file2.k
+%(_python_)s %(cat_py)s file2 file2.k
scons: rebuilding `file3' because:
`yyy' changed
`zzz' changed
-%(python)s %(cat_py)s file3 xxx yyy zzz
+%(_python_)s %(cat_py)s file3 xxx yyy zzz
scons: rebuilding `%(work4_inc_bbb_k)s' because:
`%(work4_inc_ddd)s' is no longer a dependency
`%(work4_inc_eee)s' is no longer a dependency
`bbb.k' changed
Install file: "bbb.k" as "%(work4_inc_bbb_k)s"
scons: rebuilding `file5' because `%(work4_inc_bbb_k)s' changed
-%(python)s %(cat_py)s file5 file5.k
+%(_python_)s %(cat_py)s file5 file5.k
""" % locals()))
test.must_match(['work4', 'src', 'file1'], "file1.in 2\n")
import TestSCons
import string
import sys
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
_dll = TestSCons._dll
dll_ = TestSCons.dll_
/* cpp file 2 */
""")
+mygcc_py = test.workpath('gnutools','mygcc.py')
+mygxx_py = test.workpath('gnutools','myg++.py')
+
test.write(['work1', 'SConstruct'],"""
env = Environment(tools=['gcc','g++','gnulink'],
- CC=r'%s %s',
- CXX=r'%s %s',
+ CC=r'%(_python_)s %(mygcc_py)s',
+ CXX=r'%(_python_)s %(mygxx_py)s',
OBJSUFFIX='.o',
SHOBJSUFFIX='.os')
env.Program('c-only', Split('cfile1.c cfile2.c'))
env.SharedLibrary('c-only', Split('cfile1.c cfile2.c'))
env.SharedLibrary('cpp-only', Split('cppfile1.cpp cppfile2.cpp'))
env.SharedLibrary('c-and-cpp', Split('cfile1.c cppfile1.cpp'))
-""" % (python, test.workpath('gnutools','mygcc.py'),
- python, test.workpath('gnutools','myg++.py')))
+""" % locals())
test.run(chdir='work1')
import TestCmd
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """\
env = Environment()
-f1 = env.Command('f1.out', 'f1.in', "%(python)s build.py $TARGET $SOURCE")
-f2 = env.Command('f2.out', 'f2.in', "-%(python)s build.py $TARGET $SOURCE")
-f3 = env.Command('f3.out', 'f3.in', "- %(python)s build.py $TARGET $SOURCE")
-f4 = env.Command('f4.out', 'f4.in', "@-%(python)s build.py $TARGET $SOURCE")
-f5 = env.Command('f5.out', 'f5.in', "@- %(python)s build.py $TARGET $SOURCE")
-f6 = env.Command('f6.out', 'f6.in', "-@%(python)s build.py $TARGET $SOURCE")
-f7 = env.Command('f7.out', 'f7.in', "-@ %(python)s build.py $TARGET $SOURCE")
+f1 = env.Command('f1.out', 'f1.in', '%(_python_)s build.py $TARGET $SOURCE')
+f2 = env.Command('f2.out', 'f2.in', '-%(_python_)s build.py $TARGET $SOURCE')
+f3 = env.Command('f3.out', 'f3.in', '- %(_python_)s build.py $TARGET $SOURCE')
+f4 = env.Command('f4.out', 'f4.in', '@-%(_python_)s build.py $TARGET $SOURCE')
+f5 = env.Command('f5.out', 'f5.in', '@- %(_python_)s build.py $TARGET $SOURCE')
+f6 = env.Command('f6.out', 'f6.in', '-@%(_python_)s build.py $TARGET $SOURCE')
+f7 = env.Command('f7.out', 'f7.in', '-@ %(_python_)s build.py $TARGET $SOURCE')
Default(f2, f3, f4, f5, f6, f7)
""" % locals())
--- /dev/null
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Verify that SetOption/GetOption('implicit_cache') works and can
+be overridden from the command line.
+"""
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+test.write('SConstruct', """
+assert not GetOption('implicit_cache')
+SetOption('implicit_cache', 1)
+assert GetOption('implicit_cache')
+""")
+
+test.run()
+
+test.write('SConstruct', """
+assert GetOption('implicit_cache')
+SetOption('implicit_cache', 0)
+assert GetOption('implicit_cache')
+""")
+
+test.run(arguments='--implicit-cache')
+
+
+test.pass_test()
--- /dev/null
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Verify that SetOption('implicit_cache', 1) actually enables implicit
+caching by detecting the case where implicit caching causes inaccurate
+builds: a same-named file dropped into a directory earlier in the
+CPPPATH list will *not* be detected because we use what's in the cache.
+"""
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+test.write('SConstruct', """
+SetOption('implicit_cache', 1)
+env=Environment(CPPPATH=['i1', 'i2'])
+env.Object('foo.c')
+""")
+
+test.subdir('i1')
+test.subdir('i2')
+
+test.write('foo.c', """
+#include <foo.h>
+
+void foo(void)
+{
+ FOO_H_DEFINED
+ ++x; /* reference x */
+}
+""")
+
+test.write('i2/foo.h', """
+#define FOO_H_DEFINED int x = 1;
+""")
+
+test.run(arguments = '.')
+
+test.write('i1/foo.h', """
+this line will cause a syntax error if it's included by a rebuild
+""");
+
+test.up_to_date(arguments = '.')
+
+
+test.pass_test()
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
-import os
-import sys
+import os.path
+
import TestSCons
-import string
_exe = TestSCons._exe
_obj = TestSCons._obj
env.Program(target='prog', source='prog.c')
""")
-test.write('nodeps.in',
-r"""
+test.write('nodeps.in', r"""
int
main(int argc, char *argv[])
{
""")
-test.write(['include', 'foo.h'],
-r"""
+test.write(['include', 'foo.h'], r"""
#define FOO_STRING "include/foo.h 1\n"
#include <bar.h>
""")
-test.write(['include', 'bar.h'],
-r"""
+test.write(['include', 'bar.h'], r"""
#define BAR_STRING "include/bar.h 1\n"
""")
-test.write(['include', 'baz.h'],
-r"""
+test.write(['include', 'baz.h'], r"""
#define BAZ_STRING "include/baz.h 1\n"
""")
-test.write(['subdir', 'prog.c'],
-r"""
+test.write(['subdir', 'prog.c'], r"""
#include <foo.h>
#include <stdio.h>
}
""")
-test.write(['subdir', 'include', 'foo.h'],
-r"""
+test.write(['subdir', 'include', 'foo.h'], r"""
#define FOO_STRING "subdir/include/foo.h 1\n"
#include "bar.h"
""")
-test.write(['subdir', 'include', 'bar.h'],
-r"""
+test.write(['subdir', 'include', 'bar.h'], r"""
#define BAR_STRING "subdir/include/bar.h 1\n"
""")
-test.write('one.c' ,
-r"""
+test.write('one.c' , r"""
#include <foo.h>
void one(void) { }
test.up_to_date(arguments = args)
-# Make sure implicit dependenies work right when one is modifed:
-test.write(['include', 'foo.h'],
-r"""
+
+
+# Make sure implicit dependencies work right when one is modifed:
+test.write(['include', 'foo.h'], r"""
#define FOO_STRING "include/foo.h 2\n"
#include "bar.h"
""")
test.up_to_date(arguments = args)
+
+
# Make sure that changing the order of includes causes rebuilds and
# doesn't produce redundant rebuilds:
-test.write(['include', 'foo.h'],
-r"""
+test.write(['include', 'foo.h'], r"""
#define FOO_STRING "include/foo.h 2\n"
#include "bar.h"
#include "baz.h"
test.up_to_date(arguments = args)
-test.write(['include', 'foo.h'],
-r"""
+
+
+test.write(['include', 'foo.h'], r"""
#define FOO_STRING "include/foo.h 2\n"
#include "baz.h"
#include "bar.h"
test.up_to_date(arguments = args)
+
+
# Add inc2/foo.h that should shadow include/foo.h, but
# because of implicit dependency caching, scons doesn't
# detect this:
-test.write(['inc2', 'foo.h'],
-r"""
+test.write(['inc2', 'foo.h'], r"""
#define FOO_STRING "inc2/foo.h 1\n"
#include <bar.h>
""")
test.run(arguments = "--implicit-cache " + args)
-test.run(arguments = "--implicit-cache " + args)
-
test.run(program = test.workpath(prog),
stdout = "subdir/prog.c\ninclude/foo.h 2\ninclude/bar.h 1\n")
test.run(program = test.workpath(variant_prog),
stdout = "subdir/prog.c\ninclude/foo.h 2\ninclude/bar.h 1\n")
+
+
# Now modifying include/foo.h should make scons aware of inc2/foo.h
-test.write(['include', 'foo.h'],
-r"""
+test.write(['include', 'foo.h'], r"""
#define FOO_STRING "include/foo.h 3\n"
#include "bar.h"
""")
test.run(program = test.workpath(variant_prog),
stdout = "subdir/prog.c\ninclude/foo.h 3\ninclude/bar.h 1\n")
-# test in the face of a file with no dependencies where the source file is generated:
+
+
+# test a file with no dependencies where the source file is generated:
test.run(arguments = "--implicit-cache nodeps%s"%_exe)
-test.write('nodeps.in',
-r"""
+test.write('nodeps.in', r"""
#include <foo.h>
int
}
""")
-test.run(arguments = "--implicit-cache one%s"%_obj)
test.run(arguments = "--implicit-cache one%s"%_obj)
+
+
# Test forcing of implicit caching:
-test.write(['include', 'foo.h'],
-r"""
+test.write(['include', 'foo.h'], r"""
#define FOO_STRING "include/foo.h 3\n"
#include "bar.h"
""")
test.run(arguments = "--implicit-cache " + args)
-test.write(['include', 'foo.h'],
-r"""
+test.write(['include', 'foo.h'], r"""
#define FOO_STRING "include/foo.h 3\n"
#include "baz.h"
#include "bar.h"
""")
-test.run(arguments = "--implicit-deps-unchanged " + variant_prog)
-assert string.find(test.stdout(), 'is up to date') == -1, test.stdout()
+test.not_up_to_date(options = "--implicit-deps-unchanged",
+ arguments = variant_prog)
-test.write(['include', 'baz.h'],
-r"""
+test.write(['include', 'baz.h'], r"""
#define BAZ_STRING "include/baz.h 2\n"
""")
-test.run(arguments = "--implicit-deps-unchanged " + variant_prog)
-assert string.find(test.stdout(), 'is up to date') != -1, test.stdout()
+test.up_to_date(options = "--implicit-deps-unchanged",
+ arguments = variant_prog)
+
+test.not_up_to_date(arguments = variant_prog)
+
-test.run(arguments = variant_prog)
-assert string.find(test.stdout(), 'is up to date') == -1, test.stdout()
# Test forcing rescanning:
-test.write(['include', 'foo.h'],
-r"""
+test.write(['include', 'foo.h'], r"""
#define FOO_STRING "include/foo.h 3\n"
#include "bar.h"
""")
test.run(arguments = "--implicit-cache " + args)
-test.write(['include', 'foo.h'],
-r"""
+test.write(['include', 'foo.h'], r"""
#define FOO_STRING "include/foo.h 3\n"
#include "baz.h"
#include "bar.h"
""")
-test.run(arguments = "--implicit-deps-unchanged " + variant_prog)
-assert string.find(test.stdout(), 'is up to date') == -1, test.stdout()
+test.not_up_to_date(options = "--implicit-deps-unchanged",
+ arguments = variant_prog)
-test.write(['include', 'baz.h'],
-r"""
+test.write(['include', 'baz.h'], r"""
#define BAZ_STRING "include/baz.h 2\n"
""")
-test.run(arguments = "--implicit-deps-unchanged " + variant_prog)
-assert string.find(test.stdout(), 'is up to date') != -1, test.stdout()
-
-test.run(arguments = "--implicit-deps-changed " + variant_prog)
-assert string.find(test.stdout(), 'is up to date') == -1, test.stdout()
-
-# Test that Set/GetOption('implicit_cache') works:
-test.write('SConstruct', """
-assert not GetOption('implicit_cache')
-SetOption('implicit_cache', 1)
-assert GetOption('implicit_cache')
-""")
-
-test.run()
-
-test.write('SConstruct', """
-assert GetOption('implicit_cache')
-SetOption('implicit_cache', 0)
-assert GetOption('implicit_cache')
-""")
-
-test.run(arguments='--implicit-cache')
-
-# Test to make sure SetOption('implicit_cache', 1) actually enables implicit caching
-# by detecting the one case where implicit caching causes inaccurate builds:
-test.write('SConstruct', """
-SetOption('implicit_cache', 1)
-env=Environment(CPPPATH=['i1', 'i2'])
-env.Object('foo.c')
-""")
-
-test.subdir('i1')
-test.subdir('i2')
-
-test.write('foo.c', """
-#include <foo.h>
-
-void foo(void)
-{
- FOO_H_DEFINED
- ++x; /* reference x */
-}
-""")
-
-test.write('i2/foo.h', """
-#define FOO_H_DEFINED int x = 1;
-""")
-
-test.run()
+test.up_to_date(options = "--implicit-deps-unchanged",
+ arguments = variant_prog)
-test.write('i1/foo.h', """
-""");
+test.not_up_to_date(options = "--implicit-deps-changed",
+ arguments = variant_prog)
-test.run()
test.pass_test()
test = TestSCons.TestSCons()
+SConstruct_path = test.workpath('SConstruct')
+
platforms = [
'aix',
'cygwin',
# Intel no compiler warning..
intel_no_compiler_fmt = """
-scons: warning: Failed to find Intel compiler for version='None', abi='%s'
-File "SConstruct", line 1, in ?
+scons: warning: Failed to find Intel compiler for version='None', abi='%(abi)s'
+File "%(SConstruct_path)s", line 1, in ?
"""
-intel_no_compiler_32_warning = intel_no_compiler_fmt % 'ia32'
-intel_no_compiler_64_warning = intel_no_compiler_fmt % 'x86_64'
+abi = 'ia32'
+intel_no_compiler_32_warning = intel_no_compiler_fmt % locals()
+
+abi = 'x86_64'
+intel_no_compiler_64_warning = intel_no_compiler_fmt % locals()
# Intel no top dir warning.
intel_no_top_dir_fmt = """
-scons: warning: Can't find Intel compiler top dir for version='None', abi='%s'
-File "SConstruct", line 1, in ?
-"""
+scons: warning: Can't find Intel compiler top dir for version='None', abi='%(abi)s'
+File "%(SConstruct_path)s", line 1, in ?
+""" % locals()
-intel_no_top_dir_32_warning = intel_no_top_dir_fmt % 'ia32'
-intel_no_top_dir_64_warning = intel_no_top_dir_fmt % 'x86_64'
+abi = 'ia32'
+intel_no_top_dir_32_warning = intel_no_top_dir_fmt % locals()
+
+abi = 'x86_64'
+intel_no_top_dir_64_warning = intel_no_top_dir_fmt % locals()
# Intel no license directory warning
intel_license_warning = """
scons: warning: Intel license dir was not found. Tried using the INTEL_LICENSE_FILE environment variable (), the registry () and the default path (C:\Program Files\Common Files\Intel\Licenses). Using the default path as a last resort.
-File "SConstruct", line 1, in ?
-"""
+File "%(SConstruct_path)s", line 1, in ?
+""" % locals()
intel_warnings = [
intel_license_warning,
moc = test.where_is('moc')
if moc:
import os.path
+
+ qtdir = os.path.dirname(os.path.dirname(moc))
+
qt_err = """
-scons: warning: Could not detect qt, using moc executable as a hint (QTDIR=%s)
-File "SConstruct", line 1, in ?
-""" % os.path.dirname(os.path.dirname(moc))
+scons: warning: Could not detect qt, using moc executable as a hint (QTDIR=%(qtdir)s)
+File "%(SConstruct_path)s", line 1, in ?
+""" % locals()
+
else:
+
qt_err = """
scons: warning: Could not detect qt, using empty QTDIR
-File "SConstruct", line 1, in ?
-"""
+File "%(SConstruct_path)s", line 1, in ?
+""" % locals()
error_output = {
'icl' : intel_warnings,
""" % (arflag_init, arflag, linkflag_init, linkflag))
test.write('foo.c', r"""
+#include <stdio.h>
+#include <stdlib.h>
int
main(int argc, char *argv[])
{
""")
test.write('static.c', r"""
+#include <stdio.h>
+#include <stdlib.h>
int
main(int argc, char *argv[])
{
""")
test.write('shared.c', r"""
+#include <stdio.h>
+#include <stdlib.h>
int
main(int argc, char *argv[])
{
test = TestSCons.TestSCons(match=TestCmd.match_re)
+_python_ = TestSCons._python_
#
# A builder with "multi" set can be called multiple times and
test.write('SConstruct', """
-B = Builder(action='%(python)s build.py $foo $TARGET $SOURCES', multi=1)
+B = Builder(action='%(_python_)s build.py $foo $TARGET $SOURCES', multi=1)
env = Environment(BUILDERS = { 'B' : B })
env.B(target = 'file03.out', source = 'file03a.in', foo=1)
env.B(target = 'file03.out', source = 'file03b.in', foo=2)
-""" % {'python':TestSCons.python})
+""" % locals())
test.write('file03a.in', 'file03a.in\n')
test.write('file03b.in', 'file03b.in\n')
test.write('SConstruct', """
-B = Builder(action='%(python)s build.py $foo $TARGET $SOURCES', multi=1)
+B = Builder(action='%(_python_)s build.py $foo $TARGET $SOURCES', multi=1)
env = Environment(BUILDERS = { 'B' : B })
env.B(target = 'file4.out', source = 'file4a.in', foo=3)
env.B(target = 'file4.out', source = 'file4b.in', foo=3)
-""" % {'python':TestSCons.python})
+""" % locals())
test.write('file4a.in', 'file4a.in\n')
test.write('file4b.in', 'file4b.in\n')
python_expr = string.replace(TestSCons.python, '\\', '\\\\')
-act = TestSCons.re_escape('%s build.py \$foo \$TARGET \$SOURCES' % python_expr)
+act = TestSCons.re_escape('"%s" build.py \$foo \$TARGET \$SOURCES' % python_expr)
test.run(arguments='file4.out',
stderr=("""
import TestSCons
python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-B1 = Builder(action = [ [ r'%s', 'build.py', '.temp', '$SOURCES' ],
- [ r'%s', 'build.py', '$TARGETS', '.temp'] ])
-B2 = Builder(action = r'%s' + " build.py .temp $SOURCES\\n" + r'%s' + " build.py $TARGETS .temp")
+B1 = Builder(action = [ [ r'%(python)s', 'build.py', '.temp', '$SOURCES' ],
+ [ r'%(python)s', 'build.py', '$TARGETS', '.temp'] ])
+B2 = Builder(action = r'%(_python_)s' + ' build.py .temp $SOURCES\\n' + r'%(_python_)s' + " build.py $TARGETS .temp")
env = Environment(BUILDERS = { 'B1' : B1, 'B2' : B2 })
env.B1(target = 'foo1.out', source = 'foo1.in')
env.B2(target = 'foo2.out', source = 'foo2.in')
env.B1(target = 'foo3.out', source = 'foo3.in')
-""" % (python, python, python, python))
+""" % locals())
test.write('foo1.in', "foo1.in\n")
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-MyBuild = Builder(action = r'%s build.py $TARGETS')
+MyBuild = Builder(action = r'%(_python_)s build.py $TARGETS')
env = Environment(BUILDERS = { 'MyBuild' : MyBuild })
env.MyBuild(target = '-f1.out', source = 'f1.in')
env.MyBuild(target = '-f2.out', source = 'f2.in')
-""" % python)
+""" % locals())
test.write('f1.in', "f1.in\n")
test.write('f2.in', "f2.in\n")
-expect = test.wrap_stdout("%s build.py -f1.out\n%s build.py -f2.out\n" % (python, python))
+expect = test.wrap_stdout('%(_python_)s build.py -f1.out\n%(_python_)s build.py -f2.out\n' % locals())
test.run(arguments = '-- -f1.out -f2.out', stdout = expect)
import TestSCons
import os
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """
import SCons.Defaults
-B = Builder(action=r'%s build.py $TARGET $SOURCES')
+B = Builder(action=r'%(_python_)s build.py $TARGET $SOURCES')
env = Environment()
env['BUILDERS']['B'] = B
env.B(target = 'sub1/foo.out', source = 'sub1/foo.in')
Export('env')
SConscript('sub1/SConscript')
SConscript('sub2/SConscript')
-""" % python)
+""" % locals())
test.write(['sub1', 'SConscript'], """
Import('env')
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-MyBuild = Builder(action = r'%s build.py $TARGET')
+MyBuild = Builder(action = r'%(_python_)s build.py $TARGET')
env = Environment(BUILDERS = { 'MyBuild' : MyBuild })
env.MyBuild(target = 'f1.out', source = 'f1.in')
env.MyBuild(target = 'f2.out', source = 'f2.in')
-""" % python)
+""" % locals())
test.write('f1.in', "f1.in\n")
test.write('f2.in', "f2.in\n")
test.run(arguments = '-Q f1.out f2.out', stdout = """\
-%s build.py f1.out
-%s build.py f2.out
-""" % (python, python))
+%(_python_)s build.py f1.out
+%(_python_)s build.py f2.out
+""" % locals())
test.fail_test(not os.path.exists(test.workpath('f1.out')))
test.fail_test(not os.path.exists(test.workpath('f2.out')))
test = TestSCons.TestSCons()
-python = TestSCons.python
+_python_ = TestSCons._python_
test.subdir('sub1', 'sub2', 'sub3')
test.write('SConstruct', r"""
import SCons.Defaults
env = Environment()
-env['BUILDERS']['B'] = Builder(action=r'%s build.py $TARGET $SOURCES', multi=1)
+env['BUILDERS']['B'] = Builder(action=r'%(_python_)s build.py $TARGET $SOURCES', multi=1)
Default(env.B(target = 'sub1/foo.out', source = 'sub1/foo.in'))
Export('env')
SConscript('sub2/SConscript')
SConscript('sub2b/SConscript')
Default(env.B(target = 'sub2/xxx.out', source = 'xxx.in'))
SConscript('SConscript')
-""" % python)
+""" % locals())
test.write(['sub2', 'SConscript'], """
Import('env')
""")
test.write(['repository', 'aaa.c'], r"""
+#include <stdio.h>
void
aaa(void)
{
""")
test.write(['repository', 'bbb.c'], r"""
+#include <stdio.h>
void
bbb(void)
{
""")
test.write(['repository', 'foo.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
extern void aaa(void);
extern void bbb(void);
int
#
test.write(['work1', 'bbb.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
void
bbb(void)
{
#
test.write(['work1', 'aaa.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
void
aaa(void)
{
""")
test.write(['work1', 'foo.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
extern void aaa(void);
extern void bbb(void);
int
test.write(['r.NEW', 'SConstruct'], SConstruct)
test.write(['r.OLD', 'foo.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
int
main(int argc, char *argv[])
{
test.writable('r.NEW', 1)
test.write(['r.NEW', 'foo.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
int
main(int argc, char *argv[])
{
#
test.write(['work2', 'foo.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
int
main(int argc, char *argv[])
{
test.writable('r.NEW', 1)
test.write(['r.OLD', 'foo.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
int
main(int argc, char *argv[])
{
""")
test.write(['r.NEW', 'foo.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
int
main(int argc, char *argv[])
{
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
_exe = TestSCons._exe
_obj = TestSCons._obj
file.close()
""")
+cache = test.workpath('cache')
+
test.write(['src1', 'SConstruct'], """
def cat(env, source, target):
target = str(target[0])
f.write(open(src, "rb").read())
f.close()
env = Environment(BUILDERS={'Internal':Builder(action=cat),
- 'External':Builder(action='%s build.py $TARGET $SOURCES')})
+ 'External':Builder(action='%(_python_)s build.py $TARGET $SOURCES')})
env.External('aaa.out', 'aaa.in')
env.External('bbb.out', 'bbb.in')
env.Internal('ccc.out', 'ccc.in')
env.Internal('all', ['aaa.out', 'bbb.out', 'ccc.out'])
-CacheDir(r'%s')
-""" % (python, test.workpath('cache')))
+CacheDir(r'%(cache)s')
+""" % locals())
test.write(['src1', 'aaa.in'], "aaa.in\n")
test.write(['src1', 'bbb.in'], "bbb.in\n")
# Verify that using --cache-show reports the files as being rebuilt,
# even though we actually fetch them from the cache. Then clean up.
-test.run(chdir = 'src1',
- arguments = '--cache-show .',
- stdout = test.wrap_stdout("""\
-%s build.py aaa.out aaa.in
-%s build.py bbb.out bbb.in
+expect = test.wrap_stdout("""\
+%(_python_)s build.py aaa.out aaa.in
+%(_python_)s build.py bbb.out bbb.in
cat(["ccc.out"], ["ccc.in"])
cat(["all"], ["aaa.out", "bbb.out", "ccc.out"])
-""" % (python, python)))
+""" % locals())
+
+test.run(chdir = 'src1', arguments = '--cache-show .', stdout = expect)
test.must_not_exist(test.workpath('src1', 'cat.out'))
# Verify that using --cache-show -n reports the files as being rebuilt,
# even though we don't actually fetch them from the cache. No need to
# clean up.
-test.run(chdir = 'src1',
- arguments = '--cache-show -n .',
- stdout = test.wrap_stdout("""\
-%s build.py aaa.out aaa.in
-%s build.py bbb.out bbb.in
+expect = test.wrap_stdout("""\
+%(_python_)s build.py aaa.out aaa.in
+%(_python_)s build.py bbb.out bbb.in
cat(["ccc.out"], ["ccc.in"])
cat(["all"], ["aaa.out", "bbb.out", "ccc.out"])
-""" % (python, python)))
+""" % locals())
+
+test.run(chdir = 'src1', arguments = '--cache-show -n .', stdout = expect)
test.must_not_exist(test.workpath('src1', 'cat.out'))
""" % (test.workpath('cache')))
test.write(['src2', 'hello.c'], r"""\
+#include <stdio.h>
+#include <stdlib.h>
int
main(int argc, char *argv[])
{
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
-import TestSCons
import sys
import string
import re
import time
+import TestSCons
+
+_python_ = TestSCons._python_
+
test = TestSCons.TestSCons()
test.write('SConstruct', """
test.run(arguments = "--debug=pdb", stdin = "n\ns\nq\n")
test.fail_test(string.find(test.stdout(), "(Pdb)") == -1)
-test.fail_test(string.find(test.stdout(), "scons") == -1)
+test.fail_test(string.find(test.stdout(), "SCons") == -1)
############################
# test --debug=presub
TEMP = Builder(action="$TEMPCOM")
LIST = Builder(action="$LISTCOM")
FUNC = Builder(action=cat)
-env = Environment(PYTHON='%s',
+env = Environment(PYTHON='%(_python_)s',
BUILDERS = {'FILE':FILE, 'TEMP':TEMP, 'LIST':LIST, 'FUNC':FUNC},
FILECOM="$PYTHON cat.py $SOURCES $TARGET",
TEMPCOM="$PYTHON cat.py $SOURCES temp\\n$PYTHON cat.py temp $TARGET",
env.LIST('file16.out', 'file16.in')
env.FUNC('file17.out', 'file17.in')
env.FUNC('file18.out', 'file18.in')
-""" % TestSCons.python)
+""" % locals())
test.write('file01.in', "file01.in\n")
test.write('file02.in', "file02.in\n")
expect = """\
Building file01.out with action:
$PYTHON cat.py $SOURCES $TARGET
-__PYTHON__ cat.py file01.in file01.out
+%(_python_)s cat.py file01.in file01.out
Building file02.out with action:
$PYTHON cat.py $SOURCES $TARGET
-__PYTHON__ cat.py file02.in file02.out
+%(_python_)s cat.py file02.in file02.out
Building file03.out with action:
$PYTHON cat.py $SOURCES temp
-__PYTHON__ cat.py file03.in temp
+%(_python_)s cat.py file03.in temp
Building file03.out with action:
$PYTHON cat.py temp $TARGET
-__PYTHON__ cat.py temp file03.out
+%(_python_)s cat.py temp file03.out
Building file04.out with action:
$PYTHON cat.py $SOURCES temp
-__PYTHON__ cat.py file04.in temp
+%(_python_)s cat.py file04.in temp
Building file04.out with action:
$PYTHON cat.py temp $TARGET
-__PYTHON__ cat.py temp file04.out
+%(_python_)s cat.py temp file04.out
Building file05.out with action:
$PYTHON cat.py $SOURCES temp
-__PYTHON__ cat.py file05.in temp
+%(_python_)s cat.py file05.in temp
Building file05.out with action:
$PYTHON cat.py temp $TARGET
-__PYTHON__ cat.py temp file05.out
+%(_python_)s cat.py temp file05.out
Building file06.out with action:
$PYTHON cat.py $SOURCES temp
-__PYTHON__ cat.py file06.in temp
+%(_python_)s cat.py file06.in temp
Building file06.out with action:
$PYTHON cat.py temp $TARGET
-__PYTHON__ cat.py temp file06.out
+%(_python_)s cat.py temp file06.out
Building file07.out with action:
cat(target, source, env)
cat(["file07.out"], ["file07.in"])
cat(["file09.out"], ["file09.in"])
Building file11.out with action:
$PYTHON cat.py $SOURCES $TARGET
-__PYTHON__ cat.py file11.in file11.out
+%(_python_)s cat.py file11.in file11.out
Building file12.out with action:
$PYTHON cat.py $SOURCES $TARGET
-__PYTHON__ cat.py file12.in file12.out
+%(_python_)s cat.py file12.in file12.out
Building file13.out with action:
$PYTHON cat.py $SOURCES temp
-__PYTHON__ cat.py file13.in temp
+%(_python_)s cat.py file13.in temp
Building file13.out with action:
$PYTHON cat.py temp $TARGET
-__PYTHON__ cat.py temp file13.out
+%(_python_)s cat.py temp file13.out
Building file14.out with action:
$PYTHON cat.py $SOURCES temp
-__PYTHON__ cat.py file14.in temp
+%(_python_)s cat.py file14.in temp
Building file14.out with action:
$PYTHON cat.py temp $TARGET
-__PYTHON__ cat.py temp file14.out
+%(_python_)s cat.py temp file14.out
Building file15.out with action:
$PYTHON cat.py $SOURCES temp
-__PYTHON__ cat.py file15.in temp
+%(_python_)s cat.py file15.in temp
Building file15.out with action:
$PYTHON cat.py temp $TARGET
-__PYTHON__ cat.py temp file15.out
+%(_python_)s cat.py temp file15.out
Building file16.out with action:
$PYTHON cat.py $SOURCES temp
-__PYTHON__ cat.py file16.in temp
+%(_python_)s cat.py file16.in temp
Building file16.out with action:
$PYTHON cat.py temp $TARGET
-__PYTHON__ cat.py temp file16.out
+%(_python_)s cat.py temp file16.out
Building file17.out with action:
cat(target, source, env)
cat(["file17.out"], ["file17.in"])
Building file18.out with action:
cat(target, source, env)
cat(["file18.out"], ["file18.in"])
-"""
-expect = string.replace(expect, '__PYTHON__', TestSCons.python)
+""" % locals()
+
test.run(arguments = "--debug=presub .", stdout=test.wrap_stdout(expect))
test.must_match('file01.out', "file01.in\n")
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-B = Builder(action = r'%s build.py $TARGETS $SOURCES')
+B = Builder(action = r'%(_python_)s build.py $TARGETS $SOURCES')
env = Environment(BUILDERS = { 'B' : B })
env.B(target = 'f1.out', source = 'f1.in')
env.B(target = 'f2.out', source = 'f2.in')
-""" % python)
+""" % locals())
test.write('f1.in', "f1.in\n")
test.write('f2.in', "f2.in\n")
test.run(arguments = 'f1.out f2.out',
stdout = test.wrap_stdout(
"""scons: `f1.out' is up to date.
-%s build.py f2.out f2.in
-""" % python))
+%(_python_)s build.py f2.out f2.in
+""" % locals()))
atime = os.path.getatime(test.workpath('f1.in'))
mtime = os.path.getmtime(test.workpath('f1.in'))
test.up_to_date(options='--max-drift=0', arguments='f1.out f2.out')
-test.run(arguments = '--max-drift=-1 f1.out f2.out',
- stdout = test.wrap_stdout(
-"""%s build.py f1.out f1.in
+expect = test.wrap_stdout(
+"""%(_python_)s build.py f1.out f1.in
scons: `f2.out' is up to date.
-""" % python))
+""" % locals())
+
+test.run(arguments = '--max-drift=-1 f1.out f2.out', stdout = expect)
# Test that Set/GetOption('max_drift') works:
test.write('SConstruct', """
# by mucking with the file timestamps to make SCons not realize the source has changed
test.write('SConstruct', """
SetOption('max_drift', 0)
-B = Builder(action = r'%s build.py $TARGETS $SOURCES')
+B = Builder(action = r'%(_python_)s build.py $TARGETS $SOURCES')
env = Environment(BUILDERS = { 'B' : B })
env.B(target = 'foo.out', source = 'foo.in')
-""" % python)
+""" % locals())
test.write('foo.in', 'foo.in\n')
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-B = Builder(action = r'%s build.py $TARGETS $SOURCES')
+B = Builder(action = r'%(_python_)s build.py $TARGETS $SOURCES')
env = Environment(BUILDERS = { 'B' : B })
env.B(target = 'foo1.out', source = 'foo1.in')
env.B(target = 'foo2.out', source = 'foo2.xxx')
env.Command(['touch1.out', 'touch2.out'],
[],
[Touch('${TARGETS[0]}'), Touch('${TARGETS[1]}')])
-""" % python)
+""" % locals())
test.write('foo1.in', "foo1.in\n")
test.write('aux1.x', "aux1.x\n")
test.write('aux2.x', "aux2.x\n")
test.write('SConstruct', """
-B = Builder(action = r'%s build.py $TARGETS $SOURCES')
+B = Builder(action = r'%(_python_)s build.py $TARGETS $SOURCES')
env = Environment(BUILDERS = { 'B' : B }, FOO = 'foo2')
env.B(target = 'foo1.out', source = 'foo1.in')
env.B(target = 'foo2.out', source = 'foo2.xxx')
Clean(foo2_xxx, ['aux1.x'])
env.Clean(['${FOO}.xxx'], ['aux2.x'])
Clean('.', ['subd'])
-""" % python)
+""" % locals())
test.write(['subd', 'SConscript'], """
Clean('.', 'foox.in')
# Ensure that Set/GetOption('clean') works correctly:
test.write('SConstruct', """
-B = Builder(action = r'%s build.py $TARGETS $SOURCES')
+B = Builder(action = r'%(_python_)s build.py $TARGETS $SOURCES')
env = Environment(BUILDERS = { 'B' : B })
env.B(target = 'foo.out', source = 'foo.in')
assert not GetOption('clean')
-"""%python)
+""" % locals())
test.write('foo.in', '"Foo", I say!\n')
test.must_match(test.workpath('foo.out'), '"Foo", I say!\n')
test.write('SConstruct', """
-B = Builder(action = r'%s build.py $TARGETS $SOURCES')
+B = Builder(action = r'%(_python_)s build.py $TARGETS $SOURCES')
env = Environment(BUILDERS = { 'B' : B })
env.B(target = 'foo.out', source = 'foo.in')
assert GetOption('clean')
SetOption('clean', 0)
assert GetOption('clean')
-"""%python)
+""" % locals())
test.run(arguments='-c foo.out')
test.must_not_exist(test.workpath('foo.out'))
test.write('SConstruct', """
-B = Builder(action = r'%s build.py $TARGETS $SOURCES')
+B = Builder(action = r'%(_python_)s build.py $TARGETS $SOURCES')
env = Environment(BUILDERS = { 'B' : B })
env.B(target = 'foo.out', source = 'foo.in')
-"""%python)
+""" % locals())
test.run(arguments='foo.out')
test.must_match(test.workpath('foo.out'), '"Foo", I say!\n')
test.write('SConstruct', """
-B = Builder(action = r'%s build.py $TARGETS $SOURCES')
+B = Builder(action = r'%(_python_)s build.py $TARGETS $SOURCES')
env = Environment(BUILDERS = { 'B' : B })
env.B(target = 'foo.out', source = 'foo.in')
assert not GetOption('clean')
SetOption('clean', 1)
assert GetOption('clean')
-"""%python)
+""" % locals())
test.run(arguments='foo.out')
test.must_not_exist(test.workpath('foo.out'))
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-Succeed = Builder(action = r'%s succeed.py $TARGETS')
-Fail = Builder(action = r'%s fail.py $TARGETS')
+Succeed = Builder(action = r'%(_python_)s succeed.py $TARGETS')
+Fail = Builder(action = r'%(_python_)s fail.py $TARGETS')
env = Environment(BUILDERS = { 'Succeed' : Succeed, 'Fail' : Fail })
env.Fail(target = 'aaa.1', source = 'aaa.in')
env.Succeed(target = 'aaa.out', source = 'aaa.1')
env.Fail(target = 'bbb.1', source = 'bbb.in')
env.Succeed(target = 'bbb.out', source = 'bbb.1')
-""" % (python, python))
+""" % locals())
test.write('aaa.in', "aaa.in\n")
test.write('bbb.in', "bbb.in\n")
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
try:
import threading
""")
test.write('SConstruct', """
-MyBuild = Builder(action = r'%s build.py $TARGETS')
+MyBuild = Builder(action = r'%(_python_)s build.py $TARGETS')
env = Environment(BUILDERS = { 'MyBuild' : MyBuild })
env.MyBuild(target = 'f1', source = 'f1.in')
env.MyBuild(target = 'f2', source = 'f2.in')
source='foo/foo.in',
action=copyn)
env.Install('out', t)
-""" % python)
+""" % locals())
def RunTest(args, extra):
"""extra is used to make scons rebuild the output file"""
# Test SetJobs() with no -j:
test.write('SConstruct', """
-MyBuild = Builder(action = r'%s build.py $TARGETS')
+MyBuild = Builder(action = r'%(_python_)s build.py $TARGETS')
env = Environment(BUILDERS = { 'MyBuild' : MyBuild })
env.MyBuild(target = 'f1', source = 'f1.in')
env.MyBuild(target = 'f2', source = 'f2.in')
assert GetOption('num_jobs') == 1
SetOption('num_jobs', 2)
assert GetOption('num_jobs') == 2
-""" % python)
+""" % locals())
# This should be a parallel build because the SConscript sets jobs to 2.
# fail if the second file was not started
# Test SetJobs() with -j:
test.write('SConstruct', """
-MyBuild = Builder(action = r'%s build.py $TARGETS')
+MyBuild = Builder(action = r'%(_python_)s build.py $TARGETS')
env = Environment(BUILDERS = { 'MyBuild' : MyBuild })
env.MyBuild(target = 'f1', source = 'f1.in')
env.MyBuild(target = 'f2', source = 'f2.in')
assert GetOption('num_jobs') == 1
SetOption('num_jobs', 2)
assert GetOption('num_jobs') == 1
-""" % python)
+""" % locals())
# This should be a serial build since -j 1 overrides the call to SetJobs().
# fail if the second file was started
""")
test.write('SConstruct', """
-MyCopy = Builder(action = r'%s mycopy.py $TARGET $SOURCE')
-Fail = Builder(action = r'%s myfail.py $TARGETS $SOURCE')
+MyCopy = Builder(action = r'%(_python_)s mycopy.py $TARGET $SOURCE')
+Fail = Builder(action = r'%(_python_)s myfail.py $TARGETS $SOURCE')
env = Environment(BUILDERS = { 'MyCopy' : MyCopy, 'Fail' : Fail })
env.Fail(target = 'f3', source = 'f3.in')
env.MyCopy(target = 'f4', source = 'f4.in')
env.MyCopy(target = 'f5', source = 'f5.in')
env.MyCopy(target = 'f6', source = 'f6.in')
-""" % (python, python))
+""" % locals())
test.write('f3.in', "f3.in\n")
test.write('f4.in', "f4.in\n")
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
""")
test.write(['work1', 'SConstruct'], """\
-Succeed = Builder(action = r'%s ../succeed.py $TARGETS')
-Fail = Builder(action = r'%s ../fail.py $TARGETS')
+Succeed = Builder(action = r'%(_python_)s ../succeed.py $TARGETS')
+Fail = Builder(action = r'%(_python_)s ../fail.py $TARGETS')
env = Environment(BUILDERS = { 'Succeed' : Succeed, 'Fail' : Fail })
env.Fail(target = 'aaa.1', source = 'aaa.in')
env.Succeed(target = 'aaa.out', source = 'aaa.1')
env.Succeed(target = 'bbb.out', source = 'bbb.in')
-""" % (python, python))
+""" % locals())
test.write(['work1', 'aaa.in'], "aaa.in\n")
test.write(['work1', 'bbb.in'], "bbb.in\n")
test.write(['work2', 'SConstruct'], """\
-Succeed = Builder(action = r'%s ../succeed.py $TARGETS')
-Fail = Builder(action = r'%s ../fail.py $TARGETS')
+Succeed = Builder(action = r'%(_python_)s ../succeed.py $TARGETS')
+Fail = Builder(action = r'%(_python_)s ../fail.py $TARGETS')
env = Environment(BUILDERS = { 'Succeed' : Succeed, 'Fail' : Fail })
env.Fail('aaa.out', 'aaa.in')
env.Succeed('bbb.out', 'aaa.out')
env.Succeed('ccc.out', 'ccc.in')
env.Succeed('ddd.out', 'ccc.in')
-""" % (python, python))
+""" % locals())
test.write(['work2', 'aaa.in'], "aaa.in\n")
test.write(['work2', 'ccc.in'], "ccc.in\n")
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
-%s ../fail.py aaa.out
-%s ../succeed.py ccc.out
-%s ../succeed.py ddd.out
+%(_python_)s ../fail.py aaa.out
+%(_python_)s ../succeed.py ccc.out
+%(_python_)s ../succeed.py ddd.out
scons: done building targets (errors occurred during build).
-""" % (python, python, python))
+""" % locals())
test.must_not_exist(['work2', 'aaa.out'])
test.must_not_exist(['work2', 'bbb.out'])
import TestCmd
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-MyBuild = Builder(action = r'%s build.py $TARGETS')
+MyBuild = Builder(action = r'%(_python_)s build.py $TARGETS')
env = Environment(BUILDERS = { 'MyBuild' : MyBuild })
env.MyBuild(target = 'f1.out', source = 'f1.in')
env.MyBuild(target = 'f2.out', source = 'f2.in')
env.Install('install', 'f3.in')
BuildDir('build', 'src', duplicate=1)
SConscript('build/SConscript', "env")
-""" % python)
+""" % locals())
test.write(['src', 'SConscript'], """
Import("env")
args = 'f1.out f2.out'
expect = test.wrap_stdout("""\
-%s build.py f1.out
-%s build.py f2.out
-""" % (python, python))
+%(_python_)s build.py f1.out
+%(_python_)s build.py f2.out
+""" % locals())
test.run(arguments = args, stdout = expect)
test.fail_test(not os.path.exists(test.workpath('f1.out')))
# Test that SCons does not write a modified .sconsign when -n is used.
expect = test.wrap_stdout("""\
-%s build.py f1.out
-""" % python)
+%(_python_)s build.py f1.out
+""" % locals())
test.unlink('.sconsign.dblite')
test.write('f1.out', "X1.out\n")
test.run(arguments = '-n f1.out', stdout = expect)
test = TestSCons.TestSCons()
-python = TestSCons.python
+_python_ = TestSCons._python_
test.write('build.py', r"""
import sys
""")
test.write('SConstruct', """
-B = Builder(action=r'%s build.py $TARGET $SOURCES')
+B = Builder(action=r'%(_python_)s build.py $TARGET $SOURCES')
env = Environment(BUILDERS = { 'B' : B })
env.B(target = 'aaa.out', source = 'aaa.in')
env.B(target = 'bbb.out', source = 'bbb.in')
-""" % python)
+""" % locals())
test.write('aaa.in', "aaa.in\n")
test.write('bbb.in', "bbb.in\n")
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-MyBuild = Builder(action = r'%s build.py $TARGET')
+MyBuild = Builder(action = r'%(_python_)s build.py $TARGET')
env = Environment(BUILDERS = { 'MyBuild' : MyBuild })
env.MyBuild(target = 'f1.out', source = 'f1.in')
env.MyBuild(target = 'f2.out', source = 'f2.in')
-""" % python)
+""" % locals())
test.write('f1.in', "f1.in\n")
test.write('f2.in', "f2.in\n")
""")
test.write('foo.c', r"""
+#include <stdio.h>
+#include <stdlib.h>
#include "foo.h"
int main(int argc, char *argv[])
{
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
-import TestSCons
import sys
import string
import re
import time
+import TestSCons
+
+_python_ = TestSCons._python_
+
test = TestSCons.TestSCons()
test.subdir('sub1', 'sub2')
LIBS = ['iii', 'jjj', 'kkk', 'lll', 'mmm'],
LIBPREFIXES = ['a-', 'b-', 'c-'],
LIBSUFFIXES = ['.aaa', '.bbb', '.ccc'],
- LINKCOM = '%(python)s cat.py $TARGET $SOURCES')
+ LINKCOM = '%(_python_)s cat.py $TARGET $SOURCES')
env.Program('foo', 'a.ooo',)
-""" % {'python' : TestSCons.python})
+""" % locals())
test.write('a.ooo', "a.ooo\n")
findlibs: looking for 'c-mmm.ccc' in 'sub1' ...
findlibs: looking for 'c-mmm.ccc' in 'sub2' ...
findlibs: looking for 'c-mmm.ccc' in '.' ...
-%(python)s cat.py foo.xxx a.ooo
-""" % {'python' : TestSCons.python}))
+%(_python_)s cat.py foo.xxx a.ooo
+""" % locals()))
test.must_match('foo.xxx', "a.ooo\n")
""")
test.write('foo.c', r"""
+#include <stdio.h>
+#include <stdlib.h>
#include "foo.h"
int main(int argc, char *argv[])
{
+# Test that full path names to SConscript files show up in stack traces.
+
+test.write('SConstruct', """\
+1/0
+""")
+
+test.run(arguments = '--debug=stacktrace',
+ status = 2,
+ stderr = None)
+
+lines = [
+ ' File "%s", line 1:' % test.workpath('SConstruct'),
+]
+
+err = must_contain_all_lines(test.stderr(), lines)
+if err:
+ print string.join(err, '')
+ test.fail_test(1)
+
+
+
test.pass_test()
""")
test.write('foo.c', r"""
+#include <stdio.h>
+#include <stdlib.h>
#include "foo.h"
int main(int argc, char *argv[])
{
""")
test.write('foo.c', r"""
+#include <stdio.h>
+#include <stdlib.h>
#include "foo.h"
int main(int argc, char *argv[])
{
# (UNIX/Linux) and case-insensitive (Windows) systems.
test.write('Foo.c', r"""
+#include <stdio.h>
+#include <stdlib.h>
#include "Foo.h"
int main(int argc, char *argv[])
{
test = TestSCons.TestSCons()
-test.write('SConstruct', "\n")
+test.write('SConstruct', """\
+Command('file.out', 'file.in', Copy("$TARGET", "$SOURCE"))
+""")
+
+test.write('file.in', "file.in\n")
scons_prof = test.workpath('scons.prof')
scons_prof = test.workpath('scons2.prof')
-test.run(arguments = "--profile %s -h" % scons_prof)
-test.fail_test(string.find(test.stdout(), 'usage: scons [OPTION]') == -1)
-test.fail_test(string.find(test.stdout(), 'Options:') == -1)
+test.run(arguments = "--profile %s" % scons_prof)
stats = pstats.Stats(scons_prof)
stats.sort_stats('time')
-sys.stdout = StringIO.StringIO()
+try:
+ save_stdout = sys.stdout
+ sys.stdout = StringIO.StringIO()
-stats.strip_dirs().print_stats()
+ stats.strip_dirs().print_stats()
-s = sys.stdout.getvalue()
+ s = sys.stdout.getvalue()
+finally:
+ sys.stdout = save_stdout
test.fail_test(string.find(s, 'Main.py') == -1)
-test.fail_test(string.find(s, 'print_help') == -1)
test.fail_test(string.find(s, '_main') == -1)
-test.fail_test(string.find(s, 'option_parser.py') == -1)
+test.fail_test(string.find(s, 'FS.py') == -1)
scons_prof = test.workpath('scons3.prof')
test.run(arguments = "--profile %s --debug=memory -h" % scons_prof)
-print test.stdout()
test.fail_test(string.find(test.stdout(), 'usage: scons [OPTION]') == -1)
test.fail_test(string.find(test.stdout(), 'Options:') == -1)
test = TestSCons.TestSCons()
-python = TestSCons.python
+_python_ = TestSCons._python_
test.write('SConstruct', """
env = Environment(CCFLAGS='-DFOO', LIBS=['a'])
test.write('SConstruct', """
env = Environment()
env.Program('hello', 'hello.c',
- CC=r'%s mycc.py',
- LINK=r'%s mylink.py',
+ CC=r'%(_python_)s mycc.py',
+ LINK=r'%(_python_)s mylink.py',
OBJSUFFIX='.not_obj',
PROGSUFFIX='.not_exe')
-"""%(python,python))
+""" % locals())
test.write('hello.c',"this ain't no c file!\n")
test.write('SConstruct', """\
env = Environment()
env.Program('goodbye', 'goodbye.c',
- CC=r'%s mycc.py',
- LINK=r'%s mylink.py',
+ CC=r'%(_python_)s mycc.py',
+ LINK=r'%(_python_)s mylink.py',
OBJSUFFIX='.not_obj',
PROGSUFFIX='.not_exe',
targets='ttt',
sources='sss')
-""" % (python, python))
+""" % locals())
test.write('goodbye.c',"this ain't no c file!\n")
import os
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', r"""
env = Environment()
env.Command(target='foo1', source='bar1',
- action= '%s cat.py $SOURCES > $TARGET')
+ action= '%(_python_)s cat.py $SOURCES > $TARGET')
env.Command(target='foo2', source='bar2',
- action= '%s cat.py < $SOURCES > $TARGET')
+ action= '%(_python_)s cat.py < $SOURCES > $TARGET')
env.Command(target='foo3', source='bar3',
- action='%s cat.py $SOURCES | %s cat.py > $TARGET')
+ action='%(_python_)s cat.py $SOURCES | %(_python_)s cat.py > $TARGET')
env.Command(target='foo4', source='bar4',
- action='%s cat.py <$SOURCES |%s cat.py >$TARGET')
-""" % (python, python, python, python, python, python))
+ action='%(_python_)s cat.py <$SOURCES |%(_python_)s cat.py >$TARGET')
+""" % locals())
test.write('bar1', 'bar1\r\n')
test.write('bar2', 'bar2\r\n')
--- /dev/null
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Test writing Aegis batch output to a file.
+"""
+
+import TestRuntest
+
+test = TestRuntest.TestRuntest()
+
+test.subdir('test')
+
+test.write_failing_test(['test', 'fail.py'])
+
+test.write_no_result_test(['test', 'no_result.py'])
+
+test.write_passing_test(['test', 'pass.py'])
+
+test.run(arguments = '-o aegis.out --aegis test', status=1)
+
+expect = """\
+test_result = [
+ { file_name = "test/fail.py";
+ exit_status = 1; },
+ { file_name = "test/no_result.py";
+ exit_status = 2; },
+ { file_name = "test/pass.py";
+ exit_status = 0; },
+];
+"""
+
+# The mode is 'r' (not default 'rb') because QMTest opens the file
+# description on which we write as non-binary.
+test.must_match('aegis.out', expect, mode='r')
+
+test.pass_test()
test with no argument on the command line.
"""
+import os.path
+
import TestRuntest
+test_fail_py = os.path.join('test', 'fail.py')
+test_no_result_py = os.path.join('test', 'no_result.py')
+test_pass_py = os.path.join('test', 'pass.py')
+
test = TestRuntest.TestRuntest()
test.subdir('test')
# NOTE: The "test/fail.py : FAIL" and "test/pass.py : PASS" lines both
# have spaces at the end.
-expect = r"""qmtest.py run --output baseline.qmr --format none --result-stream=scons_tdb.AegisBaselineStream test
+expect = r"""qmtest.py run --output baseline.qmr --format none --result-stream="scons_tdb.AegisBaselineStream" test
--- TEST RESULTS -------------------------------------------------------------
- test/fail.py : FAIL
+ %(test_fail_py)s : FAIL
FAILING TEST STDOUT
FAILING TEST STDERR
- test/no_result.py : NO_RESULT
+ %(test_no_result_py)s : NO_RESULT
NO RESULT TEST STDOUT
NO RESULT TEST STDERR
- test/pass.py : PASS
+ %(test_pass_py)s : PASS
--- TESTS WITH UNEXPECTED OUTCOMES -------------------------------------------
- test/no_result.py : NO_RESULT
+ %(test_no_result_py)s : NO_RESULT
- test/pass.py : PASS
+ %(test_pass_py)s : PASS
--- STATISTICS ---------------------------------------------------------------
- 1 ( 33%) tests as expected
- 1 ( 33%) tests unexpected PASS
- 1 ( 33%) tests unexpected NO_RESULT
-"""
+ 1 ( 33%%) tests as expected
+ 1 ( 33%%) tests unexpected PASS
+ 1 ( 33%%) tests unexpected NO_RESULT
+""" % locals()
-test.run(arguments = '--qmtest -b . test', stdout = expect)
+test.run(arguments = '-b . test', status = 1, stdout = expect)
test.pass_test()
# NOTE: The "test/fail.py : FAIL" line has spaces at the end.
-expect = r"""qmtest.py run --output baseline.qmr --format none --result-stream=scons_tdb.AegisBaselineStream test/fail.py
+expect = r"""qmtest.py run --output baseline.qmr --format none --result-stream="scons_tdb.AegisBaselineStream" test/fail.py
--- TEST RESULTS -------------------------------------------------------------
test/fail.py : FAIL
1 (100%) tests as expected
"""
-test.run(arguments = '--qmtest -b . test/fail.py', stdout = expect)
+test.run(arguments = '-b . test/fail.py', status = 1, stdout = expect)
test.pass_test()
test.write_no_result_test(['test', 'no_result.py'])
-expect = r"""qmtest.py run --output baseline.qmr --format none --result-stream=scons_tdb.AegisBaselineStream test/no_result.py
+expect = r"""qmtest.py run --output baseline.qmr --format none --result-stream="scons_tdb.AegisBaselineStream" test/no_result.py
--- TEST RESULTS -------------------------------------------------------------
test/no_result.py : NO_RESULT
1 (100%) tests unexpected NO_RESULT
"""
-test.run(arguments = '--qmtest -b . test/no_result.py', stdout = expect)
+test.run(arguments = '-b . test/no_result.py', status = 1, stdout = expect)
test.pass_test()
# NOTE: The "test/pass.py : PASS" line has spaces at the end.
-expect = r"""qmtest.py run --output baseline.qmr --format none --result-stream=scons_tdb.AegisBaselineStream test/pass.py
+expect = r"""qmtest.py run --output baseline.qmr --format none --result-stream="scons_tdb.AegisBaselineStream" test/pass.py
--- TEST RESULTS -------------------------------------------------------------
test/pass.py : PASS
1 (100%) tests unexpected PASS
"""
-test.run(arguments = '--qmtest -b . test/pass.py', stdout = expect)
+test.run(arguments = '-b . test/pass.py', stdout = expect)
test.pass_test()
--- /dev/null
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Test that runtest.py falls back (with a warning) using --noqmtest
+if it can't find qmtest.py on the $PATH.
+"""
+
+import os
+import os.path
+import re
+import string
+
+import TestRuntest
+
+python = TestRuntest.python
+_python_ = TestRuntest._python_
+
+test = TestRuntest.TestRuntest(noqmtest=1)
+
+qmtest_py = test.where_is('qmtest.py')
+
+if qmtest_py:
+ dir = os.path.split(qmtest_py)[0]
+ path = string.split(os.environ['PATH'], os.pathsep)
+ path.remove(dir)
+ os.environ['PATH'] = string.join(path, os.pathsep)
+
+test.subdir('test')
+
+test_pass_py = os.path.join('test', 'pass.py')
+test_fail_py = os.path.join('test', 'fail.py')
+test_no_result_py = os.path.join('test', 'no_result.py')
+
+workpath_pass_py = test.workpath(test_pass_py)
+workpath_fail_py = test.workpath(test_fail_py)
+workpath_no_result_py = test.workpath(test_no_result_py)
+
+test.write_failing_test(test_fail_py)
+test.write_no_result_test(test_no_result_py)
+test.write_passing_test(test_pass_py)
+
+if re.search('\s', python):
+ expect_python = _python_
+else:
+ expect_python = python
+
+expect_stdout = """\
+%(expect_python)s -tt %(workpath_fail_py)s
+FAILING TEST STDOUT
+%(expect_python)s -tt %(workpath_no_result_py)s
+NO RESULT TEST STDOUT
+%(expect_python)s -tt %(workpath_pass_py)s
+PASSING TEST STDOUT
+
+Failed the following test:
+\t%(test_fail_py)s
+
+NO RESULT from the following test:
+\t%(test_no_result_py)s
+""" % locals()
+
+expect_stderr = """\
+Warning: qmtest.py not found on $PATH, assuming --noqmtest option.
+FAILING TEST STDERR
+NO RESULT TEST STDERR
+PASSING TEST STDERR
+"""
+
+testlist = [
+ test_fail_py,
+ test_no_result_py,
+ test_pass_py,
+]
+
+test.run(arguments = string.join(testlist),
+ status = 1,
+ stdout = expect_stdout,
+ stderr = expect_stderr)
+
+test.pass_test()
--- /dev/null
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Test that the --noqmtest option invokes tests directly via Python, not
+using qmtest.
+"""
+
+import os.path
+import re
+import string
+
+import TestRuntest
+
+python = TestRuntest.python
+_python_ = TestRuntest._python_
+
+test = TestRuntest.TestRuntest(noqmtest=1)
+
+test.subdir('test')
+
+test_pass_py = os.path.join('test', 'pass.py')
+test_fail_py = os.path.join('test', 'fail.py')
+test_no_result_py = os.path.join('test', 'no_result.py')
+
+workpath_pass_py = test.workpath(test_pass_py)
+workpath_fail_py = test.workpath(test_fail_py)
+workpath_no_result_py = test.workpath(test_no_result_py)
+
+test.write_failing_test(test_fail_py)
+test.write_no_result_test(test_no_result_py)
+test.write_passing_test(test_pass_py)
+
+if re.search('\s', python):
+ expect_python = _python_
+else:
+ expect_python = python
+
+expect_stdout = """\
+%(expect_python)s -tt %(workpath_fail_py)s
+FAILING TEST STDOUT
+%(expect_python)s -tt %(workpath_no_result_py)s
+NO RESULT TEST STDOUT
+%(expect_python)s -tt %(workpath_pass_py)s
+PASSING TEST STDOUT
+
+Failed the following test:
+\t%(test_fail_py)s
+
+NO RESULT from the following test:
+\t%(test_no_result_py)s
+""" % locals()
+
+expect_stderr = """\
+FAILING TEST STDERR
+NO RESULT TEST STDERR
+PASSING TEST STDERR
+"""
+
+testlist = [
+ test_fail_py,
+ test_no_result_py,
+ test_pass_py,
+]
+
+test.run(arguments = '--noqmtest %s' % string.join(testlist),
+ status = 1,
+ stdout = expect_stdout,
+ stderr = expect_stderr)
+
+test.pass_test()
test with no argument on the command line.
"""
+import os.path
+import re
+
import TestCmd
import TestRuntest
+test_fail_py = re.escape(os.path.join('test', 'fail.py'))
+test_no_result_py = re.escape(os.path.join('test', 'no_result.py'))
+test_pass_py = re.escape(os.path.join('test', 'pass.py'))
+
test = TestRuntest.TestRuntest(match = TestCmd.match_re)
test.subdir('test')
# NOTE: The "test/fail.py : FAIL" and "test/pass.py : PASS" lines both
# have spaces at the end.
-expect = r"""qmtest.py run --output results.qmr --format none --result-stream=scons_tdb.AegisChangeStream --context print_time=1 test
+expect = r"""qmtest.py run --output results.qmr --format none --result-stream="scons_tdb.AegisChangeStream\(print_time='1'\)" test
--- TEST RESULTS -------------------------------------------------------------
- test/fail.py : FAIL
+ %(test_fail_py)s : FAIL
FAILING TEST STDOUT
Total execution time: \d+\.\d+ seconds
- test/no_result.py : NO_RESULT
+ %(test_no_result_py)s : NO_RESULT
NO RESULT TEST STDOUT
Total execution time: \d+\.\d+ seconds
- test/pass.py : PASS
+ %(test_pass_py)s : PASS
Total execution time: \d+\.\d+ seconds
--- TESTS THAT DID NOT PASS --------------------------------------------------
- test/fail.py : FAIL
+ %(test_fail_py)s : FAIL
- test/no_result.py : NO_RESULT
+ %(test_no_result_py)s : NO_RESULT
--- STATISTICS ---------------------------------------------------------------
3 tests total
- 1 \( 33%\) tests PASS
- 1 \( 33%\) tests FAIL
- 1 \( 33%\) tests NO_RESULT
-"""
+ 1 \( 33%%\) tests PASS
+ 1 \( 33%%\) tests FAIL
+ 1 \( 33%%\) tests NO_RESULT
+""" % locals()
-test.run(arguments = '--qmtest -t test', stdout = expect)
+test.run(arguments = '-t test', status = 1, stdout = expect)
test.pass_test()
Test that the -P option lets us specify a Python version to use.
"""
+import os.path
+import re
+import sys
+
+if not hasattr(os.path, 'pardir'):
+ os.path.pardir = '..'
+
import TestRuntest
test = TestRuntest.TestRuntest()
-mypython_py = test.workpath('mypython.py')
-mypython_out = test.workpath('mypython.out')
+test_pass_py = os.path.join('test', 'pass.py')
-test.subdir('test')
+head, python = os.path.split(TestRuntest.python)
+head, dir = os.path.split(head)
-test.write_passing_test(['test', 'pass.py'])
+mypython = os.path.join(head, dir, os.path.pardir, dir, python)
-test.write(mypython_py, """\
-#!/usr/bin/env python
-import os
-import sys
-import string
-open(r'%s', 'a').write(string.join(sys.argv) + '\\n')
-os.system(string.join([sys.executable] + sys.argv[1:]))
-""" % mypython_out)
+if re.search('\s', mypython):
+ _mypython_ = '"' + mypython + '"'
+else:
+ _mypython_ = mypython
-test.chmod(mypython_py, 0755)
+test.subdir('test')
+
+test.write_passing_test(['test', 'pass.py'])
# NOTE: The "test/fail.py : FAIL" and "test/pass.py : PASS" lines both
# have spaces at the end.
-expect = r"""qmtest.py run --output results.qmr --format none --result-stream=scons_tdb.AegisChangeStream --context python=%(mypython_py)s test
+expect = r"""qmtest.py run --output results.qmr --format none --result-stream="scons_tdb.AegisChangeStream" --context python="%(mypython)s" test
--- TEST RESULTS -------------------------------------------------------------
- test/pass.py : PASS
+ %(test_pass_py)s : PASS
--- TESTS THAT DID NOT PASS --------------------------------------------------
1 (100%%) tests PASS
""" % locals()
-test.run(arguments = '--qmtest -P %s test' % mypython_py,
- stdout = expect)
-
-test.must_match(mypython_out, """\
-%s ./test/pass.py
-""" % mypython_py)
+test.run(arguments = '-P %s test' % _mypython_, stdout = expect)
test.pass_test()
test with no argument on the command line.
"""
+import os.path
+
import TestRuntest
test = TestRuntest.TestRuntest()
+test_fail_py = os.path.join('test', 'fail.py')
+test_no_result_py = os.path.join('test', 'no_result.py')
+test_pass_py = os.path.join('test', 'pass.py')
+
test.subdir('test')
test.write_failing_test(['test', 'fail.py'])
# NOTE: The "test/fail.py : FAIL" and "test/pass.py : PASS" lines both
# have spaces at the end.
-expect = r"""qmtest.py run --output results.qmr --format none --result-stream=scons_tdb.AegisChangeStream test
+expect = r"""qmtest.py run --output results.qmr --format none --result-stream="scons_tdb.AegisChangeStream" test
--- TEST RESULTS -------------------------------------------------------------
- test/fail.py : FAIL
+ %(test_fail_py)s : FAIL
FAILING TEST STDOUT
FAILING TEST STDERR
- test/no_result.py : NO_RESULT
+ %(test_no_result_py)s : NO_RESULT
NO RESULT TEST STDOUT
NO RESULT TEST STDERR
- test/pass.py : PASS
+ %(test_pass_py)s : PASS
--- TESTS THAT DID NOT PASS --------------------------------------------------
- test/fail.py : FAIL
+ %(test_fail_py)s : FAIL
- test/no_result.py : NO_RESULT
+ %(test_no_result_py)s : NO_RESULT
--- STATISTICS ---------------------------------------------------------------
3 tests total
- 1 ( 33%) tests PASS
- 1 ( 33%) tests FAIL
- 1 ( 33%) tests NO_RESULT
-"""
+ 1 ( 33%%) tests PASS
+ 1 ( 33%%) tests FAIL
+ 1 ( 33%%) tests NO_RESULT
+""" % locals()
-test.run(arguments = '--qmtest test', stdout = expect)
+test.run(arguments = 'test', status = 1, stdout = expect)
test.pass_test()
# NOTE: The "test/fail.py : FAIL" line has spaces at the end.
-expect = r"""qmtest.py run --output results.qmr --format none --result-stream=scons_tdb.AegisChangeStream test/fail.py
+expect = r"""qmtest.py run --output results.qmr --format none --result-stream="scons_tdb.AegisChangeStream" test/fail.py
--- TEST RESULTS -------------------------------------------------------------
test/fail.py : FAIL
1 (100%) tests FAIL
"""
-test.run(arguments = '--qmtest test/fail.py', stdout = expect)
+test.run(arguments = 'test/fail.py', status = 1, stdout = expect)
test.pass_test()
test.write_no_result_test(['test', 'no_result.py'])
-expect = r"""qmtest.py run --output results.qmr --format none --result-stream=scons_tdb.AegisChangeStream test/no_result.py
+expect = r"""qmtest.py run --output results.qmr --format none --result-stream="scons_tdb.AegisChangeStream" test/no_result.py
--- TEST RESULTS -------------------------------------------------------------
test/no_result.py : NO_RESULT
1 (100%) tests NO_RESULT
"""
-test.run(arguments = '--qmtest test/no_result.py', stdout = expect)
+test.run(arguments = 'test/no_result.py', status = 1, stdout = expect)
test.pass_test()
# NOTE: The "test/pass.py : PASS" line has spaces at the end.
-expect = r"""qmtest.py run --output results.qmr --format none --result-stream=scons_tdb.AegisChangeStream test/pass.py
+expect = r"""qmtest.py run --output results.qmr --format none --result-stream="scons_tdb.AegisChangeStream" test/pass.py
--- TEST RESULTS -------------------------------------------------------------
test/pass.py : PASS
1 (100%) tests PASS
"""
-test.run(arguments = '--qmtest test/pass.py', stdout = expect)
+test.run(arguments = 'test/pass.py', stdout = expect)
test.pass_test()
with *Tests.py.
"""
+import os.path
+
import TestRuntest
test = TestRuntest.TestRuntest(verbose=1)
test.subdir(['src'],
['src', 'suite'])
+src_passTests_py = os.path.join('src', 'passTests.py')
+src_suite_passTests_py = os.path.join('src', 'suite', 'passTests.py')
+
test.write_passing_test(['src', 'pass.py'])
test.write_passing_test(['src', 'passTests.py'])
test.write_passing_test(['src', 'suite', 'passTests.py'])
-# NOTE: The "test/fail.py : FAIL" and "test/pass.py : PASS" lines both
-# have spaces at the end.
+# NOTE: The "test/pass.py : PASS" and "test/passTests.py : PASS" lines
+# both have spaces at the end.
-expect = r"""qmtest.py run --output results.qmr --format none --result-stream=scons_tdb.AegisChangeStream src
+expect = r"""qmtest.py run --output results.qmr --format none --result-stream="scons_tdb.AegisChangeStream" src
--- TEST RESULTS -------------------------------------------------------------
- src/passTests.py : PASS
+ %(src_passTests_py)s : PASS
- src/suite/passTests.py : PASS
+ %(src_suite_passTests_py)s : PASS
--- TESTS THAT DID NOT PASS --------------------------------------------------
2 tests total
- 2 (100%) tests PASS
-"""
+ 2 (100%%) tests PASS
+""" % locals()
-test.run(arguments = '--qmtest src', stdout = expect)
+test.run(arguments = 'src', stdout = expect)
test.pass_test()
--- /dev/null
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Test a list of tests to run in a file specified with the -f option.
+"""
+
+import os.path
+
+import TestCmd
+import TestRuntest
+
+test_fail_py = os.path.join('test', 'fail.py')
+test_no_result_py = os.path.join('test', 'no_result.py')
+test_pass_py = os.path.join('test', 'pass.py')
+
+test = TestRuntest.TestRuntest()
+
+test.subdir('test')
+
+test.write_failing_test(['test', 'fail.py'])
+
+test.write_no_result_test(['test', 'no_result.py'])
+
+test.write_passing_test(['test', 'pass.py'])
+
+test.write('t.txt', """\
+#%(test_fail_py)s
+%(test_pass_py)s
+""" % locals())
+
+# NOTE: The "test/fail.py : FAIL" and "test/pass.py : PASS" lines both
+# have spaces at the end.
+
+expect = """qmtest.py run --output results.qmr --format none --result-stream="scons_tdb.AegisChangeStream" %(test_pass_py)s
+--- TEST RESULTS -------------------------------------------------------------
+
+ %(test_pass_py)s : PASS
+
+--- TESTS THAT DID NOT PASS --------------------------------------------------
+
+ None.
+
+
+--- STATISTICS ---------------------------------------------------------------
+
+ 1 tests total
+
+ 1 (100%%) tests PASS
+""" % locals()
+
+test.run(arguments = '-f t.txt', stdout = expect)
+
+test.pass_test()
--- /dev/null
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Test writing XML output to a file.
+"""
+
+import os.path
+import re
+import sys
+
+import TestRuntest
+
+test = TestRuntest.TestRuntest()
+
+test_fail_py = re.escape(os.path.join('test', 'fail.py'))
+test_no_result_py = re.escape(os.path.join('test', 'no_result.py'))
+test_pass_py = re.escape(os.path.join('test', 'pass.py'))
+
+# sys.stdout and sys.stderr are open non-binary ('w' instead of 'wb')
+# so the lines written on Windows are terminated \r\n, not just \n. The
+# expressions below use 'cr' as the optional carriage return character.
+if sys.platform in ['win32']:
+ cr = '\r'
+else:
+ cr = ''
+
+test.subdir('test')
+
+test.write_fake_scons_source_tree()
+
+test.write_failing_test(['test', 'fail.py'])
+
+test.write_no_result_test(['test', 'no_result.py'])
+
+test.write_passing_test(['test', 'pass.py'])
+
+test.run(arguments = '-o xml.out --xml test', status = 1)
+
+expect_engine = """\
+<annotation key="scons_test\\.engine">
+ __build__='D456'
+ __buildsys__='another_fake_system'
+ __date__='Dec 31 1999'
+ __developer__='John Doe'
+ __version__='4\\.5\\.6'
+</annotation>
+"""
+
+expect_script = """\
+<annotation key="scons_test\\.script">
+ __build__='D123'
+ __buildsys__='fake_system'
+ __date__='Jan 1 1970'
+ __developer__='Anonymous'
+ __version__='1\\.2\\.3'
+</annotation>
+"""
+
+# The actual values printed for sys and os.environ will be completely
+# dependent on the local values. Don't bother trying to match, just
+# look to see if the opening tag exists.
+
+expect_sys = """\
+<annotation key="scons_test\\.sys">
+"""
+
+expect_os_environ = """\
+<annotation key="scons_test\\.os\\.environ">
+"""
+
+expect_fail = """\
+ <result id="%(test_fail_py)s" kind="test" outcome="FAIL">
+ <annotation name="Test\\.exit_code">
+ "1"
+ </annotation>
+ <annotation name="Test\\.stderr">
+ "<pre>FAILING TEST STDERR%(cr)s
+</pre>"
+ </annotation>
+ <annotation name="Test\\.stdout">
+ "<pre>FAILING TEST STDOUT%(cr)s
+</pre>"
+ </annotation>
+ <annotation name="qmtest\\.cause">
+ "Non-zero exit_code\\."
+ </annotation>
+ <annotation name="qmtest\\.end_time">
+ "[\\d.]+"
+ </annotation>
+ <annotation name="qmtest\\.start_time">
+ "[\\d.]+"
+ </annotation>
+ <annotation name="qmtest\\.target">
+ "local"
+ </annotation>
+ </result>
+""" % locals()
+
+expect_no_result = """\
+ <result id="%(test_no_result_py)s" kind="test" outcome="FAIL">
+ <annotation name="Test.exit_code">
+ "2"
+ </annotation>
+ <annotation name="Test\\.stderr">
+ "<pre>NO RESULT TEST STDERR%(cr)s
+</pre>"
+ </annotation>
+ <annotation name="Test\\.stdout">
+ "<pre>NO RESULT TEST STDOUT%(cr)s
+</pre>"
+ </annotation>
+ <annotation name="qmtest\\.cause">
+ "Non-zero exit_code\\."
+ </annotation>
+ <annotation name="qmtest\\.end_time">
+ "[\\d.]+"
+ </annotation>
+ <annotation name="qmtest\\.start_time">
+ "[\\d.]+"
+ </annotation>
+ <annotation name="qmtest\\.target">
+ "local"
+ </annotation>
+ </result>
+""" % locals()
+
+expect_pass = """\
+ <result id="%(test_pass_py)s" kind="test" outcome="PASS">
+ <annotation name="qmtest\\.end_time">
+ "[\\d.]+"
+ </annotation>
+ <annotation name="qmtest\\.start_time">
+ "[\\d.]+"
+ </annotation>
+ <annotation name="qmtest\\.target">
+ "local"
+ </annotation>
+ </result>
+""" % locals()
+
+xml_out = test.read('xml.out', 'r')
+
+expect = [
+ expect_engine,
+ expect_script,
+ expect_sys,
+ expect_os_environ,
+ expect_fail,
+ expect_no_result,
+ expect_pass,
+]
+
+non_matches = []
+
+for e in expect:
+ if not re.search(e, xml_out):
+ non_matches.append(e)
+
+if non_matches:
+ for n in non_matches:
+ print "DID NOT MATCH " + '='*60
+ print n
+ print "ACTUAL XML OUTPUT " + '='*60
+ print xml_out
+ test.fail_test()
+
+test.pass_test()
""")
test.write('foo.c', r"""
+#include <stdio.h>
+#include <stdlib.h>
#include <bu/bu.h>
int
main(int argc, char *argv[])
""")
test.write(['bu', 'bu.c'], r"""
+#include <stdio.h>
void
bu(void)
{
""")
test.write(['work1', 'sub1', 'hello.c'], r"""\
+#include <stdio.h>
+#include <stdlib.h>
int
main(int argc, char *argv[])
{
""")
test.write(['work1', 'sub2', 'hello.c'], r"""\
+#include <stdio.h>
+#include <stdlib.h>
#include <inc1.h>
#include <inc2.h>
int
""")
test.write(['work2', 'sub1', 'hello.c'], r"""\
+#include <stdio.h>
+#include <stdlib.h>
int
main(int argc, char *argv[])
{
""")
test.write(['work2', 'sub2', 'hello.c'], r"""\
+#include <stdio.h>
+#include <stdlib.h>
#include <inc1.h>
#include <inc2.h>
int
""")
test.write(['work1', 'foo.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
#include <aaa.h>
#include <bbb.h>
int
""")
test.write(['work2', 'foo.c'], r"""
+#include <stdio.h>
+#include <stdlib.h>
#include "aaa.h"
#include "bbb.h"
int
import TestCmd
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
test.write('SConstruct', """\
env = Environment()
-env.Command('f1.out', 'f1.in', "%(python)s build.py $TARGET $SOURCE")
-env.Command('f2.out', 'f2.in', "@%(python)s build.py $TARGET $SOURCE")
-env.Command('f3.out', 'f3.in', "@ %(python)s build.py $TARGET $SOURCE")
-env.Command('f4.out', 'f4.in', "@-%(python)s build.py $TARGET $SOURCE")
-env.Command('f5.out', 'f5.in', "@- %(python)s build.py $TARGET $SOURCE")
-env.Command('f6.out', 'f6.in', "-@%(python)s build.py $TARGET $SOURCE")
-env.Command('f7.out', 'f7.in', "-@ %(python)s build.py $TARGET $SOURCE")
+env.Command('f1.out', 'f1.in', '%(_python_)s build.py $TARGET $SOURCE')
+env.Command('f2.out', 'f2.in', '@%(_python_)s build.py $TARGET $SOURCE')
+env.Command('f3.out', 'f3.in', '@ %(_python_)s build.py $TARGET $SOURCE')
+env.Command('f4.out', 'f4.in', '@-%(_python_)s build.py $TARGET $SOURCE')
+env.Command('f5.out', 'f5.in', '@- %(_python_)s build.py $TARGET $SOURCE')
+env.Command('f6.out', 'f6.in', '-@%(_python_)s build.py $TARGET $SOURCE')
+env.Command('f7.out', 'f7.in', '-@ %(_python_)s build.py $TARGET $SOURCE')
""" % locals())
test.write('f1.in', "f1.in\n")
test.write('f7.in', "f7.in\n")
expect = test.wrap_stdout("""\
-%(python)s build.py f1.out f1.in
+%(_python_)s build.py f1.out f1.in
""" % locals())
test.run(arguments = '.', stdout = expect)
import TestSCons
+_python_ = TestSCons._python_
+
test = TestSCons.TestSCons()
attempt_file_names = [
def buildFileStr(fn):
return "env.Build(source=r\"\"\"%s.in\"\"\", target=r\"\"\"%s.out\"\"\")" % ( fn, fn )
+xxx = string.join(map(buildFileStr, file_names), '\n')
+
test.write("SConstruct", """
-env=Environment(BUILDERS = {'Build' : Builder(action = '%s cat.py $TARGET $SOURCE')})
+env=Environment(BUILDERS = {'Build' : Builder(action = '%(_python_)s cat.py $TARGET $SOURCE')})
-%s
-""" % (TestSCons.python, string.join(map(buildFileStr, file_names), '\n')))
+%(xxx)s
+""" % locals())
test.run(arguments='.')
import TestSCons
+_python_ = TestSCons._python_
+
test = TestSCons.TestSCons()
test.write('getrevision', """
env=Environment()
content_env=env.Copy()
content_env.TargetSignatures('content')
-content_env.Command('revision.in', [], '%(python)s getrevision > $TARGET')
+content_env.Command('revision.in', [], '%(_python_)s getrevision > $TARGET')
content_env.AlwaysBuild('revision.in')
env.Precious('main.c')
env.Command('main.c', 'revision.in', SubRevision)
exe = env.Program('main.c')
env.Default(exe)
-""" % {'python':TestSCons.python})
+""" % locals())
test.write('main.c', """\
#include <stdio.h>
+#include <stdlib.h>
+#include <stdio.h>
int
main(int argc, char *argv[])
{
prog = 'main' + TestSCons._exe
light_build=test.wrap_stdout("""\
-%(python)s getrevision > revision.in
-""" % {'python':TestSCons.python})
+%(_python_)s getrevision > revision.in
+""" % locals())
test.run(arguments='.')
test.must_exist(prog)
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
func1action = Action(func, strfunction)
func2action = Action(func, strfunction=strfunction)
-cmd = r"%(python)s cat.py $SOURCE $TARGET"
+cmd = r'%(_python_)s cat.py $SOURCE $TARGET'
cmd1action = Action(cmd, strfunction)
cmd2action = Action(cmd, strfunction=strfunction)
-list = [ r"%(python)s cat.py $SOURCE .temp",
- r"%(python)s cat.py .temp $TARGET" ]
+list = [ r'%(_python_)s cat.py $SOURCE .temp',
+ r'%(_python_)s cat.py .temp $TARGET' ]
listaction = Action(list, strfunction=strfunction)
lazy = '$LAZY'
'Dict' : Builder(action=dict),
},
- LAZY = r"%(python)s cat.py $SOURCE $TARGET")
+ LAZY = r'%(_python_)s cat.py $SOURCE $TARGET')
env.Cmd('cmd.out', 'cmd.in')
env.Cmd1Str('cmd1str.out', 'cmdstr.in')
test.write('dict8.liststr', "dict8.liststr\n")
expect = test.wrap_stdout("""\
-%(python)s cat.py cmd.in cmd.out
+%(_python_)s cat.py cmd.in cmd.out
Building cmd1str.out from cmdstr.in
Building cmd2str.out from cmdstr.in
-%(python)s cat.py dict1.cmd dict1.out
+%(_python_)s cat.py dict1.cmd dict1.out
Building dict2.out from dict2.cmdstr
func(["dict3.out"], ["dict3.func"])
Building dict4.out from dict4.funcstr
-%(python)s cat.py dict5.lazy dict5.out
+%(_python_)s cat.py dict5.lazy dict5.out
Building dict6.out from dict6.lazystr
-%(python)s cat.py dict7.list .temp
-%(python)s cat.py .temp dict7.out
+%(_python_)s cat.py dict7.list .temp
+%(_python_)s cat.py .temp dict7.out
Building dict8.out from dict8.liststr
Building dict8.out from dict8.liststr
func(["func.out"], ["func.in"])
Building func1str.out from funcstr.in
Building func2str.out from funcstr.in
-%(python)s cat.py lazy.in lazy.out
+%(_python_)s cat.py lazy.in lazy.out
Building lazy1str.out from lazystr.in
Building lazy2str.out from lazystr.in
-%(python)s cat.py list.in .temp
-%(python)s cat.py .temp list.out
+%(_python_)s cat.py list.in .temp
+%(_python_)s cat.py .temp list.out
Building liststr.out from liststr.in
Building liststr.out from liststr.in
target.out
""")
test.write('hello.c', """\
+#include <stdio.h>
+#include <stdlib.h>
int
main(int argc, char *argv[]) {
printf("hello.c\\n");
import TestSCons
import os.path
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-B = Builder(action = "%s build.py $TARGETS $SOURCES")
+B = Builder(action = '%(_python_)s build.py $TARGETS $SOURCES')
env = Environment(BUILDERS = { 'B' : B })
env.B(target = 'subdir/f1.out', source = 'subdir/f1.in')
env.B(target = 'subdir/f2.out', source = 'subdir/f2.in')
env.B(target = 'subdir/f3.out', source = 'subdir/f3.in')
env.B(target = 'subdir/f4.out', source = 'subdir/f4.in')
-""" % python)
+""" % locals())
test.write(['subdir', 'f1.in'], "f1.in\n")
test.write(['subdir', 'f2.in'], "f2.in\n")
""" % TestSCons._obj)
test.write('foo.c', """\
+#include <stdio.h>
+#include <stdlib.h>
void
foo(void) {
printf("foo.c\\n");
""")
test.write(['src', 'main.c'], """\
+#include <stdio.h>
+#include <stdlib.h>
extern void foo(void);
extern void bar(void);
int
""")
test.write(['src', 'sub', 'bar.c'], """\
+#include <stdio.h>
+#include <stdlib.h>
void
bar(void) {
printf("bar.c\\n");
--- /dev/null
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+XXX Put a description of the test here.
+"""
+
+import os
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+if not hasattr(os, 'symlink'):
+ print "No os.symlink() method, no symlinks to test."
+ test.no_result(1)
+
+test.subdir('obj',
+ ['obj', 'subdir'],
+ 'src',
+ 'srcdir')
+
+test.write('SConstruct', """
+env = Environment()
+BuildDir('obj/subdir', 'src')
+Program('hello', ['obj/subdir/main.c'])
+""")
+
+test.write(['srcdir', 'main.c'], r"""
+int
+main(int ac, char *argv[])
+{
+ printf("srcdir/main.c\n");
+}
+""")
+
+os.symlink('../srcdir/main.c', 'src/main.c')
+
+test.run(arguments = '.')
+
+test.pass_test()
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
"""
-Test how we handle symlinks in end-cases.
+Test how we handle #includes of dangling symlinks.
"""
import os
-import string
import TestSCons
scons: *** Source `foo.h' not found, needed by target `%s'. Stop.
"""% foo_obj
-test.run(arguments = '.',
- status = 2,
- stderr = expect)
-
-test.write('SConstruct', """
-Command('file.out', 'file.in', Copy('$TARGET', '$SOURCE'))
-""")
-
-test.symlink('nonexistent', 'file.in')
-
-test.run(arguments = '.',
- status = 2,
- stderr = "scons: *** Source `file.in' not found, needed by target `file.out'. Stop.\n")
+test.run(arguments = '.', status = 2, stderr = expect)
test.pass_test()
--- /dev/null
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Test how we handle dangling symlinks as source files.
+"""
+
+import os
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+if not hasattr(os, 'symlink'):
+ print "No os.symlink() method, no symlinks to test."
+ test.no_result(1)
+
+test.write('SConstruct', """
+Command('file.out', 'file.in', Copy('$TARGET', '$SOURCE'))
+""")
+
+test.symlink('nonexistent', 'file.in')
+
+expect = """\
+scons: *** Source `file.in' not found, needed by target `file.out'. Stop.
+"""
+
+test.run(arguments = '.', status = 2, stderr = expect)
+
+test.pass_test()
import sys
import TestSCons
-python = TestSCons.python
+_python_ = TestSCons._python_
test = TestSCons.TestSCons()
""")
test.write('SConstruct', """
-B = Builder(action = r'%s build.py $TARGETS $SOURCES')
+B = Builder(action = r'%(_python_)s build.py $TARGETS $SOURCES')
env = Environment(BUILDERS = { 'B' : B })
env.B(target = 'f1.out', source = 'f1.in')
env.B(target = 'f2.out', source = 'f2.in')
env.B(target = 'f3.out', source = 'f3.in')
env.B(target = 'f4.out', source = 'f4.in')
-""" % python)
+""" % locals())
test.write('f1.in', "f1.in\n")
test.write('f2.in', "f2.in\n")
test.run(arguments = 'f1.out f3.out')
-test.run(arguments = 'f1.out f2.out f3.out f4.out', stdout =
-test.wrap_stdout("""\
+expect = test.wrap_stdout("""\
scons: `f1.out' is up to date.
-%s build.py f2.out f2.in
+%(_python_)s build.py f2.out f2.in
scons: `f3.out' is up to date.
-%s build.py f4.out f4.in
-""" % (python, python)))
+%(_python_)s build.py f4.out f4.in
+""" % locals())
+
+test.run(arguments = 'f1.out f2.out f3.out f4.out', stdout = expect)
test.pass_test()