From: stevenknight Date: Thu, 2 Nov 2006 16:21:36 +0000 (+0000) Subject: Merged revisions 1582-1665 via svnmerge from X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=09c25718ce084ca9d08f4a0ef4dbede044d3c3bb;p=scons.git Merged revisions 1582-1665 via svnmerge from http://scons.tigris.org/svn/scons/branches/core ........ r1585 | stevenknight | 2006-08-06 21:21:12 -0500 (Sun, 06 Aug 2006) | 1 line 0.96.D430 - Fix bug with finding Fortran modules in build directories. (Nicolas Vigier) ........ r1586 | stevenknight | 2006-08-06 22:54:39 -0500 (Sun, 06 Aug 2006) | 1 line 0.96.D431 - Fix use of BuildDir when the source file is a relative-path symlink. (Nicola Vi ........ r1587 | timot | 2006-08-10 14:45:00 -0500 (Thu, 10 Aug 2006) | 1 line fix Platform SDK init ........ r1589 | stevenknight | 2006-08-12 13:28:51 -0500 (Sat, 12 Aug 2006) | 1 line 0.96.D432 - Change the default mingw linker from g++ to gcc. (Mariusz Olko) ........ r1590 | stevenknight | 2006-08-13 11:16:32 -0500 (Sun, 13 Aug 2006) | 1 line 0.96.D433 - More runtest.py enhancements. ........ r1594 | stevenknight | 2006-08-15 04:47:46 -0500 (Tue, 15 Aug 2006) | 1 line 0.96.D434 - Print the full path of SConscript files in stack traces. (Dobes Vandermeer) ........ r1600 | timot | 2006-08-16 11:34:44 -0500 (Wed, 16 Aug 2006) | 1 line add M4 to mingw tools ........ r1611 | stevenknight | 2006-08-19 16:25:24 -0500 (Sat, 19 Aug 2006) | 1 line 0.96.D435 - Add an SCons XMLResultStream to capture test results for mailing in. Get Aegis ........ r1617 | timot | 2006-08-21 16:19:03 -0500 (Mon, 21 Aug 2006) | 1 line handling of spawnve returning an error code that is not in exitvalmap ........ r1619 | stevenknight | 2006-09-01 19:07:47 -0500 (Fri, 01 Sep 2006) | 1 line 0.96.D436 - Win32 test portability and other test fixes. ........ r1620 | stevenknight | 2006-09-02 20:21:51 -0500 (Sat, 02 Sep 2006) | 2 lines Bring msvc.py in sync with Aegis repository. ........ r1621 | stevenknight | 2006-09-02 20:23:48 -0500 (Sat, 02 Sep 2006) | 2 lines Move to keep symlink tests together. ........ r1622 | garyo | 2006-09-06 11:51:42 -0500 (Wed, 06 Sep 2006) | 1 line Fix for Issue #1370; allow exit values not in exitvalmap. Added some tests for this kind of thing. Also improved win32 err msg if command exits with nonzero to show actual cmd, not just "cmd.exe". Note this fix improves posix and win32 behavior. ........ r1623 | stevenknight | 2006-09-07 06:35:16 -0500 (Thu, 07 Sep 2006) | 1 line 0.96.D440 - Fix runtest.py with QMTest on Windows. ........ r1625 | stevenknight | 2006-09-09 09:22:15 -0500 (Sat, 09 Sep 2006) | 3 lines Comment out a long-command test which fails on older Pythons (1.5.2) on Fedora Core 3. We can restore it in the future. ........ r1626 | stevenknight | 2006-09-09 16:17:44 -0500 (Sat, 09 Sep 2006) | 1 line 0.96.D441 - Allow Python Values to be the targets of Builders. (Anonymous) ........ r1627 | stevenknight | 2006-09-09 20:25:53 -0500 (Sat, 09 Sep 2006) | 1 line 0.96.D442 - Support src_dir on SConscript() calls. (Dobes Vandermeer) ........ r1628 | stevenknight | 2006-09-10 07:28:54 -0500 (Sun, 10 Sep 2006) | 1 line 0.96.D443 - Add miscellaneous utility scripts and config changes. ........ r1629 | stevenknight | 2006-09-11 04:45:01 -0500 (Mon, 11 Sep 2006) | 1 line 0.96.D444 - Add a test case for BuildDir handling of nested SConscript files. (Adam Simpkin ........ r1630 | stevenknight | 2006-09-11 11:34:07 -0500 (Mon, 11 Sep 2006) | 1 line 0.96.D445 - Workaround bug in early versions of thePython 2.4 profiler. ........ r1631 | stevenknight | 2006-09-19 19:12:51 -0500 (Tue, 19 Sep 2006) | 1 line 0.96.D446 - Fix Visual Studio common prefix handling to only treat common prefixes on comple ........ r1632 | stevenknight | 2006-09-25 07:11:44 -0500 (Mon, 25 Sep 2006) | 1 line 0.96.D447 - Fix tests that fail due to warnings from (some versions?) of gcc. (Sohail Soman ........ r1633 | stevenknight | 2006-09-25 07:57:48 -0500 (Mon, 25 Sep 2006) | 1 line 0.96.D448 - Handle python paths with quotes in tests. ........ r1634 | stevenknight | 2006-09-25 14:38:07 -0500 (Mon, 25 Sep 2006) | 1 line 0.96.D449 - Fix SCons build when python is not in the path (e.g. on Windows). (Chad Austin) ........ r1635 | stevenknight | 2006-09-26 11:28:23 -0500 (Tue, 26 Sep 2006) | 1 line 0.96.D450 - Handle warnings from Python 2.1; make sure we still test on Python 1.5. ........ r1636 | stevenknight | 2006-09-27 05:34:23 -0500 (Wed, 27 Sep 2006) | 1 line 0.96.D451 - Avoid calling Options validators and converters twice. ........ r1637 | stevenknight | 2006-09-28 08:12:38 -0500 (Thu, 28 Sep 2006) | 1 line 0.96.D452 - Allow setting MSVS_VERSION after initialization to select the Visual Studio vers ........ r1638 | stevenknight | 2006-09-30 08:38:15 -0500 (Sat, 30 Sep 2006) | 1 line 0.96.D453 - Give the MSVC resource builder a src_builder list and .rc src_suffix. (Leanid N ........ r1639 | stevenknight | 2006-10-12 08:50:58 -0500 (Thu, 12 Oct 2006) | 1 line 0.96.D454 - Test handling of env.Append() and env.Prepend(), making sure it works on later P ........ r1640 | stevenknight | 2006-10-15 20:42:09 -0500 (Sun, 15 Oct 2006) | 1 line 0.96.D455 - Support the runtest.py -f option when using QMTest. ........ r1641 | stevenknight | 2006-10-15 21:20:02 -0500 (Sun, 15 Oct 2006) | 1 line 0.96.D456 - Fix an error in ListOption handling caused by making new copies of Options objec ........ r1642 | stevenknight | 2006-10-16 05:53:14 -0500 (Mon, 16 Oct 2006) | 1 line 0.96.D457 - Fix new Append()/Prepend() handling of dictionaries in later Python versions (2. ........ r1643 | stevenknight | 2006-10-16 07:13:16 -0500 (Mon, 16 Oct 2006) | 1 line 0.96.D458 - Allow Install() to handle directories as sources. (Matthew A. Nicholson) ........ r1644 | stevenknight | 2006-10-17 09:17:58 -0500 (Tue, 17 Oct 2006) | 1 line 0.96.D459 - Add a test to make sure SideEffect() doesn't interfere with CacheDir(). Refacto ........ r1645 | stevenknight | 2006-10-17 10:20:22 -0500 (Tue, 17 Oct 2006) | 1 line 0.96.D460 - Do not use -fPIC when using gcc on win32 (MinGW). (Jan Nijtmans) ........ r1646 | stevenknight | 2006-10-17 17:21:58 -0500 (Tue, 17 Oct 2006) | 6 lines Move all the scons.org stuff from the scons source tree itself to a directory next to the trunk, and delete the copies from the branches. There's a lot of stuff there (what with all of the documentation of the different versions) and it's ridiculous to make everyone sync it just to work on the code. ........ r1647 | stevenknight | 2006-10-17 23:18:29 -0500 (Tue, 17 Oct 2006) | 1 line 0.96.D461 - Fix the tests of runtest.py so they skip appropriately if qmtest.py isn't instal ........ r1648 | stevenknight | 2006-10-18 08:48:47 -0500 (Wed, 18 Oct 2006) | 1 line 0.96.D462 - When using --implicit-cache, do not re-scan files if the scanner returned no imp ........ r1649 | stevenknight | 2006-10-18 19:42:13 -0500 (Wed, 18 Oct 2006) | 1 line 0.96.D463 - More test portability fixes. ........ r1650 | stevenknight | 2006-10-19 00:30:23 -0500 (Thu, 19 Oct 2006) | 1 line 0.96.D464 - Add a cpp.py module that knows how to find dependencies from #include lines like ........ r1651 | stevenknight | 2006-10-20 06:49:51 -0500 (Fri, 20 Oct 2006) | 1 line 0.96.D465 - Fix unresolved variable name in win32 portion of test. ........ r1652 | stevenknight | 2006-10-23 00:20:38 -0500 (Mon, 23 Oct 2006) | 1 line 0.96.D466 - Add an option for tracing files to and from the CacheDir. ........ r1653 | stevenknight | 2006-10-23 00:29:32 -0500 (Mon, 23 Oct 2006) | 1 line 0.96.D467 - Make {Append,Prepend}Unique() handle adding elements to empty lists like {Append ........ r1654 | stevenknight | 2006-10-23 02:38:06 -0500 (Mon, 23 Oct 2006) | 1 line 0.96.D468 - Allow Debug.caller() to take multiple arguments; add a debug utility to post-pro ........ r1655 | stevenknight | 2006-10-23 03:16:42 -0500 (Mon, 23 Oct 2006) | 1 line 0.96.D469 - Reduce unnecessary calls to Node.FS.disambiguate(), undoing (?) a performance hi ........ r1656 | stevenknight | 2006-10-25 00:06:27 -0500 (Wed, 25 Oct 2006) | 1 line 0.96.D470 - More test portability fixes. ........ r1657 | stevenknight | 2006-10-25 00:16:22 -0500 (Wed, 25 Oct 2006) | 1 line 0.96.D471 - Have runtest.py fall back to the --noqmtest option (with a warning) if qmtest.py ........ r1658 | stevenknight | 2006-10-25 12:12:02 -0500 (Wed, 25 Oct 2006) | 1 line 0.96.D472 - Document the default use of the /Z7 flag for Visual Studio and ways to use /Zi. ........ r1659 | stevenknight | 2006-10-26 23:53:51 -0500 (Thu, 26 Oct 2006) | 1 line 0.96.D473 - Have runtest.py -d accomodate different Python library locations. ........ r1660 | stevenknight | 2006-10-27 00:03:59 -0500 (Fri, 27 Oct 2006) | 1 line 0.96.D474 - Patch to support running SCons under WingIDE. (Allen Bierbaum) ........ r1661 | stevenknight | 2006-10-27 12:17:27 -0500 (Fri, 27 Oct 2006) | 1 line 0.96.D475 - Restore execution of all Environment unit tests. ........ r1662 | stevenknight | 2006-10-31 23:22:58 -0600 (Tue, 31 Oct 2006) | 1 line 0.96.D476 - Eliminate unnecessary print from a test, left over from debugging. ........ r1663 | stevenknight | 2006-10-31 23:32:00 -0600 (Tue, 31 Oct 2006) | 1 line 0.96.D477 - Support creating shared object files from assembly language. (James Y. Knight) ........ r1664 | stevenknight | 2006-10-31 23:44:08 -0600 (Tue, 31 Oct 2006) | 1 line 0.96.D478 - Fix the Memoizer to deal with a compiled .pyo or .pyc file that's in a different ........ r1665 | stevenknight | 2006-11-01 21:59:18 -0600 (Wed, 01 Nov 2006) | 1 line 0.96.D479 - Put back the scons-{LICENSE,README} files in the scons-loacal package; add tests ........ git-svn-id: http://scons.tigris.org/svn/scons/trunk@1667 fdb21ef1-2011-0410-befe-b5e4ea1792b1 --- diff --git a/HOWTO/release.txt b/HOWTO/release.txt index 397033a1..88f93521 100644 --- a/HOWTO/release.txt +++ b/HOWTO/release.txt @@ -93,8 +93,8 @@ Things to do to release a new X.Y version of SCons: 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 diff --git a/HOWTO/subrelease.txt b/HOWTO/subrelease.txt index fb799e69..6826c817 100644 --- a/HOWTO/subrelease.txt +++ b/HOWTO/subrelease.txt @@ -39,8 +39,8 @@ Things to do to release a new X.Y.Z version of SCons: 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 diff --git a/QMTest/TestRuntest.py b/QMTest/TestRuntest.py index a4bcd05d..94527469 100644 --- a/QMTest/TestRuntest.py +++ b/QMTest/TestRuntest.py @@ -27,9 +27,11 @@ from TestCommon import __all__ __all__.extend([ 'TestRuntest', 'python', + '_python_', ]) python = python_executable +_python_ = '"' + python_executable + '"' failing_test_template = """\ @@ -53,6 +55,22 @@ sys.stderr.write('PASSING TEST STDERR\\n') 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. @@ -91,15 +109,28 @@ class TestRuntest(TestCommon): 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): @@ -127,6 +158,47 @@ class TestRuntest(TestCommon): 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) diff --git a/QMTest/TestSCons.py b/QMTest/TestSCons.py index 0904d315..de155264 100644 --- a/QMTest/TestSCons.py +++ b/QMTest/TestSCons.py @@ -24,6 +24,14 @@ import sys 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', @@ -36,6 +44,7 @@ __all__.extend([ 'TestSCons', ]) python = python_executable +_python_ = '"' + python_executable + '"' _exe = exe_suffix _obj = obj_suffix _shobj = shobj_suffix @@ -105,6 +114,8 @@ class TestSCons(TestCommon): initializations. """ + scons_version = SConsVersion + def __init__(self, **kw): """Initialize an SCons testing object. @@ -398,12 +409,12 @@ void my_qt_symbol(const char *arg) { } """) - 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) @@ -412,6 +423,7 @@ env.StaticLibrary( 'myqt', 'my_qobject.cpp' ) 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([]): diff --git a/QMTest/classes.qmc b/QMTest/classes.qmc index 73e3df3a..88de0615 100644 --- a/QMTest/classes.qmc +++ b/QMTest/classes.qmc @@ -8,4 +8,5 @@ + diff --git a/QMTest/scons_tdb.py b/QMTest/scons_tdb.py index 145c2a7a..e0d76830 100644 --- a/QMTest/scons_tdb.py +++ b/QMTest/scons_tdb.py @@ -46,9 +46,13 @@ from qm.test import suite 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' @@ -128,62 +132,145 @@ def check_exit_status(result, prefix, desc, status): 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 -# " %s" % module.__version__ -# " %s" % module.__build__ -# " %s" % module.__buildsys__ -# " %s" % module.__date__ -# " %s" % module.__developer__ -# " " % tag - -# " " -# print_version_info("script", scons) -# print_version_info("engine", 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 @@ -227,7 +314,7 @@ class AegisStream(TextResultStream): 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" @@ -296,18 +383,7 @@ class AegisBaselineStream(AegisStream): ) 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): @@ -320,7 +396,11 @@ class AegisBatchStream(FileResultStream): 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') @@ -349,9 +429,8 @@ class Test(AegisTest): 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.") diff --git a/SConstruct b/SConstruct index 49cc6ff3..0fdacd52 100644 --- a/SConstruct +++ b/SConstruct @@ -913,12 +913,14 @@ for p in [ scons ]: 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, diff --git a/bin/ae-cvs-ci b/bin/ae-cvs-ci new file mode 100755 index 00000000..3dcc2870 --- /dev/null +++ b/bin/ae-cvs-ci @@ -0,0 +1,190 @@ +# +# 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 " + +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 diff --git a/bin/ae-svn-ci b/bin/ae-svn-ci new file mode 100755 index 00000000..e5b81a4d --- /dev/null +++ b/bin/ae-svn-ci @@ -0,0 +1,226 @@ +# +# 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] []" + +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 diff --git a/bin/caller-tree.py b/bin/caller-tree.py new file mode 100644 index 00000000..5d907b83 --- /dev/null +++ b/bin/caller-tree.py @@ -0,0 +1,90 @@ +#!/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, '') diff --git a/bin/scons-cdist b/bin/scons-cdist index 425e430b..58b1bae0 100644 --- a/bin/scons-cdist +++ b/bin/scons-cdist @@ -22,45 +22,58 @@ # 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` @@ -70,8 +83,14 @@ if test "X$1" = "X"; then 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() @@ -82,6 +101,27 @@ 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 @@ -95,29 +135,38 @@ BASELINE=`aesub -p ${AEGIS_PROJECT} -c ${CHANGE} '${Project trunk_name}'` 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 # @@ -144,38 +193,73 @@ 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 # @@ -185,4 +269,4 @@ 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 diff --git a/bin/scons-diff.py b/bin/scons-diff.py new file mode 100644 index 00000000..6cfe25ad --- /dev/null +++ b/bin/scons-diff.py @@ -0,0 +1,189 @@ +#!/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) diff --git a/config b/config index e540484f..b055bdb2 100644 --- a/config +++ b/config @@ -50,7 +50,7 @@ * * 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 @@ -258,9 +258,9 @@ diff_command = * 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"; @@ -286,3 +286,14 @@ file_template = 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"; + * + */ diff --git a/doc/SConscript b/doc/SConscript index 6162f939..6f92fbc8 100644 --- a/doc/SConscript +++ b/doc/SConscript @@ -169,7 +169,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. 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) @@ -259,7 +259,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. 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) @@ -387,7 +387,7 @@ man_i_files = ['builders.man', 'tools.man', 'variables.man'] 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) diff --git a/doc/man/scons.1 b/doc/man/scons.1 index 49f9a305..a12bd68d 100644 --- a/doc/man/scons.1 +++ b/doc/man/scons.1 @@ -420,6 +420,24 @@ Will not remove any targets specified by the .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 @@ -1712,6 +1730,24 @@ the specified 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 ) @@ -1993,6 +2029,24 @@ the specified 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 ) @@ -2759,8 +2813,11 @@ Import("*") .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']) @@ -2771,11 +2828,15 @@ 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', @@ -3997,17 +4058,31 @@ env.Tool('opengl', toolpath = ['build/tools']) '\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .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): @@ -4018,6 +4093,15 @@ prefix = ARGUMENTS.get('prefix', '/usr/local') 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 '\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" diff --git a/runtest.py b/runtest.py index 7f5cbc3c..5440c107 100644 --- a/runtest.py +++ b/runtest.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation +# __COPYRIGHT__ # # runtest.py - wrapper script for running SCons tests # @@ -96,20 +96,21 @@ import string 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 @@ -119,13 +120,6 @@ spe = 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: @@ -137,6 +131,7 @@ 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 @@ -167,7 +162,7 @@ Options: 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', @@ -179,7 +174,11 @@ for o, a in opts: 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) @@ -191,6 +190,8 @@ for o, a in opts: 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) @@ -202,7 +203,7 @@ for o, a in opts: 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']: @@ -222,6 +223,17 @@ for o, a in opts: 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) @@ -234,6 +246,16 @@ def whereis(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: @@ -277,9 +299,9 @@ except AttributeError: 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): @@ -352,86 +374,8 @@ format_class = { '--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: @@ -476,6 +420,8 @@ 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 @@ -529,6 +475,8 @@ else: 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') @@ -548,6 +496,7 @@ elif scons_lib_dir: 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 @@ -573,43 +522,123 @@ if old_pythonpath: 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: @@ -617,6 +646,8 @@ if qmtest: #except OSError: # pass +tests = map(Test, tests) + class Unbuffered: def __init__(self, file): self.file = file @@ -644,20 +675,15 @@ if not python: # 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: diff --git a/src/CHANGES.txt b/src/CHANGES.txt index ccbc3af5..88e70dc8 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -10,10 +10,29 @@ 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 @@ -29,6 +48,10 @@ RELEASE 0.97 - XXX - 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 @@ -47,16 +70,44 @@ RELEASE 0.97 - XXX 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. @@ -70,6 +121,19 @@ RELEASE 0.97 - XXX - 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 @@ -105,10 +169,36 @@ RELEASE 0.97 - XXX - 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. diff --git a/src/engine/MANIFEST.in b/src/engine/MANIFEST.in index 9d6c9721..c762f1cd 100644 --- a/src/engine/MANIFEST.in +++ b/src/engine/MANIFEST.in @@ -2,6 +2,7 @@ SCons/__init__.py SCons/Action.py SCons/Builder.py SCons/Conftest.py +SCons/cpp.py SCons/dblite.py SCons/Debug.py SCons/Defaults.py diff --git a/src/engine/SCons/ActionTests.py b/src/engine/SCons/ActionTests.py index 1085586e..57910de4 100644 --- a/src/engine/SCons/ActionTests.py +++ b/src/engine/SCons/ActionTests.py @@ -182,6 +182,8 @@ if os.name == 'java': else: python = sys.executable +_python_ = '"' + python + '"' + class ActionTestCase(unittest.TestCase): """Test the Action() factory function""" @@ -903,7 +905,7 @@ class CommandActionTestCase(unittest.TestCase): 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()) @@ -911,7 +913,7 @@ class CommandActionTestCase(unittest.TestCase): 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()) @@ -919,7 +921,7 @@ class CommandActionTestCase(unittest.TestCase): 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()) @@ -927,7 +929,7 @@ class CommandActionTestCase(unittest.TestCase): 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()) @@ -935,7 +937,7 @@ class CommandActionTestCase(unittest.TestCase): 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')] @@ -945,7 +947,7 @@ class CommandActionTestCase(unittest.TestCase): 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() @@ -978,7 +980,7 @@ class CommandActionTestCase(unittest.TestCase): 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')], @@ -1016,31 +1018,31 @@ class CommandActionTestCase(unittest.TestCase): 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 @@ -1074,7 +1076,7 @@ class CommandActionTestCase(unittest.TestCase): # 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, @@ -1571,7 +1573,7 @@ class ListActionTestCase(unittest.TestCase): 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") @@ -1644,7 +1646,7 @@ class LazyActionTestCase(unittest.TestCase): 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 diff --git a/src/engine/SCons/Debug.py b/src/engine/SCons/Debug.py index 1cff9c6c..47d21349 100644 --- a/src/engine/SCons/Debug.py +++ b/src/engine/SCons/Debug.py @@ -119,20 +119,22 @@ else: 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() diff --git a/src/engine/SCons/Defaults.py b/src/engine/SCons/Defaults.py index cb628b82..7513c0dd 100644 --- a/src/engine/SCons/Defaults.py +++ b/src/engine/SCons/Defaults.py @@ -173,14 +173,34 @@ Touch = ActionFactory(touch_func, 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 @@ -334,13 +354,14 @@ ConstructionEnvironment = { '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, diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py index d76f71d5..7aa19091 100644 --- a/src/engine/SCons/Environment.py +++ b/src/engine/SCons/Environment.py @@ -84,7 +84,11 @@ def installFunc(target, source, env): 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) @@ -742,21 +746,31 @@ class Base(SubstitutionEnvironment): # 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. @@ -895,19 +909,19 @@ class Base(SubstitutionEnvironment): 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 @@ -925,6 +939,17 @@ class Base(SubstitutionEnvironment): # 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): @@ -952,7 +977,7 @@ class Base(SubstitutionEnvironment): """ 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): @@ -1134,19 +1159,19 @@ class Base(SubstitutionEnvironment): 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 @@ -1164,6 +1189,17 @@ class Base(SubstitutionEnvironment): 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): @@ -1191,7 +1227,7 @@ class Base(SubstitutionEnvironment): """ 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): @@ -1504,25 +1540,37 @@ class Base(SubstitutionEnvironment): 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)) @@ -1632,10 +1680,10 @@ class Base(SubstitutionEnvironment): 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 diff --git a/src/engine/SCons/EnvironmentTests.py b/src/engine/SCons/EnvironmentTests.py index c56f1f52..52aac235 100644 --- a/src/engine/SCons/EnvironmentTests.py +++ b/src/engine/SCons/EnvironmentTests.py @@ -23,6 +23,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +import copy import os import string import StringIO @@ -595,15 +596,17 @@ sys.exit(1) 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() @@ -612,7 +615,7 @@ sys.exit(1) 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: @@ -747,6 +750,24 @@ class BaseTestCase(unittest.TestCase,TestEnvironmentFixture): 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') @@ -1212,6 +1233,8 @@ def exists(env): b2 = Environment()['BUILDERS'] assert b1 == b2, diff_dict(b1, b2) + import UserDict + UD = UserDict.UserDict import UserList UL = UserList.UserList @@ -1243,6 +1266,18 @@ def exists(env): 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']), @@ -1293,14 +1328,21 @@ def exists(env): 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 @@ -1399,6 +1441,33 @@ def exists(env): 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 @@ -1784,6 +1853,8 @@ f5: \ def test_Prepend(self): """Test prepending to construction variables in an Environment """ + import UserDict + UD = UserDict.UserDict import UserList UL = UserList.UserList @@ -1815,6 +1886,18 @@ f5: \ 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']), @@ -1865,14 +1948,21 @@ f5: \ 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 @@ -1965,6 +2055,33 @@ f5: \ 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 @@ -2650,23 +2767,23 @@ def generate(env): 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: @@ -2674,8 +2791,8 @@ def generate(env): 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""" @@ -2956,6 +3073,9 @@ def generate(env): 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): diff --git a/src/engine/SCons/Memoize.py b/src/engine/SCons/Memoize.py index 134206f3..c2a30272 100644 --- a/src/engine/SCons/Memoize.py +++ b/src/engine/SCons/Memoize.py @@ -798,9 +798,14 @@ else: # 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 '', + filename, "eval") superinit = eval(superinitcode, {'cls':cls, diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py index ce5bcc0c..382bca3a 100644 --- a/src/engine/SCons/Node/FS.py +++ b/src/engine/SCons/Node/FS.py @@ -95,10 +95,33 @@ def save_strings(val): # 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'] @@ -113,16 +136,6 @@ def set_duplicate(duplicate): # 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, @@ -152,10 +165,11 @@ def LinkFunc(target, source, env): 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 @@ -213,13 +227,15 @@ def CacheRetrieveFunc(target, source, env): 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] @@ -237,9 +253,18 @@ def CachePushFunc(target, source, env): 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) @@ -258,7 +283,6 @@ def CachePushFunc(target, source, env): 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) @@ -835,6 +859,14 @@ class LocalFS: 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): @@ -1139,6 +1171,21 @@ class FS(LocalFS): 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 @@ -1776,7 +1823,7 @@ class File(Base): __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 @@ -1818,11 +1865,14 @@ class File(Base): 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__""" diff --git a/src/engine/SCons/Node/FSTests.py b/src/engine/SCons/Node/FSTests.py index 98e08a9f..1b38ffee 100644 --- a/src/engine/SCons/Node/FSTests.py +++ b/src/engine/SCons/Node/FSTests.py @@ -425,57 +425,39 @@ class BuildDirTestCase(unittest.TestCase): 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: @@ -485,32 +467,31 @@ class BuildDirTestCase(unittest.TestCase): 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: diff --git a/src/engine/SCons/Node/Python.py b/src/engine/SCons/Node/Python.py index 99dc5b03..a639aee3 100644 --- a/src/engine/SCons/Node/Python.py +++ b/src/engine/SCons/Node/Python.py @@ -45,16 +45,18 @@ class Value(SCons.Node.Node): 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 @@ -64,9 +66,23 @@ class Value(SCons.Node.Node): # 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() diff --git a/src/engine/SCons/Node/PythonTests.py b/src/engine/SCons/Node/PythonTests.py index 0801fb3e..62bcf8b6 100644 --- a/src/engine/SCons/Node/PythonTests.py +++ b/src/engine/SCons/Node/PythonTests.py @@ -45,6 +45,44 @@ class ValueTestCase(unittest.TestCase): 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 """ diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py index bda3a482..42be5b12 100644 --- a/src/engine/SCons/Node/__init__.py +++ b/src/engine/SCons/Node/__init__.py @@ -474,6 +474,7 @@ class Node: 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 @@ -538,7 +539,7 @@ class Node: # 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: diff --git a/src/engine/SCons/Options/ListOption.py b/src/engine/SCons/Options/ListOption.py index d14b22ac..5aa508ad 100644 --- a/src/engine/SCons/Options/ListOption.py +++ b/src/engine/SCons/Options/ListOption.py @@ -65,7 +65,7 @@ class _ListOption(UserList.UserList): UserList.UserList.__init__(self, filter(None, initlist)) self.allowedElems = allowedElems[:] self.allowedElems.sort() - + def __cmp__(self, other): raise NotImplementedError def __eq__(self, other): @@ -88,7 +88,7 @@ class _ListOption(UserList.UserList): return string.join(self, ',') def __repr__(self): return self.__str__() - + def _converter(val, allowedElems, mapdict): """ """ diff --git a/src/engine/SCons/Options/ListOptionTests.py b/src/engine/SCons/Options/ListOptionTests.py index a892e18b..22378bcf 100644 --- a/src/engine/SCons/Options/ListOptionTests.py +++ b/src/engine/SCons/Options/ListOptionTests.py @@ -122,9 +122,6 @@ class ListOptionTestCase(unittest.TestCase): 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(): diff --git a/src/engine/SCons/Options/OptionsTests.py b/src/engine/SCons/Options/OptionsTests.py index aeffe2df..1d9b851e 100644 --- a/src/engine/SCons/Options/OptionsTests.py +++ b/src/engine/SCons/Options/OptionsTests.py @@ -59,6 +59,19 @@ def checkSave(file, expected): 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() diff --git a/src/engine/SCons/Options/__init__.py b/src/engine/SCons/Options/__init__.py index 73339859..83798b3d 100644 --- a/src/engine/SCons/Options/__init__.py +++ b/src/engine/SCons/Options/__init__.py @@ -76,6 +76,11 @@ class 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): """ @@ -100,7 +105,6 @@ class Options: self._do_add(key, help, default, validator, converter) - def AddOptions(self, *optlist): """ Add a list of options. diff --git a/src/engine/SCons/Platform/posix.py b/src/engine/SCons/Platform/posix.py index 675167e4..1d4e9f70 100644 --- a/src/engine/SCons/Platform/posix.py +++ b/src/engine/SCons/Platform/posix.py @@ -70,7 +70,7 @@ def exec_spawnvpe(l, env): # 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. @@ -78,7 +78,7 @@ def exec_fork(l, env): 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: @@ -159,7 +159,7 @@ def exec_piped_fork(l, env, stdout, stderr): 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: diff --git a/src/engine/SCons/Platform/win32.py b/src/engine/SCons/Platform/win32.py index 61880987..148d9df8 100644 --- a/src/engine/SCons/Platform/win32.py +++ b/src/engine/SCons/Platform/win32.py @@ -90,7 +90,11 @@ def piped_spawn(sh, escape, cmd, args, env, stdout, stderr): 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 @@ -114,8 +118,19 @@ def exec_spawn(l, env): 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): @@ -124,9 +139,15 @@ 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(): diff --git a/src/engine/SCons/Scanner/CTests.py b/src/engine/SCons/Scanner/CTests.py index c57e7f70..2ca522b8 100644 --- a/src/engine/SCons/Scanner/CTests.py +++ b/src/engine/SCons/Scanner/CTests.py @@ -221,6 +221,7 @@ def deps_match(self, deps, headers): 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) @@ -230,6 +231,7 @@ class CScannerTestCase1(unittest.TestCase): 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) @@ -239,6 +241,7 @@ class CScannerTestCase2(unittest.TestCase): 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) @@ -248,6 +251,7 @@ class CScannerTestCase3(unittest.TestCase): 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) @@ -257,6 +261,7 @@ class CScannerTestCase4(unittest.TestCase): 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) @@ -280,6 +285,7 @@ class CScannerTestCase5(unittest.TestCase): 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() @@ -294,6 +300,7 @@ class CScannerTestCase6(unittest.TestCase): 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) @@ -310,6 +317,7 @@ class CScannerTestCase8(unittest.TestCase): 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): @@ -334,6 +342,7 @@ class CScannerTestCase9(unittest.TestCase): 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=[]) @@ -348,6 +357,7 @@ class CScannerTestCase10(unittest.TestCase): 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')) @@ -367,6 +377,7 @@ class CScannerTestCase11(unittest.TestCase): 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) @@ -388,6 +399,7 @@ class CScannerTestCase12(unittest.TestCase): 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") @@ -400,6 +412,7 @@ class CScannerTestCase13(unittest.TestCase): 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) @@ -409,6 +422,7 @@ class CScannerTestCase14(unittest.TestCase): 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", diff --git a/src/engine/SCons/Script/Main.py b/src/engine/SCons/Script/Main.py index 73f96e2e..2c181128 100644 --- a/src/engine/SCons/Script/Main.py +++ b/src/engine/SCons/Script/Main.py @@ -588,29 +588,29 @@ def _create_path(plist): 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] ...") @@ -630,6 +630,10 @@ class OptParser(OptionParser): 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.") @@ -1048,6 +1052,9 @@ def _main(args, parser): 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 @@ -1291,8 +1298,21 @@ def _exec_main(): 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: diff --git a/src/engine/SCons/Script/SConscript.py b/src/engine/SCons/Script/SConscript.py index f932d309..dc896a00 100644 --- a/src/engine/SCons/Script/SConscript.py +++ b/src/engine/SCons/Script/SConscript.py @@ -176,7 +176,7 @@ def _SConscript(fs, *files, **kw): # 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 @@ -185,7 +185,7 @@ def _SConscript(fs, *files, **kw): 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 @@ -197,7 +197,18 @@ def _SConscript(fs, *files, **kw): # 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: @@ -208,6 +219,7 @@ def _SConscript(fs, *files, **kw): # 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 @@ -223,7 +235,16 @@ def _SConscript(fs, *files, **kw): # 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) @@ -374,6 +395,7 @@ class SConsEnvironment(SCons.Environment.Base): 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) @@ -383,11 +405,11 @@ class SConsEnvironment(SCons.Environment.Base): 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) @@ -490,8 +512,8 @@ class SConsEnvironment(SCons.Environment.Base): 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 diff --git a/src/engine/SCons/Tool/as.py b/src/engine/SCons/Tool/as.py index 5a267a52..1b1b4b3a 100644 --- a/src/engine/SCons/Tool/as.py +++ b/src/engine/SCons/Tool/as.py @@ -52,11 +52,15 @@ def generate(env): 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('') diff --git a/src/engine/SCons/Tool/fortran.py b/src/engine/SCons/Tool/fortran.py index b694a58c..b83e7d3b 100644 --- a/src/engine/SCons/Tool/fortran.py +++ b/src/engine/SCons/Tool/fortran.py @@ -146,7 +146,7 @@ def add_to_env(env): 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) diff --git a/src/engine/SCons/Tool/gcc.py b/src/engine/SCons/Tool/gcc.py index 1be665a9..ad02e0de 100644 --- a/src/engine/SCons/Tool/gcc.py +++ b/src/engine/SCons/Tool/gcc.py @@ -46,7 +46,7 @@ def generate(env): 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') diff --git a/src/engine/SCons/Tool/mingw.py b/src/engine/SCons/Tool/mingw.py index 5765e258..d679b53e 100644 --- a/src/engine/SCons/Tool/mingw.py +++ b/src/engine/SCons/Tool/mingw.py @@ -118,7 +118,7 @@ def generate(env): # 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) @@ -130,7 +130,6 @@ def generate(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'] = '' diff --git a/src/engine/SCons/Tool/mslink.xml b/src/engine/SCons/Tool/mslink.xml index 58cfb1d7..6499cfee 100644 --- a/src/engine/SCons/Tool/mslink.xml +++ b/src/engine/SCons/Tool/mslink.xml @@ -37,6 +37,20 @@ Example: env['PDB'] = 'hello.pdb' + +The Visual C++ compiler switch that SCons uses by default +to generate PDB information is . +This works correctly with parallel () 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 instead may yield improved +link-time performance, +although parallel builds will no longer work. +You can generate PDB files with the +switch by overriding the default &cv-CCPDBFLAGS; variable; +see the entry for that variable for specific examples. diff --git a/src/engine/SCons/Tool/msvc.py b/src/engine/SCons/Tool/msvc.py index 86cde784..80b59263 100644 --- a/src/engine/SCons/Tool/msvc.py +++ b/src/engine/SCons/Tool/msvc.py @@ -517,9 +517,10 @@ def _get_msvc8_default_paths(env, version, suite, use_mfc_dirs): 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'] ) ) @@ -658,7 +659,10 @@ pch_builder = SCons.Builder.Builder(action=pch_action, suffix='.pch', 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) diff --git a/src/engine/SCons/Tool/msvc.xml b/src/engine/SCons/Tool/msvc.xml index 252d9628..1c0f3fa2 100644 --- a/src/engine/SCons/Tool/msvc.xml +++ b/src/engine/SCons/Tool/msvc.xml @@ -47,6 +47,53 @@ env.RES('resource.rc') + + +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. + + + + +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 . +This works correctly with parallel () 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 instead may yield improved +link-time performance, +although parallel builds will no longer work. + +You can generate PDB files with the +switch by overriding the default &cv-CCPDBFLAGS; variable as follows: + + +import SCons.Util +env['CCPDBFLAGS'] = SCons.Util.CLVar(['${(PDB and "/Zi /Fd%s" % File(PDB)) or ""}']) + + +An alternative would be to use the +to put the debugging information in a separate .pdb +file for each object file by overriding +the &cv-CCPDBFLAGS; variable as follows: + + +env['CCPDBFLAGS'] = '/Zi /Fd${TARGET}.pdb' + + + The Microsoft Visual C++ precompiled header that will be used when compiling diff --git a/src/engine/SCons/Tool/msvs.py b/src/engine/SCons/Tool/msvs.py index e8aaf834..e35c92ab 100644 --- a/src/engine/SCons/Tool/msvs.py +++ b/src/engine/SCons/Tool/msvs.py @@ -297,7 +297,7 @@ class _DSPGenerator: 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 @@ -316,7 +316,7 @@ class _DSPGenerator: 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(): @@ -690,6 +690,29 @@ class _GenerateV7DSP(_DSPGenerator): 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\n' % (key)) + self.printSources(value, commonprefix) + self.file.write('\t\t\t\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\n' + '\t\t\t\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', @@ -708,43 +731,26 @@ class _GenerateV7DSP(_DSPGenerator): '\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\n' % (key)) - printSources(value, commonprefix) - self.file.write('\t\t\t\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\n' - '\t\t\t\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\n') @@ -873,7 +879,7 @@ class _GenerateV7DSW(_DSWGenerator): 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) @@ -892,10 +898,10 @@ class _GenerateV7DSW(_DSWGenerator): "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(): @@ -1127,32 +1133,24 @@ def GenerateDSW(dswfile, source, env): 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(): """ diff --git a/src/engine/SCons/Tool/msvsTests.py b/src/engine/SCons/Tool/msvsTests.py index 6095dff6..b1125e71 100644 --- a/src/engine/SCons/Tool/msvsTests.py +++ b/src/engine/SCons/Tool/msvsTests.py @@ -471,6 +471,18 @@ class msvsTestCase(unittest.TestCase): 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() diff --git a/src/engine/SCons/cpp.py b/src/engine/SCons/cpp.py new file mode 100644 index 00000000..9bf5779a --- /dev/null +++ b/src/engine/SCons/cpp.py @@ -0,0 +1,561 @@ +# +# __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 + # + # 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 ' 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__ diff --git a/src/engine/SCons/cppTests.py b/src/engine/SCons/cppTests.py new file mode 100644 index 00000000..0959e2cc --- /dev/null +++ b/src/engine/SCons/cppTests.py @@ -0,0 +1,573 @@ +# +# __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 +""" + + +substitution_input = """ +#define FILE3 "file3-yes" +#define FILE4 + +#include FILE3 +#include FILE4 + +#define XXX_FILE5 YYY_FILE5 +#define YYY_FILE5 ZZZ_FILE5 +#define ZZZ_FILE5 FILE5 + +#define FILE5 "file5-yes" +#define FILE6 + +#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 +#else +#include +#endif +""" + + +if_boolean_input = """ +#define ZERO 0 +#define ONE 1 + +#if ZERO +#include "file9-no" +#else +#include "file9-yes" +#endif + +#if ONE +#include +#else +#include +#endif + +#if ZERO +#include "file11-no-1" +#elif ZERO +#include "file11-no-2" +#else +#include "file11-yes" +#endif + +#if ZERO +#include +#elif ONE +#include +#else +#include +#endif + +#if ONE +#include "file13-yes" +#elif ZERO +#include "file13-no-1" +#else +#include "file13-no-2" +#endif + +#if ONE +#include +#elif ONE +#include +#else +#include +#endif +""" + + +if_defined_input = """ +#define DEFINED 0 + +#if defined(DEFINED) +#include "file15-yes" +#endif + +#if ! defined(DEFINED) +#include +#else +#include +#endif + +#if defined DEFINED +#include "file17-yes" +#endif + +#if ! defined DEFINED +#include +#else +#include +#endif +""" + + +expression_input = """ +#define ZERO 0 +#define ONE 1 + +#if ZERO && ZERO +#include "file19-no" +#else +#include "file19-yes" +#endif + +#if ZERO && ONE +#include +#else +#include +#endif + +#if ONE && ZERO +#include "file21-no" +#else +#include "file21-yes" +#endif + +#if ONE && ONE +#include +#else +#include +#endif + +#if ZERO || ZERO +#include "file23-no" +#else +#include "file23-yes" +#endif + +#if ZERO || ONE +#include +#else +#include +#endif + +#if ONE || ZERO +#include "file25-yes" +#else +#include "file25-no" +#endif + +#if ONE || ONE +#include +#else +#include +#endif + +#if ONE == ONE +#include "file27-yes" +#else +#include "file27-no" +#endif + +#if ONE != ONE +#include +#else +#include +#endif + +#if ! (ONE == ONE) +#include "file29-no" +#else +#include "file29-yes" +#endif + +#if ! (ONE != ONE) +#include +#else +#include +#endif +""" + + +undef_input = """ +#define UNDEFINE 0 + +#ifdef UNDEFINE +#include "file31-yes" +#else +#include "file31-no" +#endif + +#undef UNDEFINE + +#ifdef UNDEFINE +#include +#else +#include +#endif +""" + + +macro_function_input = """ +#define ZERO 0 +#define ONE 1 + +#define FUNC33(x) "file33-yes" +#define FUNC34(x) + +#include FUNC33(ZERO) +#include FUNC34(ZERO) + +#define FILE35 "file35-yes" +#define FILE36 + +#define FUNC35(x, y) FILE35 +#define FUNC36(x, y) FILE36 + +#include FUNC35(ZERO, ONE) +#include FUNC36(ZERO, ONE) + +#define FILE37 "file37-yes" +#define FILE38 + +#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 + +#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) + diff --git a/src/test_copyrights.py b/src/test_copyrights.py index 195649bf..3f7d1c9a 100644 --- a/src/test_copyrights.py +++ b/src/test_copyrights.py @@ -46,9 +46,12 @@ try: 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') diff --git a/src/test_files.py b/src/test_files.py new file mode 100644 index 00000000..1424c623 --- /dev/null +++ b/src/test_files.py @@ -0,0 +1,100 @@ +#!/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() diff --git a/src/test_setup.py b/src/test_setup.py index d6128972..e2bb48b8 100644 --- a/src/test_setup.py +++ b/src/test_setup.py @@ -40,15 +40,11 @@ import sys 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 @@ -203,8 +199,9 @@ if not os.path.isdir(scons_version) and os.path.isfile(tar_gz): 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, diff --git a/test/AR/AR.py b/test/AR/AR.py index 32419fa0..cb11175b 100644 --- a/test/AR/AR.py +++ b/test/AR/AR.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -45,7 +45,7 @@ os.system(string.join(sys.argv[1:], " ")) 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') @@ -53,9 +53,11 @@ obj = foo.Object('main', 'main.c') foo.Program(target = 'f', source = obj) bar.Program(target = 'b', source = obj) -""" % python) +""" % locals()) test.write('foo.c', r""" +#include + void library_function(void) { @@ -64,6 +66,8 @@ library_function(void) """) test.write('bar.c', r""" +#include + void library_function(void) { @@ -72,6 +76,9 @@ library_function(void) """) test.write('main.c', r""" +#include +#include + int main(int argc, char *argv[]) { diff --git a/test/AR/ARCOM.py b/test/AR/ARCOM.py index c8ac1d87..73c36fc7 100644 --- a/test/AR/ARCOM.py +++ b/test/AR/ARCOM.py @@ -30,7 +30,7 @@ Test the ability to configure the $ARCOM construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -51,12 +51,12 @@ test.write('myranlib.py', """ 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") diff --git a/test/AR/ARCOMSTR.py b/test/AR/ARCOMSTR.py index ae63ea06..914031b5 100644 --- a/test/AR/ARCOMSTR.py +++ b/test/AR/ARCOMSTR.py @@ -32,7 +32,7 @@ the displayed archiver string. import TestSCons import string -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -53,13 +53,13 @@ test.write('myranlib.py', """ 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") diff --git a/test/AR/ARFLAGS.py b/test/AR/ARFLAGS.py index 399170ea..d4d122e2 100644 --- a/test/AR/ARFLAGS.py +++ b/test/AR/ARFLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -45,7 +45,7 @@ os.system(string.join(sys.argv[1:], " ")) 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') @@ -53,9 +53,11 @@ obj = foo.Object('main', 'main.c') foo.Program(target = 'f', source = obj) bar.Program(target = 'b', source = obj) -""" % python) +""" % locals()) test.write('foo.c', r""" +#include + void library_function(void) { @@ -64,6 +66,8 @@ library_function(void) """) test.write('bar.c', r""" +#include + void library_function(void) { @@ -72,6 +76,8 @@ library_function(void) """) test.write('main.c', r""" +#include + int main(int argc, char *argv[]) { diff --git a/test/AS/AS.py b/test/AS/AS.py index 0543a0cc..2c9e624d 100644 --- a/test/AS/AS.py +++ b/test/AS/AS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -110,17 +110,16 @@ sys.exit(0) """) 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 @@ -183,12 +182,12 @@ os.system(cmd) 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" @@ -226,6 +225,9 @@ name: """) test.write('aaa_main.c', r""" +#include +#include + extern char name[]; int @@ -238,6 +240,9 @@ main(int argc, char *argv[]) """) test.write('bbb_main.c', r""" +#include +#include + extern char name[]; int @@ -250,6 +255,9 @@ main(int argc, char *argv[]) """) test.write('ccc_main.c', r""" +#include +#include + extern char name[]; int @@ -309,10 +317,10 @@ import os 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', """ @@ -398,11 +406,11 @@ os.system(string.join(sys.argv[1:], " ")) 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', """ diff --git a/test/AS/ASCOM.py b/test/AS/ASCOM.py index da66bcae..42925814 100644 --- a/test/AS/ASCOM.py +++ b/test/AS/ASCOM.py @@ -33,7 +33,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -56,18 +56,27 @@ else: 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 = '.') @@ -75,6 +84,10 @@ test.fail_test(test.read('test1.obj') != "test1.s\n") 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") diff --git a/test/AS/ASCOMSTR.py b/test/AS/ASCOMSTR.py index c8eed62d..287da160 100644 --- a/test/AS/ASCOMSTR.py +++ b/test/AS/ASCOMSTR.py @@ -34,7 +34,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -57,7 +57,7 @@ else: 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') diff --git a/test/AS/ASFLAGS.py b/test/AS/ASFLAGS.py index 6396c45d..a0da9ffb 100644 --- a/test/AS/ASFLAGS.py +++ b/test/AS/ASFLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() _exe = TestSCons._exe @@ -126,17 +126,17 @@ sys.exit(0) 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 diff --git a/test/AS/ASPP.py b/test/AS/ASPP.py index da476183..2045a3d6 100644 --- a/test/AS/ASPP.py +++ b/test/AS/ASPP.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -110,13 +110,13 @@ sys.exit(0) """) 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 diff --git a/test/AS/ASPPCOM.py b/test/AS/ASPPCOM.py index e8773543..bb330dcd 100644 --- a/test/AS/ASPPCOM.py +++ b/test/AS/ASPPCOM.py @@ -33,7 +33,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,19 +49,26 @@ sys.exit(0) """) 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") diff --git a/test/AS/ASPPCOMSTR.py b/test/AS/ASPPCOMSTR.py index 21e8033b..1956154c 100644 --- a/test/AS/ASPPCOMSTR.py +++ b/test/AS/ASPPCOMSTR.py @@ -34,7 +34,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -50,7 +50,7 @@ sys.exit(0) """) 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') diff --git a/test/AS/ASPPFLAGS.py b/test/AS/ASPPFLAGS.py index cbd43392..27858bdb 100644 --- a/test/AS/ASPPFLAGS.py +++ b/test/AS/ASPPFLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() _exe = TestSCons._exe @@ -126,10 +126,10 @@ sys.exit(0) 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()) diff --git a/test/Actions/actions.py b/test/Actions/actions.py index 7ae951a3..61c3c7d0 100644 --- a/test/Actions/actions.py +++ b/test/Actions/actions.py @@ -27,7 +27,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -41,10 +41,10 @@ sys.exit(0) """) 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") @@ -55,10 +55,10 @@ test.fail_test(test.read('foo.out') != "1\nfoo.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 = '.') @@ -70,14 +70,14 @@ test.write('SConstruct', """ 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) @@ -91,7 +91,7 @@ assert not globals().has_key('string') 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 @@ -102,7 +102,7 @@ class bld: B = Builder(action = bld()) env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'foo.out', source = 'foo.in') -""" % python) +""" % locals()) test.run(arguments = '.') diff --git a/test/Actions/pre-post.py b/test/Actions/pre-post.py index e25def50..e076f24f 100644 --- a/test/Actions/pre-post.py +++ b/test/Actions/pre-post.py @@ -34,7 +34,7 @@ import sys import TestSCons _exe = TestSCons._exe -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -187,7 +187,7 @@ def post_action(target, source, env): 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()) diff --git a/test/Alias/Alias.py b/test/Alias/Alias.py index 56efafdc..b53b8ce4 100644 --- a/test/Alias/Alias.py +++ b/test/Alias/Alias.py @@ -29,7 +29,7 @@ import sys import TestSCons import TestCmd -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons(match=TestCmd.match_re) @@ -42,7 +42,7 @@ sys.exit(0) """) 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') @@ -62,7 +62,7 @@ env.Depends('f1.out', 'bar') assert Alias('foo') == foo assert Alias('bar') == bar -""" % python) +""" % locals()) test.write(['sub1', 'SConscript'], """ Import("env") @@ -134,7 +134,7 @@ test.up_to_date(arguments = 'f1.out') 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') @@ -147,7 +147,7 @@ env.Alias('bar', ['sub2', 'f3.out']) 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')) @@ -157,12 +157,12 @@ test.fail_test(not os.path.exists(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') diff --git a/test/BadBuilder.py b/test/BadBuilder.py index 4667a218..8c28ea57 100644 --- a/test/BadBuilder.py +++ b/test/BadBuilder.py @@ -34,6 +34,8 @@ import TestSCons test = TestSCons.TestSCons() +SConstruct_path = test.workpath('SConstruct') + sconstruct = """ def buildop(env, source, target): outf = open(str(target[0]), 'wb') @@ -58,42 +60,42 @@ built ### 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() diff --git a/test/BitKeeper/BITKEEPERCOM.py b/test/BitKeeper/BITKEEPERCOM.py index 2b76cc30..a4bdd90e 100644 --- a/test/BitKeeper/BITKEEPERCOM.py +++ b/test/BitKeeper/BITKEEPERCOM.py @@ -32,7 +32,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -65,7 +65,7 @@ def cat(env, source, target): 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') @@ -92,19 +92,19 @@ test.write(['BitKeeper', 'sub', 'fff.in'], "BitKeeper/sub/fff.in\n") 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())) diff --git a/test/BitKeeper/BITKEEPERCOMSTR.py b/test/BitKeeper/BITKEEPERCOMSTR.py index 604642bb..aa9e2a0a 100644 --- a/test/BitKeeper/BITKEEPERCOMSTR.py +++ b/test/BitKeeper/BITKEEPERCOMSTR.py @@ -32,7 +32,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -65,7 +65,7 @@ def cat(env, source, target): 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') diff --git a/test/BuildDir/BuildDir.py b/test/BuildDir/BuildDir.py index 0bae185a..f655bf92 100644 --- a/test/BuildDir/BuildDir.py +++ b/test/BuildDir/BuildDir.py @@ -129,6 +129,9 @@ if fortran and env.Detect(fortran): """ % (fortran_runtime, fortran_runtime)) test.write(['work1', 'src', 'f1.c'], r""" +#include +#include + #include "f1.h" int @@ -141,6 +144,9 @@ main(int argc, char *argv[]) """) test.write(['work1', 'src', 'f2.in'], r""" +#include +#include + #include "f2.h" int @@ -153,6 +159,9 @@ main(int argc, char *argv[]) """) test.write(['work1', 'src', 'f3.c'], r""" +#include +#include + #include "f3.h" int @@ -165,6 +174,9 @@ main(int argc, char *argv[]) """) test.write(['work1', 'src', 'f4.in'], r""" +#include +#include + #include "f4.h" int @@ -325,6 +337,9 @@ env.Program('prog.c') """) test.write(['work2', 'prog.c'], r""" +#include +#include + int main(int argc, char *argv[]) { diff --git a/test/BuildDir/Sconscript-build_dir.py b/test/BuildDir/Sconscript-build_dir.py index 298eb9bd..685011d9 100644 --- a/test/BuildDir/Sconscript-build_dir.py +++ b/test/BuildDir/Sconscript-build_dir.py @@ -212,6 +212,9 @@ env.Program('foo', [foo_obj, 'bar.c']) """) test.write(['test2', 'bar.c'], r""" +#include +#include + void bar(void) { printf("bar.c\n"); @@ -219,6 +222,9 @@ bar(void) { """) test.write(['test2', 'foo.c'], r""" +#include +#include + int main(int argc, char *argv[]) { bar(); diff --git a/test/BuildDir/errors.py b/test/BuildDir/errors.py index 285b996c..4fcd6257 100644 --- a/test/BuildDir/errors.py +++ b/test/BuildDir/errors.py @@ -155,17 +155,22 @@ f.close() # 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() diff --git a/test/BuildDir/nested-sconscripts.py b/test/BuildDir/nested-sconscripts.py new file mode 100644 index 00000000..d9e110e2 --- /dev/null +++ b/test/BuildDir/nested-sconscripts.py @@ -0,0 +1,64 @@ +#!/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() diff --git a/test/BuildDir/reflect.py b/test/BuildDir/reflect.py index beb7df05..9a25029a 100644 --- a/test/BuildDir/reflect.py +++ b/test/BuildDir/reflect.py @@ -39,8 +39,9 @@ import re 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' @@ -51,8 +52,8 @@ print 'Link' """) 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 '#' @@ -86,17 +87,16 @@ test.write('SConstruct', sconstruct % locals() ) 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 @@ -120,9 +120,9 @@ INC_CNI = re.escape(os.path.join('INC_dir1', 'dir2_CNI')) 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, diff --git a/test/CC/CC.py b/test/CC/CC.py index a790baa0..c57b7db9 100644 --- a/test/CC/CC.py +++ b/test/CC/CC.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -108,13 +108,13 @@ sys.exit(0) 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*/ @@ -129,11 +129,11 @@ if os.path.normcase('.c') == os.path.normcase('.C'): 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*/ @@ -158,12 +158,15 @@ os.system(string.join(sys.argv[1:], " ")) 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 +#include + int main(int argc, char *argv[]) { @@ -174,6 +177,9 @@ main(int argc, char *argv[]) """) test.write('bar.c', r""" +#include +#include + int main(int argc, char *argv[]) { diff --git a/test/CC/CCCOM.py b/test/CC/CCCOM.py index 1be89a3b..ca13ec81 100644 --- a/test/CC/CCCOM.py +++ b/test/CC/CCCOM.py @@ -33,7 +33,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -55,7 +55,7 @@ else: 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') diff --git a/test/CC/CCCOMSTR.py b/test/CC/CCCOMSTR.py index 1dd6a574..50ddb5ad 100644 --- a/test/CC/CCCOMSTR.py +++ b/test/CC/CCCOMSTR.py @@ -34,7 +34,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -56,7 +56,7 @@ else: 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') diff --git a/test/CC/CCFLAGS.py b/test/CC/CCFLAGS.py index d05cdef5..bee24992 100644 --- a/test/CC/CCFLAGS.py +++ b/test/CC/CCFLAGS.py @@ -50,6 +50,9 @@ foo.Program(target = 'prog', source = 'prog.c', """ % (fooflags, barflags, _obj, _obj, _obj, _obj)) test.write('prog.c', r""" +#include +#include + int main(int argc, char *argv[]) { diff --git a/test/CC/SHCC.py b/test/CC/SHCC.py index 3679a9e4..9a025b15 100644 --- a/test/CC/SHCC.py +++ b/test/CC/SHCC.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -44,12 +44,15 @@ os.system(string.join(sys.argv[1:], " ")) 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 +#include + int main(int argc, char *argv[]) { @@ -60,6 +63,9 @@ main(int argc, char *argv[]) """) test.write('bar.c', r""" +#include +#include + int main(int argc, char *argv[]) { diff --git a/test/CC/SHCCCOM.py b/test/CC/SHCCCOM.py index 13cdaa8a..5606fd03 100644 --- a/test/CC/SHCCCOM.py +++ b/test/CC/SHCCCOM.py @@ -33,7 +33,7 @@ import TestSCons Test the ability to configure the $SHCCCOM construction variable. """ -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -54,7 +54,7 @@ else: 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') diff --git a/test/CC/SHCCCOMSTR.py b/test/CC/SHCCCOMSTR.py index 27e5cbc3..4d240ae0 100644 --- a/test/CC/SHCCCOMSTR.py +++ b/test/CC/SHCCCOMSTR.py @@ -34,7 +34,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -56,7 +56,7 @@ else: 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') diff --git a/test/CC/SHCCFLAGS.py b/test/CC/SHCCFLAGS.py index 1f4fd3de..316da0f0 100644 --- a/test/CC/SHCCFLAGS.py +++ b/test/CC/SHCCFLAGS.py @@ -28,16 +28,13 @@ import sys 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: @@ -79,6 +76,8 @@ EXPORTS """) test.write('prog.c', r""" +#include + void doIt() { diff --git a/test/CFILESUFFIX.py b/test/CFILESUFFIX.py index a122fe06..9cbadf24 100644 --- a/test/CFILESUFFIX.py +++ b/test/CFILESUFFIX.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -46,10 +46,10 @@ sys.exit(0) """) 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 diff --git a/test/CPPDEFINES.py b/test/CPPDEFINES.py index 7c654019..8639eb27 100644 --- a/test/CPPDEFINES.py +++ b/test/CPPDEFINES.py @@ -87,6 +87,9 @@ baz.Program(target = 'baz', source = 'baz.cpp') """) test.write('prog.c', r""" +#include +#include + int main(int argc, char *argv[]) { diff --git a/test/CPPFLAGS.py b/test/CPPFLAGS.py index 72b10b79..ce8bd775 100644 --- a/test/CPPFLAGS.py +++ b/test/CPPFLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe _obj = TestSCons._obj _shobj = TestSCons._shobj @@ -102,14 +102,14 @@ sys.exit(0) 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 @@ -139,15 +139,15 @@ else: 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 diff --git a/test/CPPSUFFIXES.py b/test/CPPSUFFIXES.py index a340a4a0..305cf044 100644 --- a/test/CPPSUFFIXES.py +++ b/test/CPPSUFFIXES.py @@ -30,7 +30,7 @@ Test the ability to scan additional filesuffixes added to $CPPSUFFIXES. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -51,7 +51,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(CPPPATH = ['.'], - CC = r'%s mycc.py', + CC = r'%(_python_)s mycc.py', CCFLAGS = [], CCCOM = '$CC $TARGET $SOURCES', OBJSUFFIX = '.o') @@ -60,7 +60,7 @@ env.Object(target = 'test1', source = 'test1.c') 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 @@ -80,12 +80,14 @@ test1.x 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 @@ -99,9 +101,11 @@ test.up_to_date(arguments='.') 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 @@ -118,10 +122,12 @@ test1.x 2 #include """) -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 @@ -138,10 +144,12 @@ test1.h 2 #include """) -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 diff --git a/test/CVS.py b/test/CVS.py index 3002ee76..c21d9ad3 100644 --- a/test/CVS.py +++ b/test/CVS.py @@ -97,7 +97,8 @@ def cat(env, source, target): 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') @@ -161,7 +162,8 @@ def cat(env, source, target): 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') @@ -232,7 +234,8 @@ def cat(env, source, target): 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') diff --git a/test/CVSCOM.py b/test/CVSCOM.py index f8eaa6a2..cbb2f3ff 100644 --- a/test/CVSCOM.py +++ b/test/CVSCOM.py @@ -32,7 +32,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -65,7 +65,7 @@ def cat(env, source, target): 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') @@ -92,19 +92,19 @@ test.write(['CVS', 'sub', 'fff.in'], "CVS/sub/fff.in\n") 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())) diff --git a/test/CVSCOMSTR.py b/test/CVSCOMSTR.py index 78c40f7e..acf0647a 100644 --- a/test/CVSCOMSTR.py +++ b/test/CVSCOMSTR.py @@ -32,7 +32,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -65,7 +65,7 @@ def cat(env, source, target): 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') diff --git a/test/CXX/CXX.py b/test/CXX/CXX.py index 70a9b827..a1b4c2a3 100644 --- a/test/CXX/CXX.py +++ b/test/CXX/CXX.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -107,16 +107,16 @@ sys.exit(0) """) 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++*/ @@ -158,12 +158,12 @@ test.must_match('test5' + _exe, "This is a .C++ file.\n") 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++*/ @@ -188,10 +188,10 @@ os.system(string.join(sys.argv[1:], " ")) 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 diff --git a/test/CXX/CXXCOM.py b/test/CXX/CXXCOM.py index c4c419d6..c98fb8c8 100644 --- a/test/CXX/CXXCOM.py +++ b/test/CXX/CXXCOM.py @@ -33,7 +33,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -55,7 +55,7 @@ else: 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') diff --git a/test/CXX/CXXCOMSTR.py b/test/CXX/CXXCOMSTR.py index 82f7ace6..23bd3e63 100644 --- a/test/CXX/CXXCOMSTR.py +++ b/test/CXX/CXXCOMSTR.py @@ -34,7 +34,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -56,7 +56,7 @@ else: 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') diff --git a/test/CXX/CXXFILESUFFIX.py b/test/CXX/CXXFILESUFFIX.py index 8f4c4fa1..62e8cc10 100644 --- a/test/CXX/CXXFILESUFFIX.py +++ b/test/CXX/CXXFILESUFFIX.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -46,10 +46,10 @@ sys.exit(0) """) 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 diff --git a/test/CXX/SHCXX.py b/test/CXX/SHCXX.py index 5c050d1e..c02086b4 100644 --- a/test/CXX/SHCXX.py +++ b/test/CXX/SHCXX.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -44,10 +44,10 @@ os.system(string.join(sys.argv[1:], " ")) 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 diff --git a/test/CXX/SHCXXCOM.py b/test/CXX/SHCXXCOM.py index 54ef0d53..600049e1 100644 --- a/test/CXX/SHCXXCOM.py +++ b/test/CXX/SHCXXCOM.py @@ -33,7 +33,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -55,7 +55,7 @@ else: 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') diff --git a/test/CXX/SHCXXCOMSTR.py b/test/CXX/SHCXXCOMSTR.py index ad3a9074..33beae7c 100644 --- a/test/CXX/SHCXXCOMSTR.py +++ b/test/CXX/SHCXXCOMSTR.py @@ -34,7 +34,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -56,7 +56,7 @@ else: 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') diff --git a/test/CXX/SHCXXFLAGS.py b/test/CXX/SHCXXFLAGS.py index 88da443d..049835c7 100644 --- a/test/CXX/SHCXXFLAGS.py +++ b/test/CXX/SHCXXFLAGS.py @@ -29,15 +29,8 @@ import TestSCons 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: @@ -45,6 +38,10 @@ 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) diff --git a/test/CacheDir.py b/test/CacheDir.py deleted file mode 100644 index 67d3ed4a..00000000 --- a/test/CacheDir.py +++ /dev/null @@ -1,324 +0,0 @@ -#!/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() diff --git a/test/CacheDir/BuildDir.py b/test/CacheDir/BuildDir.py new file mode 100644 index 00000000..d03bfa63 --- /dev/null +++ b/test/CacheDir/BuildDir.py @@ -0,0 +1,153 @@ +#!/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() diff --git a/test/CacheDir/CacheDir.py b/test/CacheDir/CacheDir.py new file mode 100644 index 00000000..f918707f --- /dev/null +++ b/test/CacheDir/CacheDir.py @@ -0,0 +1,157 @@ +#!/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() diff --git a/test/CacheDir/SideEffect.py b/test/CacheDir/SideEffect.py new file mode 100644 index 00000000..814a5e37 --- /dev/null +++ b/test/CacheDir/SideEffect.py @@ -0,0 +1,107 @@ +#!/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() diff --git a/test/CacheDir/debug.py b/test/CacheDir/debug.py new file mode 100644 index 00000000..ebf67f71 --- /dev/null +++ b/test/CacheDir/debug.py @@ -0,0 +1,177 @@ +#!/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() diff --git a/test/CacheDir/multi-targets.py b/test/CacheDir/multi-targets.py new file mode 100644 index 00000000..0de03313 --- /dev/null +++ b/test/CacheDir/multi-targets.py @@ -0,0 +1,70 @@ +#!/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() diff --git a/test/CacheDir/source-scanner.py b/test/CacheDir/source-scanner.py new file mode 100644 index 00000000..119a959d --- /dev/null +++ b/test/CacheDir/source-scanner.py @@ -0,0 +1,84 @@ +#!/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() diff --git a/test/Case.py b/test/Case.py index 18fb60a9..9b6bb947 100644 --- a/test/Case.py +++ b/test/Case.py @@ -40,6 +40,8 @@ Program('main', [ """) test.write('main.c', """\ +#include + void foo(); void bar(); int main() { diff --git a/test/Command.py b/test/Command.py index 6563bd9c..09c51abc 100644 --- a/test/Command.py +++ b/test/Command.py @@ -28,6 +28,7 @@ import sys import TestSCons python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -65,30 +66,30 @@ def sub(env, target, source): 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") diff --git a/test/CommandGenerator.py b/test/CommandGenerator.py index 4a99be89..947ad421 100644 --- a/test/CommandGenerator.py +++ b/test/CommandGenerator.py @@ -44,7 +44,7 @@ sys.exit(0) 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"]] @@ -54,7 +54,7 @@ env = Environment(BUILDERS = { 'b' : b }, 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") diff --git a/test/Configure/CONFIGUREDIR.py b/test/Configure/CONFIGUREDIR.py index 20648866..ae1ea2ba 100644 --- a/test/Configure/CONFIGUREDIR.py +++ b/test/Configure/CONFIGUREDIR.py @@ -1,6 +1,6 @@ #!/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 @@ -22,7 +22,7 @@ # 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 diff --git a/test/Configure/CONFIGURELOG.py b/test/Configure/CONFIGURELOG.py index 456fcc96..4b634404 100644 --- a/test/Configure/CONFIGURELOG.py +++ b/test/Configure/CONFIGURELOG.py @@ -33,7 +33,9 @@ import TestSCons 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) @@ -47,13 +49,13 @@ env = conf.Finish() 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') diff --git a/test/Configure/Configure.py b/test/Configure/Configure.py index 41c858b1..40636993 100644 --- a/test/Configure/Configure.py +++ b/test/Configure/Configure.py @@ -55,6 +55,7 @@ else: work_cnt = 0 work_dir = None python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() _obj = TestSCons._obj _exe = TestSCons._exe @@ -123,7 +124,7 @@ def checkLogAndStdout(checks, results, cached, 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) @@ -615,9 +616,9 @@ def CustomTest(*args): 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 @@ -673,7 +674,10 @@ conf.Finish() # 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']) @@ -687,15 +691,17 @@ if not (r1 and not r2): 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, @@ -722,7 +728,9 @@ File "SConstruct", line 6, in ? # 5.2 test the --config= 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']) @@ -736,10 +744,12 @@ env = conf.Finish() /* 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... ", diff --git a/test/DSUFFIXES.py b/test/DSUFFIXES.py index 9a5a55a1..a344112e 100644 --- a/test/DSUFFIXES.py +++ b/test/DSUFFIXES.py @@ -30,7 +30,7 @@ Test the ability to scan additional filesuffixes added to $DSUFFIXES. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -57,7 +57,7 @@ env = Environment() 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') @@ -66,7 +66,7 @@ env.Object(target = 'test1', source = 'test1.d') 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 @@ -86,12 +86,14 @@ import foo; 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 @@ -105,9 +107,11 @@ test.up_to_date(arguments='.') 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 @@ -124,10 +128,12 @@ test3.d 2 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 @@ -144,10 +150,12 @@ test2.d 2 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 diff --git a/test/DVIPDF/DVIPDF.py b/test/DVIPDF/DVIPDF.py index 8db57850..8d36e5a7 100644 --- a/test/DVIPDF/DVIPDF.py +++ b/test/DVIPDF/DVIPDF.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -72,15 +72,15 @@ sys.exit(0) """) 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 @@ -118,13 +118,13 @@ import os 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. diff --git a/test/DVIPDF/DVIPDFCOM.py b/test/DVIPDF/DVIPDFCOM.py index 61d5ce70..0d9cd8d8 100644 --- a/test/DVIPDF/DVIPDFCOM.py +++ b/test/DVIPDF/DVIPDFCOM.py @@ -30,7 +30,7 @@ Test the ability to configure the $DVIPDFCOM construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -48,9 +48,9 @@ sys.exit(0) 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") diff --git a/test/DVIPDF/DVIPDFCOMSTR.py b/test/DVIPDF/DVIPDFCOMSTR.py index 6e57adb5..cc0c9095 100644 --- a/test/DVIPDF/DVIPDFCOMSTR.py +++ b/test/DVIPDF/DVIPDFCOMSTR.py @@ -31,7 +31,7 @@ the displayed string when is called. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,10 +49,10 @@ sys.exit(0) 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") diff --git a/test/DVIPDF/DVIPDFFLAGS.py b/test/DVIPDF/DVIPDFFLAGS.py index e9bd8ba9..4268705d 100644 --- a/test/DVIPDF/DVIPDFFLAGS.py +++ b/test/DVIPDF/DVIPDFFLAGS.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -78,15 +78,15 @@ sys.exit(0) """) 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 @@ -124,13 +124,13 @@ import os 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. diff --git a/test/DVIPS/DVIPS.py b/test/DVIPS/DVIPS.py index 2ae856a5..490ac953 100644 --- a/test/DVIPS/DVIPS.py +++ b/test/DVIPS/DVIPS.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -72,16 +72,16 @@ sys.exit(0) """) 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 @@ -132,12 +132,12 @@ import os 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. diff --git a/test/DVIPS/DVIPSFLAGS.py b/test/DVIPS/DVIPSFLAGS.py index 82e57c59..635acb0b 100644 --- a/test/DVIPS/DVIPSFLAGS.py +++ b/test/DVIPS/DVIPSFLAGS.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -79,16 +79,16 @@ sys.exit(0) """) 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 @@ -139,12 +139,12 @@ import os 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. diff --git a/test/DVIPS/PSCOM.py b/test/DVIPS/PSCOM.py index 65e66a29..0d8408ec 100644 --- a/test/DVIPS/PSCOM.py +++ b/test/DVIPS/PSCOM.py @@ -30,7 +30,7 @@ Test the ability to configure the $PSCOM construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -48,9 +48,9 @@ sys.exit(0) 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") diff --git a/test/DVIPS/PSCOMSTR.py b/test/DVIPS/PSCOMSTR.py index 9a565a4a..67f960e5 100644 --- a/test/DVIPS/PSCOMSTR.py +++ b/test/DVIPS/PSCOMSTR.py @@ -31,7 +31,7 @@ the displayed string when is called. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,10 +49,10 @@ sys.exit(0) 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") diff --git a/test/Default.py b/test/Default.py index cda34b29..22fd883f 100644 --- a/test/Default.py +++ b/test/Default.py @@ -32,7 +32,7 @@ import os import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -54,44 +54,44 @@ file.close() # 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']: @@ -118,34 +118,34 @@ test.fail_test(test.read(test.workpath('five', 'bar.out')) != "five/bar.in\n") # 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 @@ -158,20 +158,20 @@ test.fail_test(test.read(test.workpath('eight', 'bar.out')) != "eight/bar.in\n") 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") @@ -186,19 +186,19 @@ test.subdir('ten', ['ten', 'sub2']) 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") @@ -211,12 +211,12 @@ test.fail_test(test.read(test.workpath('ten', 'sub2', 'xxx.out')) != "sub2/xxx.i 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"); diff --git a/test/Depends.py b/test/Depends.py index 284d6f74..d0b21991 100644 --- a/test/Depends.py +++ b/test/Depends.py @@ -28,7 +28,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -42,12 +42,15 @@ file.write(contents) 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') @@ -55,10 +58,7 @@ SConscript('subdir/SConscript', "env") 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") diff --git a/test/ENV.py b/test/ENV.py index 98d04f99..9a39f306 100644 --- a/test/ENV.py +++ b/test/ENV.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -38,14 +38,14 @@ bin2_build_py = test.workpath('bin2', 'build.py') 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 @@ -65,10 +65,10 @@ test.fail_test(test.read('env2.out') != "build.py env2\ninput file\n") 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""" diff --git a/test/ESCAPE.py b/test/ESCAPE.py index bee55bcc..08f4a1a4 100644 --- a/test/ESCAPE.py +++ b/test/ESCAPE.py @@ -30,7 +30,7 @@ Test the ESCAPE construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -52,7 +52,7 @@ def my_escape(s): 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") diff --git a/test/Environment.py b/test/Environment.py index 9851db7c..36c72e11 100644 --- a/test/Environment.py +++ b/test/Environment.py @@ -27,7 +27,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import TestSCons import sys -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -35,7 +35,7 @@ test.write('SConstruct', """ 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') @@ -45,7 +45,7 @@ assert target == target.File('foo.out') e2 = env.Environment(XXX='$BAR', YYY='$BLAT') print e2['XXX'] print e2['YYY'] -"""%python) +""" % locals()) test.write('build.py', """ import sys diff --git a/test/Execute.py b/test/Execute.py index 2637a6ac..44abc735 100644 --- a/test/Execute.py +++ b/test/Execute.py @@ -30,7 +30,7 @@ Test the Execute() function for executing actions directly. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -45,25 +45,25 @@ sys.exit(exitval) """) 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") diff --git a/test/Fortran/F77.py b/test/Fortran/F77.py index 1c27def2..682cfb03 100644 --- a/test/Fortran/F77.py +++ b/test/Fortran/F77.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -88,10 +88,10 @@ sys.exit(0) """) 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') @@ -106,9 +106,9 @@ env.Program(target = 'test11', source = 'test11.f90') 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') @@ -119,7 +119,7 @@ env2.Program(target = 'test27', source = 'test27.fpp') 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") @@ -191,12 +191,12 @@ os.system(string.join(sys.argv[1:], " ")) """ % 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 diff --git a/test/Fortran/F77COM.py b/test/Fortran/F77COM.py index 9de4d17a..c566d88e 100644 --- a/test/Fortran/F77COM.py +++ b/test/Fortran/F77COM.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -84,12 +84,12 @@ sys.exit(0) """) 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') @@ -104,10 +104,10 @@ env.Program(target = 'test11', source = 'test11.f90') 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') @@ -118,7 +118,7 @@ env2.Program(target = 'test27', source = 'test27.fpp') 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") diff --git a/test/Fortran/F77COMSTR.py b/test/Fortran/F77COMSTR.py index 721551d4..7f6f1a1f 100644 --- a/test/Fortran/F77COMSTR.py +++ b/test/Fortran/F77COMSTR.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -52,9 +52,9 @@ else: 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') diff --git a/test/Fortran/F77FLAGS.py b/test/Fortran/F77FLAGS.py index d50eeb91..b1d91426 100644 --- a/test/Fortran/F77FLAGS.py +++ b/test/Fortran/F77FLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() _exe = TestSCons._exe @@ -90,9 +90,9 @@ sys.exit(0) 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') @@ -104,7 +104,7 @@ env.Program(target = 'test07', source = 'test07.fpp') 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") @@ -146,12 +146,12 @@ os.system(string.join(sys.argv[1:], " ")) """ % 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 diff --git a/test/Fortran/F90.py b/test/Fortran/F90.py index 8f8bc453..6b38e8e3 100644 --- a/test/Fortran/F90.py +++ b/test/Fortran/F90.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -89,10 +89,10 @@ sys.exit(0) """) 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') @@ -107,7 +107,7 @@ env.Program(target = 'test11', source = 'test11.f90') 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") @@ -157,12 +157,12 @@ os.system(string.join(sys.argv[1:], " ")) """ % 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 diff --git a/test/Fortran/F90COM.py b/test/Fortran/F90COM.py index bb52340a..7a206da8 100644 --- a/test/Fortran/F90COM.py +++ b/test/Fortran/F90COM.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -84,12 +84,12 @@ sys.exit(0) """) 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') @@ -104,13 +104,13 @@ env.Program(target = 'test11', source = 'test11.f90') 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") diff --git a/test/Fortran/F90COMSTR.py b/test/Fortran/F90COMSTR.py index bf7451ce..e2e3cf5a 100644 --- a/test/Fortran/F90COMSTR.py +++ b/test/Fortran/F90COMSTR.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -52,9 +52,9 @@ else: 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') diff --git a/test/Fortran/F90FLAGS.py b/test/Fortran/F90FLAGS.py index 69f1dfa9..9a57eaea 100644 --- a/test/Fortran/F90FLAGS.py +++ b/test/Fortran/F90FLAGS.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() _exe = TestSCons._exe @@ -91,11 +91,11 @@ sys.exit(0) 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') @@ -111,7 +111,7 @@ env.Program(target = 'test11', source = 'test11.f90') 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") @@ -161,12 +161,12 @@ os.system(string.join(sys.argv[1:], " ")) """ % 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 diff --git a/test/Fortran/F95.py b/test/Fortran/F95.py index a19c9046..1b5fc410 100644 --- a/test/Fortran/F95.py +++ b/test/Fortran/F95.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -89,10 +89,10 @@ sys.exit(0) """) 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') @@ -107,7 +107,7 @@ env.Program(target = 'test11', source = 'test11.f90') 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") @@ -157,12 +157,12 @@ os.system(string.join(sys.argv[1:], " ")) """ % 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 diff --git a/test/Fortran/F95COM.py b/test/Fortran/F95COM.py index 26423f87..016230a9 100644 --- a/test/Fortran/F95COM.py +++ b/test/Fortran/F95COM.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -84,12 +84,12 @@ sys.exit(0) """) 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') @@ -104,13 +104,13 @@ env.Program(target = 'test11', source = 'test11.f90') 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") diff --git a/test/Fortran/F95COMSTR.py b/test/Fortran/F95COMSTR.py index 823ade6a..ed7d1e8a 100644 --- a/test/Fortran/F95COMSTR.py +++ b/test/Fortran/F95COMSTR.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -52,9 +52,9 @@ else: 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') diff --git a/test/Fortran/F95FLAGS.py b/test/Fortran/F95FLAGS.py index 883d9a39..7ccffed7 100644 --- a/test/Fortran/F95FLAGS.py +++ b/test/Fortran/F95FLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() _exe = TestSCons._exe @@ -91,11 +91,11 @@ sys.exit(0) 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') @@ -111,7 +111,7 @@ env.Program(target = 'test11', source = 'test11.f90') 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") @@ -161,12 +161,12 @@ os.system(string.join(sys.argv[1:], " ")) """ % 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 diff --git a/test/Fortran/FORTRAN.py b/test/Fortran/FORTRAN.py index 47a0a890..1bd44073 100644 --- a/test/Fortran/FORTRAN.py +++ b/test/Fortran/FORTRAN.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -87,9 +87,9 @@ sys.exit(0) """) 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') @@ -104,7 +104,7 @@ env.Program(target = 'test11', source = 'test11.f90') 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") @@ -154,12 +154,12 @@ os.system(string.join(sys.argv[1:], " ")) """ % 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 diff --git a/test/Fortran/FORTRANCOM.py b/test/Fortran/FORTRANCOM.py index f79ad6da..3e3fcb2d 100644 --- a/test/Fortran/FORTRANCOM.py +++ b/test/Fortran/FORTRANCOM.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -84,10 +84,10 @@ sys.exit(0) """) 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') @@ -102,7 +102,7 @@ env.Program(target = 'test11', source = 'test11.f90') 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") diff --git a/test/Fortran/FORTRANCOMSTR.py b/test/Fortran/FORTRANCOMSTR.py index db75d430..fd318c3a 100644 --- a/test/Fortran/FORTRANCOMSTR.py +++ b/test/Fortran/FORTRANCOMSTR.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -52,9 +52,9 @@ else: 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') diff --git a/test/Fortran/FORTRANFLAGS.py b/test/Fortran/FORTRANFLAGS.py index 8d77d630..6dd27d7f 100644 --- a/test/Fortran/FORTRANFLAGS.py +++ b/test/Fortran/FORTRANFLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() _exe = TestSCons._exe @@ -90,9 +90,9 @@ sys.exit(0) 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') @@ -108,7 +108,7 @@ env.Program(target = 'test11', source = 'test11.f90') 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") @@ -158,12 +158,12 @@ os.system(string.join(sys.argv[1:], " ")) """ % 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 diff --git a/test/Fortran/FORTRANMODDIR.py b/test/Fortran/FORTRANMODDIR.py index 4d594a18..f0c500cc 100644 --- a/test/Fortran/FORTRANMODDIR.py +++ b/test/Fortran/FORTRANMODDIR.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -51,7 +51,7 @@ sys.exit(0) """) 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()) diff --git a/test/Fortran/FORTRANSUFFIXES.py b/test/Fortran/FORTRANSUFFIXES.py index c172f7a3..3011fac7 100644 --- a/test/Fortran/FORTRANSUFFIXES.py +++ b/test/Fortran/FORTRANSUFFIXES.py @@ -30,7 +30,7 @@ Test the ability to scan additional filesuffixes added to $FORTRANSUFFIXES. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -51,7 +51,7 @@ sys.exit(0) 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']) @@ -59,7 +59,7 @@ env.Object(target = 'test1', source = 'test1.f') 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 @@ -81,12 +81,14 @@ test.write('foo.h', """\ 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 @@ -102,9 +104,11 @@ test.write('foo.h', """\ 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 @@ -121,10 +125,12 @@ test.write('test1.x', """\ 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 @@ -141,10 +147,12 @@ test.write('test1.h', """\ 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 diff --git a/test/Fortran/SHF77.py b/test/Fortran/SHF77.py index 233921b3..c9569c94 100644 --- a/test/Fortran/SHF77.py +++ b/test/Fortran/SHF77.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _obj = TestSCons._shobj test = TestSCons.TestSCons() @@ -54,8 +54,8 @@ sys.exit(0) 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') @@ -70,7 +70,7 @@ env.SharedObject(target = 'test11', source = 'test11.f90') 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') @@ -79,7 +79,7 @@ env2.SharedObject(target = 'test25', source = 'test25.ftn') 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") @@ -148,10 +148,10 @@ os.system(string.join(sys.argv[1:], " ")) 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 diff --git a/test/Fortran/SHF77COM.py b/test/Fortran/SHF77COM.py index fa024875..75192dfe 100644 --- a/test/Fortran/SHF77COM.py +++ b/test/Fortran/SHF77COM.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _obj = TestSCons._shobj test = TestSCons.TestSCons() @@ -50,10 +50,10 @@ sys.exit(0) 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') @@ -68,8 +68,8 @@ env.SharedObject(target = 'test11', source = 'test11.f90') 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') @@ -80,7 +80,7 @@ env2.SharedObject(target = 'test27', source = 'test27.fpp') 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") diff --git a/test/Fortran/SHF77COMSTR.py b/test/Fortran/SHF77COMSTR.py index fdb81c19..90855702 100644 --- a/test/Fortran/SHF77COMSTR.py +++ b/test/Fortran/SHF77COMSTR.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -52,9 +52,9 @@ else: 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') diff --git a/test/Fortran/SHF77FLAGS.py b/test/Fortran/SHF77FLAGS.py index 85c1168f..5354a576 100644 --- a/test/Fortran/SHF77FLAGS.py +++ b/test/Fortran/SHF77FLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ if sys.platform == 'win32': _obj = '.obj' @@ -63,7 +63,7 @@ sys.exit(0) 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') @@ -75,7 +75,7 @@ env.SharedObject(target = 'test07', source = 'test07.fpp') 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") @@ -117,12 +117,12 @@ os.system(string.join(sys.argv[1:], " ")) """ % 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 diff --git a/test/Fortran/SHF90.py b/test/Fortran/SHF90.py index 66bd68dc..1696b4a8 100644 --- a/test/Fortran/SHF90.py +++ b/test/Fortran/SHF90.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _obj = TestSCons._shobj test = TestSCons.TestSCons() @@ -54,8 +54,8 @@ sys.exit(0) 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') @@ -70,7 +70,7 @@ env.SharedObject(target = 'test11', source = 'test11.f90') 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") @@ -121,10 +121,10 @@ os.system(string.join(sys.argv[1:], " ")) 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 diff --git a/test/Fortran/SHF90COM.py b/test/Fortran/SHF90COM.py index ffc98789..13d9978a 100644 --- a/test/Fortran/SHF90COM.py +++ b/test/Fortran/SHF90COM.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _obj = TestSCons._shobj test = TestSCons.TestSCons() @@ -50,10 +50,10 @@ sys.exit(0) 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') @@ -68,11 +68,11 @@ env.SharedObject(target = 'test11', source = 'test11.f90') 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") diff --git a/test/Fortran/SHF90COMSTR.py b/test/Fortran/SHF90COMSTR.py index f0e44d3d..9633d451 100644 --- a/test/Fortran/SHF90COMSTR.py +++ b/test/Fortran/SHF90COMSTR.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -52,9 +52,9 @@ else: 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') diff --git a/test/Fortran/SHF90FLAGS.py b/test/Fortran/SHF90FLAGS.py index 3997cbb4..62bb7d0d 100644 --- a/test/Fortran/SHF90FLAGS.py +++ b/test/Fortran/SHF90FLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ if sys.platform == 'win32': _obj = '.obj' @@ -64,9 +64,9 @@ sys.exit(0) 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') @@ -82,7 +82,7 @@ env.SharedObject(target = 'test11', source = 'test11.f90') 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") @@ -132,12 +132,12 @@ os.system(string.join(sys.argv[1:], " ")) """ % 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 diff --git a/test/Fortran/SHF95.py b/test/Fortran/SHF95.py index d2d92a91..85702df2 100644 --- a/test/Fortran/SHF95.py +++ b/test/Fortran/SHF95.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _obj = TestSCons._shobj test = TestSCons.TestSCons() @@ -54,8 +54,8 @@ sys.exit(0) 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') @@ -70,7 +70,7 @@ env.SharedObject(target = 'test11', source = 'test11.f90') 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") @@ -121,10 +121,10 @@ os.system(string.join(sys.argv[1:], " ")) 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 diff --git a/test/Fortran/SHF95COM.py b/test/Fortran/SHF95COM.py index e28f8630..b11933a0 100644 --- a/test/Fortran/SHF95COM.py +++ b/test/Fortran/SHF95COM.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _obj = TestSCons._shobj test = TestSCons.TestSCons() @@ -50,10 +50,10 @@ sys.exit(0) 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') @@ -68,11 +68,11 @@ env.SharedObject(target = 'test11', source = 'test11.f90') 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") diff --git a/test/Fortran/SHF95COMSTR.py b/test/Fortran/SHF95COMSTR.py index 461d7ff6..eaa24ae7 100644 --- a/test/Fortran/SHF95COMSTR.py +++ b/test/Fortran/SHF95COMSTR.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -52,9 +52,9 @@ else: 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') diff --git a/test/Fortran/SHF95FLAGS.py b/test/Fortran/SHF95FLAGS.py index 782a495c..2288a4a5 100644 --- a/test/Fortran/SHF95FLAGS.py +++ b/test/Fortran/SHF95FLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ if sys.platform == 'win32': _obj = '.obj' @@ -64,9 +64,9 @@ sys.exit(0) 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') @@ -82,7 +82,7 @@ env.SharedObject(target = 'test11', source = 'test11.f90') 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") @@ -132,12 +132,12 @@ os.system(string.join(sys.argv[1:], " ")) """ % 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 diff --git a/test/Fortran/SHFORTRAN.py b/test/Fortran/SHFORTRAN.py index 17a58f5d..586b54e1 100644 --- a/test/Fortran/SHFORTRAN.py +++ b/test/Fortran/SHFORTRAN.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _obj = TestSCons._shobj test = TestSCons.TestSCons() @@ -53,7 +53,7 @@ sys.exit(0) 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') @@ -68,7 +68,7 @@ env.SharedObject(target = 'test11', source = 'test11.f90') 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") @@ -119,10 +119,10 @@ os.system(string.join(sys.argv[1:], " ")) 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 diff --git a/test/Fortran/SHFORTRANCOM.py b/test/Fortran/SHFORTRANCOM.py index f4d44dc6..21942cfa 100644 --- a/test/Fortran/SHFORTRANCOM.py +++ b/test/Fortran/SHFORTRANCOM.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _obj = TestSCons._shobj test = TestSCons.TestSCons() @@ -50,8 +50,8 @@ sys.exit(0) 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') @@ -66,7 +66,7 @@ env.SharedObject(target = 'test11', source = 'test11.f90') 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") diff --git a/test/Fortran/SHFORTRANCOMSTR.py b/test/Fortran/SHFORTRANCOMSTR.py index 8ad3b142..69a1eba7 100644 --- a/test/Fortran/SHFORTRANCOMSTR.py +++ b/test/Fortran/SHFORTRANCOMSTR.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -52,9 +52,9 @@ else: 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') diff --git a/test/Fortran/SHFORTRANFLAGS.py b/test/Fortran/SHFORTRANFLAGS.py index e96ade99..d09a2830 100644 --- a/test/Fortran/SHFORTRANFLAGS.py +++ b/test/Fortran/SHFORTRANFLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ if sys.platform == 'win32': _obj = '.obj' @@ -63,7 +63,7 @@ sys.exit(0) 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') @@ -79,7 +79,7 @@ env.SharedObject(target = 'test11', source = 'test11.f90') 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") @@ -129,13 +129,13 @@ os.system(string.join(sys.argv[1:], " ")) """ % 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 diff --git a/test/Fortran/USE-MODULE.py b/test/Fortran/USE-MODULE.py index 541c4570..23d0a894 100644 --- a/test/Fortran/USE-MODULE.py +++ b/test/Fortran/USE-MODULE.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -51,7 +51,7 @@ sys.exit(0) """) 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()) diff --git a/test/Fortran/module-subdir.py b/test/Fortran/module-subdir.py new file mode 100644 index 00000000..88d08880 --- /dev/null +++ b/test/Fortran/module-subdir.py @@ -0,0 +1,115 @@ +#!/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() diff --git a/test/Ghostscript/GS.py b/test/Ghostscript/GS.py index a836cf65..6089d60a 100644 --- a/test/Ghostscript/GS.py +++ b/test/Ghostscript/GS.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -48,11 +48,11 @@ sys.exit(0) """) 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 @@ -88,10 +88,10 @@ import os 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 diff --git a/test/Ghostscript/GSCOM.py b/test/Ghostscript/GSCOM.py index acd46f22..a41c8005 100644 --- a/test/Ghostscript/GSCOM.py +++ b/test/Ghostscript/GSCOM.py @@ -30,7 +30,7 @@ Test the ability to configure the $GSCOM construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -48,9 +48,9 @@ sys.exit(0) 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") diff --git a/test/Ghostscript/GSCOMSTR.py b/test/Ghostscript/GSCOMSTR.py index 9f7aee8f..923aee39 100644 --- a/test/Ghostscript/GSCOMSTR.py +++ b/test/Ghostscript/GSCOMSTR.py @@ -31,7 +31,7 @@ the displayed string when Ghostscript is called. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,10 +49,10 @@ sys.exit(0) 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") diff --git a/test/Ghostscript/GSFLAGS.py b/test/Ghostscript/GSFLAGS.py index 14ce7691..7acb89ec 100644 --- a/test/Ghostscript/GSFLAGS.py +++ b/test/Ghostscript/GSFLAGS.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -57,10 +57,10 @@ sys.exit(0) """) 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. diff --git a/test/IDL/MIDLCOM.py b/test/IDL/MIDLCOM.py index d3f64200..79857d06 100644 --- a/test/IDL/MIDLCOM.py +++ b/test/IDL/MIDLCOM.py @@ -30,7 +30,7 @@ Test the ability to configure the $MIDLCOM construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -48,9 +48,9 @@ sys.exit(0) 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") diff --git a/test/IDL/MIDLCOMSTR.py b/test/IDL/MIDLCOMSTR.py index 89a6e250..8c3a15a7 100644 --- a/test/IDL/MIDLCOMSTR.py +++ b/test/IDL/MIDLCOMSTR.py @@ -31,7 +31,7 @@ the displayed string when midl is called. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,10 +49,10 @@ sys.exit(0) 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") diff --git a/test/Ignore.py b/test/Ignore.py index 1652f605..15cf4f3c 100644 --- a/test/Ignore.py +++ b/test/Ignore.py @@ -28,7 +28,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -43,19 +43,19 @@ for arg in sys.argv[2:]: 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") diff --git a/test/Install/Install.py b/test/Install/Install.py index 7018466f..e24641be 100644 --- a/test/Install/Install.py +++ b/test/Install/Install.py @@ -46,6 +46,8 @@ f5_txt = test.workpath('outside', 'f5.txt') 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]) @@ -74,15 +76,13 @@ env3.Install(dir='export', source=t) 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") diff --git a/test/Install/InstallAs.py b/test/Install/InstallAs.py index 4fe4bd0b..7a6c9f6c 100644 --- a/test/Install/InstallAs.py +++ b/test/Install/InstallAs.py @@ -41,16 +41,16 @@ install_file1_out = test.workpath('install', 'file1.out') 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") diff --git a/test/Install/directories.py b/test/Install/directories.py new file mode 100644 index 00000000..300ed4dc --- /dev/null +++ b/test/Install/directories.py @@ -0,0 +1,95 @@ +#!/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() diff --git a/test/Java/JAR.py b/test/Java/JAR.py index 1344fb17..5342a484 100644 --- a/test/Java/JAR.py +++ b/test/Java/JAR.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -56,9 +56,9 @@ sys.exit(0) 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 @@ -74,9 +74,9 @@ if os.path.normcase('.class') == os.path.normcase('.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 @@ -100,13 +100,13 @@ sys.exit(0) 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') @@ -150,7 +150,7 @@ foo = Environment(tools = ['javac', 'jar'], 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') diff --git a/test/Java/JARCOM.py b/test/Java/JARCOM.py index 0d7ebba0..f03cd9f7 100644 --- a/test/Java/JARCOM.py +++ b/test/Java/JARCOM.py @@ -30,7 +30,7 @@ Test the ability to configure the $JARCOM construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -48,7 +48,7 @@ sys.exit(0) 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()) diff --git a/test/Java/JARCOMSTR.py b/test/Java/JARCOMSTR.py index aa8a6ad5..35404ce2 100644 --- a/test/Java/JARCOMSTR.py +++ b/test/Java/JARCOMSTR.py @@ -31,7 +31,7 @@ the jar output. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,7 +49,7 @@ sys.exit(0) 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()) diff --git a/test/Java/JAVAC.py b/test/Java/JAVAC.py index 93f0e7ba..b5fb3f86 100644 --- a/test/Java/JAVAC.py +++ b/test/Java/JAVAC.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -59,9 +59,9 @@ sys.exit(0) 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 @@ -77,9 +77,9 @@ if os.path.normcase('.java') == os.path.normcase('.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 @@ -114,13 +114,13 @@ os.system(string.join(sys.argv[1:], " ")) 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'], diff --git a/test/Java/JAVACCOM.py b/test/Java/JAVACCOM.py index 171649c1..7086a2a2 100644 --- a/test/Java/JAVACCOM.py +++ b/test/Java/JAVACCOM.py @@ -30,7 +30,7 @@ Test the ability to configure the $JAVACCOM construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -50,7 +50,7 @@ sys.exit(0) 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()) diff --git a/test/Java/JAVACCOMSTR.py b/test/Java/JAVACCOMSTR.py index 7f59e902..44b14496 100644 --- a/test/Java/JAVACCOMSTR.py +++ b/test/Java/JAVACCOMSTR.py @@ -33,7 +33,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -53,7 +53,7 @@ sys.exit(0) 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()) diff --git a/test/Java/JAVAH.py b/test/Java/JAVAH.py index eb70ac82..9901764d 100644 --- a/test/Java/JAVAH.py +++ b/test/Java/JAVAH.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -61,9 +61,9 @@ sys.exit(0) 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 @@ -79,9 +79,9 @@ if os.path.normcase('.java') == os.path.normcase('.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 @@ -126,7 +126,7 @@ foo = Environment(tools = ['javac', 'javah'], 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') diff --git a/test/Java/JAVAHCOM.py b/test/Java/JAVAHCOM.py index 1cc4208f..73067c61 100644 --- a/test/Java/JAVAHCOM.py +++ b/test/Java/JAVAHCOM.py @@ -30,7 +30,7 @@ Test the ability to configure the $JAVAHCOM construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -48,7 +48,7 @@ sys.exit(0) 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') diff --git a/test/Java/JAVAHCOMSTR.py b/test/Java/JAVAHCOMSTR.py index 2a14e1ce..8ee57670 100644 --- a/test/Java/JAVAHCOMSTR.py +++ b/test/Java/JAVAHCOMSTR.py @@ -33,7 +33,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -59,7 +59,7 @@ sys.exit(0) 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') diff --git a/test/Java/RMIC.py b/test/Java/RMIC.py index 7ef1359b..bb098e78 100644 --- a/test/Java/RMIC.py +++ b/test/Java/RMIC.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -60,9 +60,9 @@ sys.exit(0) 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 @@ -78,9 +78,9 @@ if os.path.normcase('.java') == os.path.normcase('.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 @@ -128,7 +128,7 @@ foo.RMIC(target = 'outdir1', 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 diff --git a/test/Java/RMICCOM.py b/test/Java/RMICCOM.py index 109c22e7..ed5e0d67 100644 --- a/test/Java/RMICCOM.py +++ b/test/Java/RMICCOM.py @@ -32,7 +32,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -58,7 +58,7 @@ sys.exit(0) 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') diff --git a/test/Java/RMICCOMSTR.py b/test/Java/RMICCOMSTR.py index 1bcf300a..5a451ebd 100644 --- a/test/Java/RMICCOMSTR.py +++ b/test/Java/RMICCOMSTR.py @@ -33,7 +33,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -59,7 +59,7 @@ sys.exit(0) 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') diff --git a/test/LEX/LEX.py b/test/LEX/LEX.py index 5515a3ed..3fd4db3d 100644 --- a/test/LEX/LEX.py +++ b/test/LEX/LEX.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -49,10 +49,10 @@ sys.exit(0) """) 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 @@ -97,10 +97,10 @@ os.system(string.join(sys.argv[1:], " ")) 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""" %%%% diff --git a/test/LEX/LEXCOM.py b/test/LEX/LEXCOM.py index ea4626d3..7ce8a15c 100644 --- a/test/LEX/LEXCOM.py +++ b/test/LEX/LEXCOM.py @@ -30,7 +30,7 @@ Test the ability to configure the $LEXCOM construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -48,10 +48,10 @@ sys.exit(0) 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") diff --git a/test/LEX/LEXCOMSTR.py b/test/LEX/LEXCOMSTR.py index 5b01df7b..a06c20c2 100644 --- a/test/LEX/LEXCOMSTR.py +++ b/test/LEX/LEXCOMSTR.py @@ -31,7 +31,7 @@ the displayed string when lex is called. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,11 +49,11 @@ sys.exit(0) 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") diff --git a/test/LEX/LEXFLAGS.py b/test/LEX/LEXFLAGS.py index 87a869fa..59239349 100644 --- a/test/LEX/LEXFLAGS.py +++ b/test/LEX/LEXFLAGS.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -52,9 +52,11 @@ sys.exit(0) """) 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 diff --git a/test/LIBPATH.py b/test/LIBPATH.py index c54d2acf..1ea7ed8f 100644 --- a/test/LIBPATH.py +++ b/test/LIBPATH.py @@ -57,6 +57,8 @@ env2.Library(target = 'foo2', source = f1) """) test.write('f1.c', r""" +#include + void f1(void) { @@ -75,6 +77,8 @@ test() """) test.write('prog.c', r""" +#include + void f1(void); int main(int argc, char *argv[]) @@ -102,6 +106,8 @@ test.fail_test(oldtime1 != os.path.getmtime(prog1)) test.fail_test(oldtime2 != os.path.getmtime(prog2)) test.write('f1.c', r""" +#include + void f1(void) { @@ -135,6 +141,8 @@ env2.Library(target = 'foo2', source = f1) test.up_to_date(arguments = '.', stderr=None) test.write('f1.c', r""" +#include + void f1(void) { diff --git a/test/LIBPREFIXES.py b/test/LIBPREFIXES.py index 753b9b30..1e5d6c2b 100644 --- a/test/LIBPREFIXES.py +++ b/test/LIBPREFIXES.py @@ -43,6 +43,8 @@ env.Program(target = 'prog', source = ['prog.c', lib]) """) test.write('foo.c', r""" +#include + void foo(void) { @@ -51,6 +53,8 @@ foo(void) """) test.write('prog.c', r""" +#include + void foo(void); int main(int argc, char *argv[]) diff --git a/test/LIBS.py b/test/LIBS.py index 3ff26e0d..708ce635 100644 --- a/test/LIBS.py +++ b/test/LIBS.py @@ -93,6 +93,7 @@ test.write('foo4.c', foo_contents) test.write('foo5.c', foo_contents) test.write('sl.c', """\ +#include void sl(void) { @@ -101,6 +102,7 @@ sl(void) """) test.write('slprog.c', """\ +#include int main(int argc, char *argv[]) { @@ -223,7 +225,7 @@ Program (source='main.c', target='blender', LIBS=libraries, LIBPREFIX='lib', LIB """) test.write('main.c', """\ -#include +#include #include "message2.h" int main (void) diff --git a/test/LIBSUFFIXES.py b/test/LIBSUFFIXES.py index c776ce0d..29cbb18e 100644 --- a/test/LIBSUFFIXES.py +++ b/test/LIBSUFFIXES.py @@ -43,6 +43,8 @@ env.Program(target = 'prog', source = ['prog.c', lib]) """) test.write('foo.c', r""" +#include + void foo(void) { @@ -51,6 +53,8 @@ foo(void) """) test.write('prog.c', r""" +#include + void foo(void); int main(int argc, char *argv[]) diff --git a/test/LINK/LINK.py b/test/LINK/LINK.py index 2d893523..ede03f5c 100644 --- a/test/LINK/LINK.py +++ b/test/LINK/LINK.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -45,12 +45,14 @@ os.system(string.join(sys.argv[1:], " ")) 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 +#include int main(int argc, char *argv[]) { @@ -61,6 +63,8 @@ main(int argc, char *argv[]) """) test.write('bar.c', r""" +#include +#include int main(int argc, char *argv[]) { diff --git a/test/LINK/LINKCOM.py b/test/LINK/LINKCOM.py index c94d5e31..d9140490 100644 --- a/test/LINK/LINKCOM.py +++ b/test/LINK/LINKCOM.py @@ -33,7 +33,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -51,7 +51,7 @@ sys.exit(0) """) 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']) diff --git a/test/LINK/LINKCOMSTR.py b/test/LINK/LINKCOMSTR.py index 70b5c0c4..1a7efbe1 100644 --- a/test/LINK/LINKCOMSTR.py +++ b/test/LINK/LINKCOMSTR.py @@ -34,7 +34,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -52,7 +52,7 @@ sys.exit(0) """) 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') diff --git a/test/LINK/LINKFLAGS.py b/test/LINK/LINKFLAGS.py index ca1cd1a8..d80960d1 100644 --- a/test/LINK/LINKFLAGS.py +++ b/test/LINK/LINKFLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -45,13 +45,15 @@ os.system(string.join(args, " ")) 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 +#include int main(int argc, char *argv[]) { @@ -62,6 +64,8 @@ main(int argc, char *argv[]) """) test.write('bar.c', r""" +#include +#include int main(int argc, char *argv[]) { diff --git a/test/LINK/SHLINK.py b/test/LINK/SHLINK.py index 8b9097d1..296845c2 100644 --- a/test/LINK/SHLINK.py +++ b/test/LINK/SHLINK.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ dll_ = TestSCons.dll_ _shlib = TestSCons._dll @@ -46,10 +46,10 @@ os.system(string.join(sys.argv[1:], " ")) 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 diff --git a/test/LINK/SHLINKCOM.py b/test/LINK/SHLINKCOM.py index d97c4edb..2d2f7184 100644 --- a/test/LINK/SHLINKCOM.py +++ b/test/LINK/SHLINKCOM.py @@ -33,7 +33,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -60,8 +60,8 @@ sys.exit(0) """) 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') diff --git a/test/LINK/SHLINKCOMSTR.py b/test/LINK/SHLINKCOMSTR.py index 1ea29b26..cf318133 100644 --- a/test/LINK/SHLINKCOMSTR.py +++ b/test/LINK/SHLINKCOMSTR.py @@ -34,7 +34,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -61,8 +61,8 @@ sys.exit(0) """) 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 = '', @@ -85,8 +85,8 @@ test2.c """) 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())) diff --git a/test/LINK/SHLINKFLAGS.py b/test/LINK/SHLINKFLAGS.py index 709ebc61..51a8f7c9 100644 --- a/test/LINK/SHLINKFLAGS.py +++ b/test/LINK/SHLINKFLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ lib_ = TestSCons.dll_ _shlib = TestSCons._dll @@ -46,11 +46,11 @@ os.system(string.join(args, " ")) 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 diff --git a/test/Library.py b/test/Library.py index e4626ab7..3a04b9c6 100644 --- a/test/Library.py +++ b/test/Library.py @@ -38,6 +38,7 @@ env.Program(target = 'prog', source = [ 'prog.cpp', libtgt ]) """) test.write('f1.c', r""" +#include void f1(void) { @@ -46,6 +47,7 @@ f1(void) """) test.write('f2a.c', r""" +#include void f2a(void) { @@ -54,6 +56,7 @@ f2a(void) """) test.write('f2b.c', r""" +#include void f2b(void) { @@ -62,6 +65,7 @@ f2b(void) """) test.write('f2c.c', r""" +#include void f2c(void) { @@ -70,6 +74,7 @@ f2c(void) """) test.write('f3a.c', r""" +#include void f3a(void) { @@ -78,6 +83,7 @@ f3a(void) """) test.write('f3b.c', r""" +#include void f3b(void) { diff --git a/test/M4/M4.py b/test/M4/M4.py index bf56e740..859c57ba 100644 --- a/test/M4/M4.py +++ b/test/M4/M4.py @@ -34,7 +34,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,9 +49,9 @@ sys.exit(0) """) 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 @@ -80,7 +80,7 @@ os.system(string.join(sys.argv[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()) diff --git a/test/M4/M4COM.py b/test/M4/M4COM.py index d1c53b4b..8c36d867 100644 --- a/test/M4/M4COM.py +++ b/test/M4/M4COM.py @@ -30,7 +30,7 @@ Test the ability to configure the $M4COM construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -48,9 +48,9 @@ sys.exit(0) 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") diff --git a/test/M4/M4COMSTR.py b/test/M4/M4COMSTR.py index 0e144952..a9e91e68 100644 --- a/test/M4/M4COMSTR.py +++ b/test/M4/M4COMSTR.py @@ -31,7 +31,7 @@ the displayed string when m4 is called. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,10 +49,10 @@ sys.exit(0) 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") diff --git a/test/MSVC/PCHCOM.py b/test/MSVC/PCHCOM.py index 593a1c14..24733915 100644 --- a/test/MSVC/PCHCOM.py +++ b/test/MSVC/PCHCOM.py @@ -30,7 +30,7 @@ Test the ability to configure the $MIDLCOM construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -48,9 +48,9 @@ sys.exit(0) 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") diff --git a/test/MSVC/PCHCOMSTR.py b/test/MSVC/PCHCOMSTR.py index c5ab9f52..23322d4a 100644 --- a/test/MSVC/PCHCOMSTR.py +++ b/test/MSVC/PCHCOMSTR.py @@ -31,7 +31,7 @@ the displayed string when pch is called. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,10 +49,10 @@ sys.exit(0) 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") diff --git a/test/MSVC/RCCOM.py b/test/MSVC/RCCOM.py index 3262f0cf..e881bb58 100644 --- a/test/MSVC/RCCOM.py +++ b/test/MSVC/RCCOM.py @@ -31,7 +31,7 @@ when using MSVC. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,7 +49,7 @@ sys.exit(0) 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()) diff --git a/test/MSVC/RCCOMSTR.py b/test/MSVC/RCCOMSTR.py index 33e192b9..96ccee09 100644 --- a/test/MSVC/RCCOMSTR.py +++ b/test/MSVC/RCCOMSTR.py @@ -31,7 +31,7 @@ the displayed string when rc is called. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,7 +49,7 @@ sys.exit(0) 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()) diff --git a/test/MSVC/generate-rc.py b/test/MSVC/generate-rc.py new file mode 100644 index 00000000..0b3c3320 --- /dev/null +++ b/test/MSVC/generate-rc.py @@ -0,0 +1,70 @@ +#!/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() diff --git a/test/MSVC/msvc.py b/test/MSVC/msvc.py index dd0f5ca0..857b6bda 100644 --- a/test/MSVC/msvc.py +++ b/test/MSVC/msvc.py @@ -24,13 +24,15 @@ __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': @@ -234,30 +236,36 @@ test.must_not_exist(test.workpath('build/StdAfx.obj')) ##### # 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() diff --git a/test/MSVS/common-prefix.py b/test/MSVS/common-prefix.py index 6f508c95..d40060c7 100644 --- a/test/MSVS/common-prefix.py +++ b/test/MSVS/common-prefix.py @@ -43,7 +43,7 @@ if sys.platform != 'win32': msg = "Skipping Visual Studio test on non-Windows platform '%s'\n" % sys.platform test.skip_test(msg) -expected_vcprojfile = """\ +vcproj_template = """\ \t \t -\t -\t\t\t -\t\t\t -\t\t\t -\t\t\t -\t\t\t -\t\t\t -\t\t -\t\t -\t +%(sln_files)s \t \t @@ -107,9 +93,9 @@ expected_vcprojfile = """\ 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}', @@ -123,16 +109,74 @@ env.MSVSProject(target = 'Test.vcproj', 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 +\t\t\t +\t\t\t +\t\t\t +\t\t\t +\t\t\t +\t\t\t +\t\t\t +\t\t\t +\t\t\t +\t\t\t +\t\t +\t\t +\t""" + +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 +\t\t\t +\t\t\t +\t\t +\t\t +\t""" + +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() diff --git a/test/MSVS/runfile.py b/test/MSVS/runfile.py index 581de649..5638916c 100644 --- a/test/MSVS/runfile.py +++ b/test/MSVS/runfile.py @@ -100,7 +100,7 @@ expected_vcprojfile = """\ SConscript_contents = """\ -env=Environment(MSVS_VERSION = '8.0') +env=Environment(tools=['msvs'], MSVS_VERSION = '8.0') env.MSVSProject(target = 'Test.vcproj', slnguid = '{SLNGUID}', diff --git a/test/MSVS/vs-6.0-files.py b/test/MSVS/vs-6.0-files.py index 135bb7fa..ce7ef463 100644 --- a/test/MSVS/vs-6.0-files.py +++ b/test/MSVS/vs-6.0-files.py @@ -184,7 +184,7 @@ Package=<3> SConscript_contents = """\ -env=Environment(MSVS_VERSION = '6.0') +env=Environment(tools=['msvs'], MSVS_VERSION = '6.0') testsrc = ['test.c'] testincs = ['sdk.h'] @@ -278,7 +278,7 @@ The real workspace file is here: 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'] diff --git a/test/MSVS/vs-7.0-files.py b/test/MSVS/vs-7.0-files.py index 8c82d1ae..8f981666 100644 --- a/test/MSVS/vs-7.0-files.py +++ b/test/MSVS/vs-7.0-files.py @@ -144,7 +144,7 @@ expected_vcprojfile = """\ SConscript_contents = """\ -env=Environment(MSVS_VERSION = '7.0') +env=Environment(tools=['msvs'], MSVS_VERSION = '7.0') testsrc = ['test1.cpp', 'test2.cpp'] testincs = ['sdk.h'] @@ -206,7 +206,7 @@ os.environ['PYTHON_ROOT'] = 'xyzzy' 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') @@ -260,7 +260,7 @@ The real workspace file is here: 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'] diff --git a/test/MSVS/vs-7.1-files.py b/test/MSVS/vs-7.1-files.py index bbe6f1e9..3ad2e977 100644 --- a/test/MSVS/vs-7.1-files.py +++ b/test/MSVS/vs-7.1-files.py @@ -146,7 +146,7 @@ expected_vcprojfile = """\ SConscript_contents = """\ -env=Environment(MSVS_VERSION = '7.1') +env=Environment(tools=['msvs'], MSVS_VERSION = '7.1') testsrc = ['test1.cpp', 'test2.cpp'] testincs = ['sdk.h'] @@ -208,7 +208,7 @@ os.environ['PYTHON_ROOT'] = 'xyzzy' 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') @@ -262,7 +262,7 @@ The real workspace file is here: 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'] diff --git a/test/MSVS/vs-8.0-files.py b/test/MSVS/vs-8.0-files.py index 878aa3ff..1d3c469f 100644 --- a/test/MSVS/vs-8.0-files.py +++ b/test/MSVS/vs-8.0-files.py @@ -153,7 +153,7 @@ expected_vcprojfile = """\ SConscript_contents = """\ -env=Environment(MSVS_VERSION = '8.0') +env=Environment(tools=['msvs'], MSVS_VERSION = '8.0') testsrc = ['test1.cpp', 'test2.cpp'] testincs = ['sdk.h'] @@ -215,7 +215,7 @@ os.environ['PYTHON_ROOT'] = 'xyzzy' 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') @@ -273,7 +273,7 @@ The real workspace file is here: 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'] diff --git a/test/MinGW/RCCOM.py b/test/MinGW/RCCOM.py index 4ddcd91d..2db05632 100644 --- a/test/MinGW/RCCOM.py +++ b/test/MinGW/RCCOM.py @@ -31,7 +31,7 @@ when using MinGW. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,7 +49,7 @@ sys.exit(0) 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()) diff --git a/test/MinGW/RCCOMSTR.py b/test/MinGW/RCCOMSTR.py index e0958473..96565f14 100644 --- a/test/MinGW/RCCOMSTR.py +++ b/test/MinGW/RCCOMSTR.py @@ -31,7 +31,7 @@ the displayed string when rc is called. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,7 +49,7 @@ sys.exit(0) 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()) diff --git a/test/NodeOps.py b/test/NodeOps.py index 9f548c41..ff3e0ca1 100644 --- a/test/NodeOps.py +++ b/test/NodeOps.py @@ -47,13 +47,6 @@ _lib = TestSCons._lib _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'] = '.' @@ -62,6 +55,10 @@ if string.find(sys.platform, 'irix') > -1: test = TestSCons.TestSCons() +e = test.Environment() +fooflags = e['SHCXXFLAGS'] + ' -DFOO' +barflags = e['SHCXXFLAGS'] + ' -DBAR' + test.subdir('bld', 'src', ['src', 'subsrcdir']) sconstruct = r""" diff --git a/test/Object.py b/test/Object.py index 8b9c5e06..da945e35 100644 --- a/test/Object.py +++ b/test/Object.py @@ -46,6 +46,7 @@ env.Program(target = 'prog3', source = ['f1%s', f2, 'f3%s', 'prog.cpp']) """ % (_obj, _obj, _obj, _obj, _obj, _obj)) test.write('f1.c', r""" +#include void f1(void) { @@ -64,6 +65,7 @@ f2(void) """) test.write('f3.c', r""" +#include void f3(void) { @@ -72,6 +74,7 @@ f3(void) """) test.write('f4.c', r""" +#include void f4(void) { @@ -80,6 +83,7 @@ f4(void) """) test.write('f5.c', r""" +#include void f5(void) { diff --git a/test/Options/BoolOption.py b/test/Options/BoolOption.py index ef6491db..7af9bfd4 100644 --- a/test/Options/BoolOption.py +++ b/test/Options/BoolOption.py @@ -35,13 +35,15 @@ import TestSCons 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) @@ -59,18 +61,21 @@ print env['profile'] 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) diff --git a/test/Options/EnumOption.py b/test/Options/EnumOption.py index c47f7d5c..5e29477a 100644 --- a/test/Options/EnumOption.py +++ b/test/Options/EnumOption.py @@ -35,13 +35,15 @@ import TestSCons 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') @@ -71,28 +73,33 @@ Default(env.Alias('dummy', None)) 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() diff --git a/test/Options/ListOption.py b/test/Options/ListOption.py index 5dbe0c37..fddfc5f3 100644 --- a/test/Options/ListOption.py +++ b/test/Options/ListOption.py @@ -35,13 +35,16 @@ import TestSCons 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') @@ -70,56 +73,69 @@ Default(env.Alias('dummy', None)) 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 diff --git a/test/Options/PackageOption.py b/test/Options/PackageOption.py index cc520f78..81f70032 100644 --- a/test/Options/PackageOption.py +++ b/test/Options/PackageOption.py @@ -35,13 +35,15 @@ import TestSCons 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) @@ -64,11 +66,12 @@ test.run(arguments='x11=no'); check(['0']) 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) diff --git a/test/Options/PathOption.py b/test/Options/PathOption.py index d15f39bc..d22071eb 100644 --- a/test/Options/PathOption.py +++ b/test/Options/PathOption.py @@ -36,6 +36,8 @@ import TestSCons 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) @@ -46,7 +48,7 @@ test.subdir('lib', 'qt', ['qt', 'lib'], 'nolib' ) workpath = test.workpath() libpath = os.path.join(workpath, 'lib') -test.write('SConstruct', """ +test.write(SConstruct_path, """\ from SCons.Options import PathOption qtdir = r'%s' @@ -88,17 +90,20 @@ test.run(arguments=['qtdir=%s' % qtpath, 'qt_libraries=%s' % libpath]) 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) @@ -149,7 +154,7 @@ test.must_not_exist(non_existing_subdir) -test.write('SConstruct', """\ +test.write(SConstruct_path, """\ opts = Options(args=ARGUMENTS) opts.AddOptions( PathOption('X', 'X variable', r'%s', validator=PathOption.PathIsFile), @@ -162,33 +167,34 @@ print env['X'] 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) @@ -205,33 +211,38 @@ print env['X'] 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) @@ -251,12 +262,12 @@ Default(env.Alias('dummy', None)) 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]) diff --git a/test/ParseConfig.py b/test/ParseConfig.py index 55678fea..668d08aa 100644 --- a/test/ParseConfig.py +++ b/test/ParseConfig.py @@ -30,7 +30,7 @@ import sys import TestCmd import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -57,8 +57,8 @@ print "-L foo -L lib_dir -isysroot /tmp -arch ppc -arch i386" 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']) @@ -67,7 +67,7 @@ print env['CCFLAGS'] 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'] @@ -78,7 +78,7 @@ print env['CCFLAGS'] 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'] diff --git a/test/ParseDepends.py b/test/ParseDepends.py index 9a9910ab..e979b91d 100644 --- a/test/ParseDepends.py +++ b/test/ParseDepends.py @@ -29,7 +29,7 @@ import string import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -44,8 +44,8 @@ file.close() """) 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') @@ -55,7 +55,7 @@ env.Bar(target = 'subdir/f3.out', source = 'f3.in') 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'), diff --git a/test/Perforce/P4COM.py b/test/Perforce/P4COM.py index c33254a4..11b28e37 100644 --- a/test/Perforce/P4COM.py +++ b/test/Perforce/P4COM.py @@ -32,7 +32,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -65,7 +65,7 @@ def cat(env, source, target): 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') @@ -92,19 +92,19 @@ test.write(['Perforce', 'sub', 'fff.in'], "Perforce/sub/fff.in\n") 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())) diff --git a/test/Perforce/P4COMSTR.py b/test/Perforce/P4COMSTR.py index d9a3bc0f..72f05b8a 100644 --- a/test/Perforce/P4COMSTR.py +++ b/test/Perforce/P4COMSTR.py @@ -32,7 +32,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -65,7 +65,7 @@ def cat(env, source, target): 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') diff --git a/test/Perforce/Perforce.py b/test/Perforce/Perforce.py index f813f106..0133ced1 100644 --- a/test/Perforce/Perforce.py +++ b/test/Perforce/Perforce.py @@ -32,7 +32,6 @@ on port 1666, as well as that of course a client must be present. """ import os -import socket import string import TestSCons @@ -41,11 +40,13 @@ class TestPerforce(TestSCons.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: @@ -98,7 +99,7 @@ class TestPerforce(TestSCons.TestSCons): 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): @@ -145,8 +146,6 @@ Client: %(client)s Owner: %(user)s -Host: %(host)s - Description: Created by %(user)s. @@ -234,7 +233,9 @@ def cat(env, source, target): 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') diff --git a/test/Precious.py b/test/Precious.py index 940fab77..76aa2a46 100644 --- a/test/Precious.py +++ b/test/Precious.py @@ -28,7 +28,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -39,17 +39,18 @@ import sys 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") diff --git a/test/Program-j.py b/test/Program-j.py index fe778b33..d8180bb6 100644 --- a/test/Program-j.py +++ b/test/Program-j.py @@ -45,6 +45,8 @@ env.Program(target = 'f4', source = 'f4.c') """) test.write('f1.c', r""" +#include +#include int main(int argc, char *argv[]) { @@ -55,6 +57,9 @@ main(int argc, char *argv[]) """) test.write('f2.c', r""" +#include +#include + int main(int argc, char *argv[]) { @@ -66,6 +71,8 @@ main(int argc, char *argv[]) test.write('f3.c', r""" +#include +#include int main(int argc, char *argv[]) { @@ -76,6 +83,8 @@ main(int argc, char *argv[]) """) test.write('f4.c', r""" +#include +#include int main(int argc, char *argv[]) { diff --git a/test/Program.py b/test/Program.py index 5b785a39..cf981489 100644 --- a/test/Program.py +++ b/test/Program.py @@ -52,6 +52,8 @@ env.Program('foo5.c') """) test.write('f1.c', r""" +#include +#include int main(int argc, char *argv[]) { @@ -62,6 +64,8 @@ main(int argc, char *argv[]) """) test.write('f2a.c', r""" +#include +#include void f2a(void) { @@ -70,6 +74,7 @@ f2a(void) """) test.write('f2b.c', r""" +#include void f2b(void) { @@ -78,6 +83,8 @@ f2b(void) """) test.write('f2c.c', r""" +#include +#include extern void f2a(void); extern void f2b(void); int @@ -92,6 +99,7 @@ main(int argc, char *argv[]) """) test.write('f3a.c', r""" +#include void f3a(void) { @@ -100,6 +108,7 @@ f3a(void) """) test.write('f3b.c', r""" +#include void f3b(void) { @@ -108,6 +117,8 @@ f3b(void) """) test.write('f3c.c', r""" +#include +#include extern void f3a(void); extern void f3b(void); int @@ -122,6 +133,8 @@ main(int argc, char *argv[]) """) test.write('f4.c', r""" +#include +#include int main(int argc, char *argv[]) { @@ -132,6 +145,8 @@ main(int argc, char *argv[]) """) test.write('foo5.c', r""" +#include +#include int main(int argc, char *argv[]) { @@ -152,6 +167,8 @@ test.run(program = foo5, stdout = "foo5.c\n") test.up_to_date(arguments = '.') test.write('f1.c', r""" +#include +#include int main(int argc, char *argv[]) { @@ -162,6 +179,7 @@ main(int argc, char *argv[]) """) test.write('f3b.c', r""" +#include void f3b(void) { @@ -170,6 +188,8 @@ f3b(void) """) test.write('f4.c', r""" +#include +#include int main(int argc, char *argv[]) { @@ -180,6 +200,8 @@ main(int argc, char *argv[]) """) test.write('foo5.c', r""" +#include +#include int main(int argc, char *argv[]) { @@ -217,6 +239,8 @@ test.fail_test(oldtime4 != os.path.getmtime(foo4)) test.fail_test(oldtime5 != os.path.getmtime(foo5)) test.write('f1.c', r""" +#include +#include int main(int argc, char *argv[]) { @@ -227,6 +251,8 @@ main(int argc, char *argv[]) """) test.write('f3b.c', r""" +#include +#include void f3b(void) { @@ -235,6 +261,8 @@ f3b(void) """) test.write('f4.c', r""" +#include +#include int main(int argc, char *argv[]) { @@ -245,6 +273,8 @@ main(int argc, char *argv[]) """) test.write('foo5.c', r""" +#include +#include int main(int argc, char *argv[]) { @@ -265,6 +295,8 @@ test.run(program = foo5, stdout = "foo5.c Y\n") test.up_to_date(arguments = foo_args) test.write('f1.c', r""" +#include +#include int main(int argc, char *argv[]) { @@ -275,6 +307,8 @@ main(int argc, char *argv[]) """) test.write('f3b.c', r""" +#include +#include void f3b(void) { @@ -283,6 +317,8 @@ f3b(void) """) test.write('f4.c', r""" +#include +#include int main(int argc, char *argv[]) { @@ -293,6 +329,8 @@ main(int argc, char *argv[]) """) test.write('foo5.c', r""" +#include +#include int main(int argc, char *argv[]) { diff --git a/test/QT/QTFLAGS.py b/test/QT/QTFLAGS.py index f9cb917a..ba08739e 100644 --- a/test/QT/QTFLAGS.py +++ b/test/QT/QTFLAGS.py @@ -31,7 +31,7 @@ Testing the configuration mechanisms of the 'qt' tool. import TestSCons import os.path -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -123,8 +123,8 @@ test.run(chdir=test.workpath('qt','lib'), arguments = '.', 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, """ diff --git a/test/QT/moc-from-header.py b/test/QT/moc-from-header.py index 0bf68737..1dbcd0f3 100644 --- a/test/QT/moc-from-header.py +++ b/test/QT/moc-from-header.py @@ -28,6 +28,8 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" Create a moc file from a header file. """ +import os + import TestSCons test = TestSCons.TestSCons() @@ -38,6 +40,10 @@ env = Environment() 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 diff --git a/test/QT/warnings.py b/test/QT/warnings.py index 7b413606..0fd3f663 100644 --- a/test/QT/warnings.py +++ b/test/QT/warnings.py @@ -29,15 +29,18 @@ Test the Qt tool warnings. """ 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" @@ -77,15 +80,19 @@ test.run(stderr=None, arguments='-n noqtdir=1') 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)) diff --git a/test/RANLIB/RANLIB.py b/test/RANLIB/RANLIB.py index 5002b20e..75e860ab 100644 --- a/test/RANLIB/RANLIB.py +++ b/test/RANLIB/RANLIB.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe @@ -53,7 +53,7 @@ test.write('SConstruct', """ 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') @@ -61,9 +61,10 @@ main = foo.Object('main', 'main.c') foo.Program(target = 'f', source = main) bar.Program(target = 'b', source = main) -""" % python) +""" % locals()) test.write('foo.c', r""" +#include void library_function(void) { @@ -72,6 +73,8 @@ library_function(void) """) test.write('bar.c', r""" +#include + void library_function(void) { @@ -80,6 +83,7 @@ library_function(void) """) test.write('main.c', r""" +#include int main(int argc, char *argv[]) { diff --git a/test/RANLIB/RANLIBCOM.py b/test/RANLIB/RANLIBCOM.py index d60a14ef..312216b2 100644 --- a/test/RANLIB/RANLIBCOM.py +++ b/test/RANLIB/RANLIBCOM.py @@ -30,7 +30,7 @@ Test the ability to configure the $RANLIBCOM construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -62,12 +62,12 @@ sys.exit(0) 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") diff --git a/test/RANLIB/RANLIBCOMSTR.py b/test/RANLIB/RANLIBCOMSTR.py index 4e036758..6929ac65 100644 --- a/test/RANLIB/RANLIBCOMSTR.py +++ b/test/RANLIB/RANLIBCOMSTR.py @@ -31,7 +31,7 @@ customize the displayed archive indexer string. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -63,21 +63,23 @@ sys.exit(0) 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") diff --git a/test/RANLIB/RANLIBFLAGS.py b/test/RANLIB/RANLIBFLAGS.py index 80618ba0..08ee9671 100644 --- a/test/RANLIB/RANLIBFLAGS.py +++ b/test/RANLIB/RANLIBFLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -50,7 +50,7 @@ os.system(string.join(sys.argv[1:], " ")) 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') @@ -58,9 +58,12 @@ main = foo.Object('main', 'main.c') foo.Program(target = 'f', source = main) bar.Program(target = 'b', source = main) -""" % python) +""" % locals()) test.write('foo.c', r""" +#include +#include + void library_function(void) { @@ -69,6 +72,8 @@ library_function(void) """) test.write('bar.c', r""" +#include +#include void library_function(void) { @@ -77,6 +82,8 @@ library_function(void) """) test.write('main.c', r""" +#include + int main(int argc, char *argv[]) { diff --git a/test/RCS/RCS_COCOM.py b/test/RCS/RCS_COCOM.py index a151d698..319a8519 100644 --- a/test/RCS/RCS_COCOM.py +++ b/test/RCS/RCS_COCOM.py @@ -32,7 +32,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -65,7 +65,7 @@ def cat(env, source, target): 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') @@ -92,19 +92,19 @@ test.write(['RCS', 'sub', 'fff.in'], "RCS/sub/fff.in\n") 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())) diff --git a/test/RCS/RCS_COCOMSTR.py b/test/RCS/RCS_COCOMSTR.py index 9e17418e..30a3a57b 100644 --- a/test/RCS/RCS_COCOMSTR.py +++ b/test/RCS/RCS_COCOMSTR.py @@ -32,7 +32,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -65,7 +65,7 @@ def cat(env, source, target): 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') diff --git a/test/RCS/diskcheck.py b/test/RCS/diskcheck.py index 8af2545d..78120f69 100644 --- a/test/RCS/diskcheck.py +++ b/test/RCS/diskcheck.py @@ -115,12 +115,13 @@ test.write('bbb.in', "checked-out bbb.in\n") 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) diff --git a/test/RCS/implicit.py b/test/RCS/implicit.py index 362f15aa..3223901b 100644 --- a/test/RCS/implicit.py +++ b/test/RCS/implicit.py @@ -49,6 +49,8 @@ if not co: test.subdir('RCS') test.write('foo.c', """\ +#include + #include "foo.h" int main(int argc, char *argv[]) { diff --git a/test/RPATH.py b/test/RPATH.py index 6ab6eb29..a0ae8c78 100644 --- a/test/RPATH.py +++ b/test/RPATH.py @@ -45,6 +45,7 @@ Program('foo', 'foo.c', LIBS='bar', LIBPATH='bar', RPATH='bar') """) test.write('foo.c', """\ +#include int main() { void bar(); bar(); diff --git a/test/Repository/CPPPATH.py b/test/Repository/CPPPATH.py index 6ec21f36..9db613e3 100644 --- a/test/Repository/CPPPATH.py +++ b/test/Repository/CPPPATH.py @@ -53,6 +53,8 @@ test.write(['repository', 'include2', 'foo.h'], r""" """) test.write(['repository', 'foo.c'], r""" +#include +#include #include int main(int argc, char *argv[]) diff --git a/test/Repository/LIBPATH.py b/test/Repository/LIBPATH.py index c4470d21..9216a8b3 100644 --- a/test/Repository/LIBPATH.py +++ b/test/Repository/LIBPATH.py @@ -62,6 +62,8 @@ env_yyy.Command('yyy.out', bbb_exe, write_LIBDIRFLAGS) """) test.write(['work', 'aaa.c'], r""" +#include +#include int main(int argc, char *argv[]) { @@ -72,6 +74,8 @@ main(int argc, char *argv[]) """) test.write(['work', 'bbb.c'], r""" +#include +#include int main(int argc, char *argv[]) { diff --git a/test/Repository/M4.py b/test/Repository/M4.py index 75fa0de1..15d8abb2 100644 --- a/test/Repository/M4.py +++ b/test/Repository/M4.py @@ -34,7 +34,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -48,16 +48,17 @@ sys.stdout.write(string.replace(contents, 'M4', 'mym4.py')) 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 diff --git a/test/Repository/Program.py b/test/Repository/Program.py index 93bcb85d..eda12021 100644 --- a/test/Repository/Program.py +++ b/test/Repository/Program.py @@ -51,6 +51,7 @@ env.Program(target= 'foo', source = Split('aaa.c bbb.c foo.c')) """ % repository) test.write(['repository', 'aaa.c'], r""" +#include void aaa(void) { @@ -59,6 +60,7 @@ aaa(void) """) test.write(['repository', 'bbb.c'], r""" +#include void bbb(void) { @@ -67,6 +69,9 @@ bbb(void) """) test.write(['repository', 'foo.c'], r""" +#include +#include + extern void aaa(void); extern void bbb(void); int @@ -95,6 +100,7 @@ test.up_to_date(chdir = 'work1', arguments = '.') # test.write(['work1', 'bbb.c'], r""" +#include void bbb(void) { @@ -113,6 +119,7 @@ test.up_to_date(chdir = 'work1', arguments = '.') # test.write(['work1', 'aaa.c'], r""" +#include void aaa(void) { @@ -121,6 +128,8 @@ aaa(void) """) test.write(['work1', 'foo.c'], r""" +#include +#include extern void aaa(void); extern void bbb(void); int @@ -185,6 +194,7 @@ env.Program(target= 'foo', source = Split('aaa.c bbb.c foo.c')) """ % (repository_new, repository_old)) test.write(['repository.old', 'aaa.c'], r""" +#include void aaa(void) { @@ -193,6 +203,7 @@ aaa(void) """) test.write(['repository.old', 'bbb.c'], r""" +#include void bbb(void) { @@ -201,6 +212,8 @@ bbb(void) """) test.write(['repository.old', 'foo.c'], r""" +#include +#include extern void aaa(void); extern void bbb(void); int @@ -232,6 +245,8 @@ test.up_to_date(chdir = 'work2', arguments = '.') test.writable('repository.new', 1) test.write(['repository.new', 'aaa.c'], r""" +#include +#include void aaa(void) { @@ -240,6 +255,8 @@ aaa(void) """) test.write(['work2', 'bbb.c'], r""" +#include +#include void bbb(void) { @@ -261,6 +278,8 @@ test.up_to_date(chdir = 'work2', arguments = '.') # test.write(['work2', 'aaa.c'], r""" +#include +#include void aaa(void) { @@ -269,6 +288,8 @@ aaa(void) """) test.write(['work2', 'foo.c'], r""" +#include +#include extern void aaa(void); extern void bbb(void); int diff --git a/test/Repository/StaticLibrary.py b/test/Repository/StaticLibrary.py index 087fa7e9..1cf20c35 100644 --- a/test/Repository/StaticLibrary.py +++ b/test/Repository/StaticLibrary.py @@ -66,6 +66,8 @@ env.Program(target = 'foo', source = 'foo.c') """) test.write(['repository', 'aaa.c'], r""" +#include +#include void aaa(void) { @@ -74,6 +76,8 @@ aaa(void) """) test.write(['repository', 'bbb.c'], r""" +#include +#include void bbb(void) { @@ -82,6 +86,8 @@ bbb(void) """) test.write(['repository', 'foo.c'], r""" +#include +#include extern void aaa(void); extern void bbb(void); int @@ -118,6 +124,8 @@ test.fail_test(os.path.exists(repository_foo)) test.up_to_date(chdir = 'work1', options = opts, arguments = ".") test.write(['work1', 'bbb.c'], r""" +#include +#include void bbb(void) { @@ -168,6 +176,8 @@ test.writable('repository', 0) test.up_to_date(chdir = 'work2', options = opts, arguments = ".") test.write(['work2', 'bbb.c'], r""" +#include +#include void bbb(void) { @@ -194,6 +204,8 @@ test.up_to_date(chdir = 'work2', options = opts, arguments = ".") test.up_to_date(chdir = 'work3', options = opts, arguments = ".") test.write(['work3', 'foo.c'], r""" +#include +#include extern void aaa(void); extern void bbb(void); int diff --git a/test/Repository/absolute-path.py b/test/Repository/absolute-path.py index ed360c71..378e3211 100644 --- a/test/Repository/absolute-path.py +++ b/test/Repository/absolute-path.py @@ -57,6 +57,8 @@ env.Program('foo', ['aaa.c', r'%s', 'foo.c']) """ % subdir_aaa_c) test.write(['repository', 'src', 'aaa.c'], r""" +#include +#include void src_aaa(void) { @@ -65,6 +67,8 @@ src_aaa(void) """) test.write(['subdir', 'aaa.c'], r""" +#include +#include void subdir_aaa(void) { @@ -73,6 +77,8 @@ subdir_aaa(void) """) test.write(['repository', 'src', 'foo.c'], r""" +#include +#include extern void src_aaa(void); extern void subdir_aaa(void); int diff --git a/test/Repository/include.py b/test/Repository/include.py index 577442a2..4575d994 100644 --- a/test/Repository/include.py +++ b/test/Repository/include.py @@ -56,6 +56,8 @@ test.write(['repository', 'bar.h'], r""" """) test.write(['repository', 'foo.c'], r""" +#include +#include #include int main(int argc, char *argv[]) @@ -100,6 +102,8 @@ test.up_to_date(chdir = 'work', arguments = '.') # test.write(['work', 'foo.c'], r""" +#include +#include #include int main(int argc, char *argv[]) diff --git a/test/Repository/link-object.py b/test/Repository/link-object.py index 63c274e0..679fa7e5 100644 --- a/test/Repository/link-object.py +++ b/test/Repository/link-object.py @@ -52,6 +52,8 @@ env.Program(target = 'foo', source = ['aaa.c', 'bbb.c', 'foo.c']) """ % workpath_repository) test.write(['repository', 'aaa.c'], r""" +#include +#include void aaa(void) { @@ -60,6 +62,8 @@ aaa(void) """) test.write(['repository', 'bbb.c'], r""" +#include +#include void bbb(void) { @@ -68,6 +72,8 @@ bbb(void) """) test.write(['repository', 'foo.c'], r""" +#include +#include extern void aaa(void); extern void bbb(void); int @@ -107,6 +113,8 @@ test.up_to_date(chdir = 'work', arguments = ".") # test.write(['work', 'bbb.c'], r""" +#include +#include void bbb(void) { diff --git a/test/Repository/multi-dir.py b/test/Repository/multi-dir.py index 4532cc39..ab67c9dc 100644 --- a/test/Repository/multi-dir.py +++ b/test/Repository/multi-dir.py @@ -73,6 +73,8 @@ test.write(['repository', 'src', 'include.h'], r""" """) test.write(['repository', 'src', 'main.c'], r""" +#include +#include #include int main(int argc, char *argv[]) diff --git a/test/Repository/no-SConsignFile.py b/test/Repository/no-SConsignFile.py index d838605c..95b1749f 100644 --- a/test/Repository/no-SConsignFile.py +++ b/test/Repository/no-SConsignFile.py @@ -45,6 +45,7 @@ env.Program('foo', 'src/foo.c') test.write(['src', 'foo.c'], """\ #include +#include #include "foo.h" int main(int argc, char *argv[]) diff --git a/test/Repository/no-repository.py b/test/Repository/no-repository.py index 6dc9add4..f9b245e9 100644 --- a/test/Repository/no-repository.py +++ b/test/Repository/no-repository.py @@ -50,6 +50,8 @@ env.Program(target = 'foo', source = Split('aaa.c bbb.c foo.c')) """ % no_repository) test.write(['work', 'aaa.c'], r""" +#include +#include void aaa(void) { @@ -58,6 +60,8 @@ aaa(void) """) test.write(['work', 'bbb.c'], r""" +#include +#include void bbb(void) { @@ -66,6 +70,8 @@ bbb(void) """) test.write(['work', 'foo.c'], r""" +#include +#include extern void aaa(void); extern void bbb(void); int diff --git a/test/Repository/signature-order.py b/test/Repository/signature-order.py index 8069b606..99bc56a7 100644 --- a/test/Repository/signature-order.py +++ b/test/Repository/signature-order.py @@ -62,6 +62,8 @@ test.write(['repository', 'foo.h'], foo_h_contents) test.write(['repository', 'bar.h'], bar_h_contents) test.write(['repository', 'foo.c'], r""" +#include +#include #include #include int diff --git a/test/Repository/top-level-path.py b/test/Repository/top-level-path.py index 2d4164a6..4dccfd55 100644 --- a/test/Repository/top-level-path.py +++ b/test/Repository/top-level-path.py @@ -56,6 +56,8 @@ env.Program('foo', ['aaa.c', '#subdir/aaa.c', 'foo.c']) """) test.write(['repository', 'src', 'aaa.c'], r""" +#include +#include void src_aaa(void) { @@ -64,6 +66,8 @@ src_aaa(void) """) test.write(['repository', 'subdir', 'aaa.c'], r""" +#include +#include void subdir_aaa(void) { @@ -72,6 +76,8 @@ subdir_aaa(void) """) test.write(['repository', 'src', 'foo.c'], r""" +#include +#include extern void src_aaa(void); extern void subdir_aaa(void); int diff --git a/test/Repository/variants.py b/test/Repository/variants.py index f8556367..cd4c24a8 100644 --- a/test/Repository/variants.py +++ b/test/Repository/variants.py @@ -133,6 +133,8 @@ test.write(['repository', 'src1', 'iii.h'], r""" """) test.write(['repository', 'src1', 'aaa.c'], r""" +#include +#include #include void aaa(void) @@ -142,6 +144,8 @@ aaa(void) """) test.write(['repository', 'src1', 'bbb.c'], r""" +#include +#include #include void bbb(void) @@ -151,6 +155,8 @@ bbb(void) """) test.write(['repository', 'src1', 'main.c'], r""" +#include +#include #include extern void aaa(void); extern void bbb(void); @@ -189,6 +195,8 @@ test.write(['repository', 'src2', 'xxx', 'include.h'], r""" """) test.write(['repository', 'src2', 'xxx', 'main.c'], r""" +#include +#include #include #ifdef FOO #define MAIN_OS "FOO" diff --git a/test/Repository/within-repository.py b/test/Repository/within-repository.py index 1cffe81c..0b7e844b 100644 --- a/test/Repository/within-repository.py +++ b/test/Repository/within-repository.py @@ -53,6 +53,8 @@ env.Program(target = 'foo', source = ['aaa.c', 'bbb.c', 'foo.c']) """ % workpath_repository) test.write(['repository', 'aaa.c'], r""" +#include +#include void aaa(void) { @@ -61,6 +63,8 @@ aaa(void) """) test.write(['repository', 'bbb.c'], r""" +#include +#include void bbb(void) { @@ -69,6 +73,8 @@ bbb(void) """) test.write(['repository', 'foo.c'], r""" +#include +#include extern void aaa(void); extern void bbb(void); int @@ -88,6 +94,8 @@ env.Program(target = 'bar', source = ['aaa.c', 'bbb.c', 'bar.c']) """) test.write(['repository', 'src', 'aaa.c'], r""" +#include +#include void aaa(void) { @@ -96,6 +104,8 @@ aaa(void) """) test.write(['repository', 'src', 'bbb.c'], r""" +#include +#include void bbb(void) { @@ -104,6 +114,8 @@ bbb(void) """) test.write(['repository', 'src', 'bar.c'], r""" +#include +#include extern void aaa(void); extern void bbb(void); int diff --git a/test/Rpcgen/RPCGEN.py b/test/Rpcgen/RPCGEN.py index 162615bd..ea224384 100644 --- a/test/Rpcgen/RPCGEN.py +++ b/test/Rpcgen/RPCGEN.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -52,12 +52,13 @@ sys.exit(0) """) 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 diff --git a/test/Rpcgen/RPCGENCLIENTFLAGS.py b/test/Rpcgen/RPCGENCLIENTFLAGS.py index d8ce2260..66ea6dfe 100644 --- a/test/Rpcgen/RPCGENCLIENTFLAGS.py +++ b/test/Rpcgen/RPCGENCLIENTFLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -52,14 +52,14 @@ sys.exit(0) """) 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 diff --git a/test/Rpcgen/RPCGENFLAGS.py b/test/Rpcgen/RPCGENFLAGS.py index 951254f6..8f6cfffc 100644 --- a/test/Rpcgen/RPCGENFLAGS.py +++ b/test/Rpcgen/RPCGENFLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -52,14 +52,14 @@ sys.exit(0) """) 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 diff --git a/test/Rpcgen/RPCGENHEADERFLAGS.py b/test/Rpcgen/RPCGENHEADERFLAGS.py index e8d3cb0f..411838d5 100644 --- a/test/Rpcgen/RPCGENHEADERFLAGS.py +++ b/test/Rpcgen/RPCGENHEADERFLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -52,14 +52,14 @@ sys.exit(0) """) 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 diff --git a/test/Rpcgen/RPCGENSERVICEFLAGS.py b/test/Rpcgen/RPCGENSERVICEFLAGS.py index fbc5c7f4..af638ced 100644 --- a/test/Rpcgen/RPCGENSERVICEFLAGS.py +++ b/test/Rpcgen/RPCGENSERVICEFLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -52,14 +52,14 @@ sys.exit(0) """) 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 diff --git a/test/Rpcgen/RPCGENXDRFLAGS.py b/test/Rpcgen/RPCGENXDRFLAGS.py index dc428a06..6ce06091 100644 --- a/test/Rpcgen/RPCGENXDRFLAGS.py +++ b/test/Rpcgen/RPCGENXDRFLAGS.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -52,14 +52,14 @@ sys.exit(0) """) 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 diff --git a/test/SCCS/SCCSCOM.py b/test/SCCS/SCCSCOM.py index 1ba57823..f7a210c1 100644 --- a/test/SCCS/SCCSCOM.py +++ b/test/SCCS/SCCSCOM.py @@ -32,7 +32,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -65,7 +65,7 @@ def cat(env, source, target): 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') @@ -92,19 +92,19 @@ test.write(['SCCS', 'sub', 'fff.in'], "SCCS/sub/fff.in\n") 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())) diff --git a/test/SCCS/SCCSCOMSTR.py b/test/SCCS/SCCSCOMSTR.py index 858e17b1..be5d8078 100644 --- a/test/SCCS/SCCSCOMSTR.py +++ b/test/SCCS/SCCSCOMSTR.py @@ -32,7 +32,7 @@ import os.path import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -65,7 +65,7 @@ def cat(env, source, target): 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') diff --git a/test/SCCS/diskcheck.py b/test/SCCS/diskcheck.py index 532ad9c8..66566fad 100644 --- a/test/SCCS/diskcheck.py +++ b/test/SCCS/diskcheck.py @@ -28,6 +28,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" Test transparent checkouts from SCCS files in an SCCS subdirectory. """ +import os.path import string import TestSCons @@ -94,10 +95,10 @@ test.write(['sub', 'eee.in'], "checked-out sub/eee.in\n") 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) diff --git a/test/SConscript.py b/test/SConscript/SConscript.py similarity index 59% rename from test/SConscript.py rename to test/SConscript/SConscript.py index 08e41a6f..268c48e2 100644 --- a/test/SConscript.py +++ b/test/SConscript/SConscript.py @@ -216,207 +216,4 @@ test.run(arguments = ".", 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() diff --git a/test/SConscript/SConscriptChdir.py b/test/SConscript/SConscriptChdir.py new file mode 100644 index 00000000..3763378a --- /dev/null +++ b/test/SConscript/SConscriptChdir.py @@ -0,0 +1,85 @@ +#!/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() diff --git a/test/SConscript/env.py b/test/SConscript/env.py new file mode 100644 index 00000000..0ad05619 --- /dev/null +++ b/test/SConscript/env.py @@ -0,0 +1,90 @@ +#!/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() diff --git a/test/SConscript/src_dir.py b/test/SConscript/src_dir.py new file mode 100644 index 00000000..f18066b0 --- /dev/null +++ b/test/SConscript/src_dir.py @@ -0,0 +1,97 @@ +#!/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 + +int main(int argc, char *argv[]) +{ + printf("Goodbye, world!\\n"); + exit(0); +} +""") + +test.write(['src', 'hello.c'], """\ +#include + +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() diff --git a/test/SConscript/variables.py b/test/SConscript/variables.py new file mode 100644 index 00000000..34f52a0c --- /dev/null +++ b/test/SConscript/variables.py @@ -0,0 +1,169 @@ +#!/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() diff --git a/test/SConscript/white-space.py b/test/SConscript/white-space.py new file mode 100644 index 00000000..87eb701e --- /dev/null +++ b/test/SConscript/white-space.py @@ -0,0 +1,50 @@ +#!/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() diff --git a/test/SConsignFile.py b/test/SConsignFile.py index 46d0954c..e2b80535 100644 --- a/test/SConsignFile.py +++ b/test/SConsignFile.py @@ -27,7 +27,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import TestSCons import os.path -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -45,13 +45,13 @@ file.close() # 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") @@ -79,13 +79,13 @@ test.must_not_exist(test.workpath('work1', 'subdir', '.sconsign')) 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") diff --git a/test/SHELL.py b/test/SHELL.py index 7dda321c..915dbce7 100644 --- a/test/SHELL.py +++ b/test/SHELL.py @@ -35,6 +35,7 @@ import sys import TestSCons python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -68,7 +69,8 @@ os.chmod(my_shell, 0755) 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") diff --git a/test/SHLIBPREFIX.py b/test/SHLIBPREFIX.py index 352f2176..87b92fae 100644 --- a/test/SHLIBPREFIX.py +++ b/test/SHLIBPREFIX.py @@ -38,6 +38,7 @@ env.SharedLibrary(target = 'foo', source = 'foo.c') """) test.write('foo.c', r""" +#include void foo(void) { diff --git a/test/SHLIBSUFFIX.py b/test/SHLIBSUFFIX.py index 94c2984c..dc88e3b1 100644 --- a/test/SHLIBSUFFIX.py +++ b/test/SHLIBSUFFIX.py @@ -38,6 +38,7 @@ env.SharedLibrary(target = 'foo', source = 'foo.c') """) test.write('foo.c', r""" +#include void foo(void) { diff --git a/test/SPAWN.py b/test/SPAWN.py index e6eb65e3..f73ab112 100644 --- a/test/SPAWN.py +++ b/test/SPAWN.py @@ -30,7 +30,7 @@ Test the SPAWN construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -45,10 +45,14 @@ ofp.close() 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()) diff --git a/test/SWIG/SWIG.py b/test/SWIG/SWIG.py index 65ecf2ba..0fb1da4b 100644 --- a/test/SWIG/SWIG.py +++ b/test/SWIG/SWIG.py @@ -35,8 +35,10 @@ if sys.platform =='darwin': # 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 @@ -68,11 +70,11 @@ sys.exit(0) """) 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 @@ -143,14 +145,13 @@ os.system(string.join(sys.argv[1:], " ")) 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()) @@ -226,7 +227,6 @@ This is bar.c! 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', @@ -252,14 +252,13 @@ foo.LoadableModule(target = 'modulename', source = ['module.i']) 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()) diff --git a/test/SWIG/SWIGCOM.py b/test/SWIG/SWIGCOM.py index 22e217a6..20d2d5d2 100644 --- a/test/SWIG/SWIGCOM.py +++ b/test/SWIG/SWIGCOM.py @@ -30,7 +30,7 @@ Test the ability to configure the $SWIGCOM construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -48,10 +48,10 @@ sys.exit(0) 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") diff --git a/test/SWIG/SWIGCOMSTR.py b/test/SWIG/SWIGCOMSTR.py index 3ffcdbf5..b991d774 100644 --- a/test/SWIG/SWIGCOMSTR.py +++ b/test/SWIG/SWIGCOMSTR.py @@ -31,7 +31,7 @@ the displayed string when swig is called. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,11 +49,11 @@ sys.exit(0) 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") diff --git a/test/Scanner.py b/test/Scanner/Scanner.py similarity index 65% rename from test/Scanner.py rename to test/Scanner/Scanner.py index 6e64c030..09c5680b 100644 --- a/test/Scanner.py +++ b/test/Scanner/Scanner.py @@ -24,10 +24,9 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" -import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -93,19 +92,19 @@ k2scan = env.Scanner(name = 'k2', 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') @@ -120,7 +119,7 @@ def blork(env, target, source): 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) @@ -134,7 +133,7 @@ blork = env.KB('moo.lork') ork = env.BLORK(blork) Alias('make_ork', ork) -""" % {'python': python}) +""" % locals()) test.write('foo.k', """foo.k 1 line 1 @@ -173,14 +172,15 @@ test.write('xxx', "xxx 1\n") 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") @@ -191,12 +191,13 @@ test.up_to_date(arguments = '.') 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") @@ -205,14 +206,15 @@ test.must_match('moo.ork', "xxx 2\nmoo.lork 1 line 2\nyyy 1\nmoo.lork 1 line 4\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") @@ -221,11 +223,12 @@ test.must_match('moo.ork', "xxx 2\nmoo.lork 1 line 2\nyyy 2\nmoo.lork 1 line 4\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") @@ -234,82 +237,4 @@ test.must_match('moo.ork', "xxx 2\nmoo.lork 1 line 2\nyyy 2\nmoo.lork 1 line 4\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() diff --git a/test/Scanner/empty-implicit.py b/test/Scanner/empty-implicit.py new file mode 100644 index 00000000..2112fd83 --- /dev/null +++ b/test/Scanner/empty-implicit.py @@ -0,0 +1,81 @@ +#!/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() diff --git a/test/Scanner-exception.py b/test/Scanner/exception.py similarity index 100% rename from test/Scanner-exception.py rename to test/Scanner/exception.py diff --git a/test/scan-once.py b/test/Scanner/generated.py similarity index 72% rename from test/scan-once.py rename to test/Scanner/generated.py index 044e2603..36f35f63 100644 --- a/test/scan-once.py +++ b/test/Scanner/generated.py @@ -22,20 +22,17 @@ # 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 @@ -45,51 +42,12 @@ import TestSCons 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 @@ -129,9 +87,9 @@ env.Append(LIBPATH = [e["EXPORT_LIB"]]) 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 @@ -205,23 +163,23 @@ def AddLibDirs(env, str): """) -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") @@ -236,7 +194,7 @@ env = env.Copy() # Yes, clobber intentionally """) -test.write(['SLF', 'src', 'lib_geng', 'SConscript'], """\ +test.write(['src', 'lib_geng', 'SConscript'], """\ # --- Begin SConscript boilerplate --- import string import sys @@ -253,8 +211,9 @@ env = env.Copy() # Yes, clobber intentionally 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 @@ -297,10 +256,10 @@ lib_objs = map(lambda x: re.sub("\.c$", ".o", x), lib_srcs) 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(".") @@ -313,8 +272,8 @@ def escape(s): 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? @@ -330,7 +289,7 @@ recurse_env.Command([lib_fullname] + lib_objs, 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 @@ -344,7 +303,7 @@ for h in ['libg_gx.h', 'libg_gy.h', 'libg_gz.h']: open(h, 'w').write('') """) -test.write(['SLF', 'src', 'lib_geng', 'SConstruct'], """\ +test.write(['src', 'lib_geng', 'SConstruct'], """\ import os Scanned = {} @@ -384,13 +343,13 @@ Default(l) # 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 @@ -413,10 +372,10 @@ Default(l) # -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 #include @@ -426,7 +385,7 @@ int g_1() } """) -test.write(['SLF', 'src', 'lib_geng', 'libg_2.c'], """\ +test.write(['src', 'lib_geng', 'libg_2.c'], """\ #include #include #include @@ -438,7 +397,7 @@ int g_2() } """) -test.write(['SLF', 'src', 'lib_geng', 'libg_3.c'], """\ +test.write(['src', 'lib_geng', 'libg_3.c'], """\ #include #include @@ -448,36 +407,7 @@ int g_3() } """) -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, diff --git a/test/Scanner/multi-env.py b/test/Scanner/multi-env.py new file mode 100644 index 00000000..514fbca6 --- /dev/null +++ b/test/Scanner/multi-env.py @@ -0,0 +1,116 @@ +#!/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() diff --git a/test/parallel-rescan.py b/test/Scanner/parallel-rescan.py similarity index 100% rename from test/parallel-rescan.py rename to test/Scanner/parallel-rescan.py diff --git a/test/Scanner/scan-once.py b/test/Scanner/scan-once.py new file mode 100644 index 00000000..7e02dd27 --- /dev/null +++ b/test/Scanner/scan-once.py @@ -0,0 +1,94 @@ +#!/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() diff --git a/test/SharedLibrary.py b/test/SharedLibrary.py index d9b03509..f8447ca3 100644 --- a/test/SharedLibrary.py +++ b/test/SharedLibrary.py @@ -94,6 +94,8 @@ EXPORTS """) test.write('f2a.c', r""" +#include + void f2a(void) { @@ -102,6 +104,7 @@ f2a(void) """) test.write('f2b.c', r""" +#include void f2b(void) { @@ -131,6 +134,7 @@ EXPORTS """) test.write('f3a.c', r""" +#include void f3a(void) { @@ -139,6 +143,7 @@ f3a(void) """) test.write('f3b.c', r""" +#include void f3b(void) { @@ -168,6 +173,7 @@ EXPORTS """) test.write('prog.c', r""" +#include void f1(void); void f2a(void); void f2b(void); @@ -253,6 +259,7 @@ EXPORTS """) test.write('progbar.c', r""" +#include void f4(void); int main(int argc, char *argv[]) diff --git a/test/TAR/TAR.py b/test/TAR/TAR.py index 9d5a617e..c82e227a 100644 --- a/test/TAR/TAR.py +++ b/test/TAR/TAR.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -60,12 +60,12 @@ sys.exit(0) """) 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") @@ -98,7 +98,7 @@ os.system(string.join(sys.argv[1:], " ")) 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') @@ -112,7 +112,7 @@ f4.Tar(target = 'f4', source = 'file19') 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', diff --git a/test/TAR/TARCOM.py b/test/TAR/TARCOM.py index f6e36e79..a39dd22f 100644 --- a/test/TAR/TARCOM.py +++ b/test/TAR/TARCOM.py @@ -33,7 +33,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -50,7 +50,7 @@ sys.exit(0) 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()) diff --git a/test/TAR/TARCOMSTR.py b/test/TAR/TARCOMSTR.py index 2bd3813d..eee9b16f 100644 --- a/test/TAR/TARCOMSTR.py +++ b/test/TAR/TARCOMSTR.py @@ -31,7 +31,7 @@ the displayed string when tar is called. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,10 +49,10 @@ sys.exit(0) 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") diff --git a/test/TAR/TARFLAGS.py b/test/TAR/TARFLAGS.py index 2cda5022..c592fe00 100644 --- a/test/TAR/TARFLAGS.py +++ b/test/TAR/TARFLAGS.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -64,12 +64,14 @@ sys.exit(0) """) 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") @@ -104,12 +106,12 @@ os.system(string.join(sys.argv[1:], " ")) 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") diff --git a/test/TARGET-dir.py b/test/TARGET-dir.py index c599a160..09f20f09 100644 --- a/test/TARGET-dir.py +++ b/test/TARGET-dir.py @@ -68,6 +68,9 @@ test.write(['src', 'foo.h.in'], """\ """) test.write(['src', 'foo.c'], """\ +#include +#include + #include int diff --git a/test/TEX/LATEX.py b/test/TEX/LATEX.py index 25446961..0636109a 100644 --- a/test/TEX/LATEX.py +++ b/test/TEX/LATEX.py @@ -36,7 +36,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -59,10 +59,10 @@ sys.exit(0) """) 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 @@ -113,14 +113,14 @@ foo = Environment(ENV = ENV) 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} diff --git a/test/TEX/LATEXCOM.py b/test/TEX/LATEXCOM.py index 803d26d2..a5044ae9 100644 --- a/test/TEX/LATEXCOM.py +++ b/test/TEX/LATEXCOM.py @@ -33,7 +33,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -51,7 +51,7 @@ sys.exit(0) 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()) diff --git a/test/TEX/LATEXCOMSTR.py b/test/TEX/LATEXCOMSTR.py index 5e31301e..08fcccb9 100644 --- a/test/TEX/LATEXCOMSTR.py +++ b/test/TEX/LATEXCOMSTR.py @@ -34,7 +34,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -52,7 +52,7 @@ sys.exit(0) 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()) diff --git a/test/TEX/LATEXFLAGS.py b/test/TEX/LATEXFLAGS.py index fa2348f0..b8870386 100644 --- a/test/TEX/LATEXFLAGS.py +++ b/test/TEX/LATEXFLAGS.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -55,10 +55,12 @@ sys.exit(0) """) 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 @@ -92,10 +94,10 @@ import os 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} diff --git a/test/TEX/PDFLATEX.py b/test/TEX/PDFLATEX.py index 015db568..e1cf00e1 100644 --- a/test/TEX/PDFLATEX.py +++ b/test/TEX/PDFLATEX.py @@ -36,7 +36,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -59,10 +59,10 @@ sys.exit(0) """) 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 @@ -110,10 +110,10 @@ import os 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} diff --git a/test/TEX/PDFLATEXCOM.py b/test/TEX/PDFLATEXCOM.py index f46ed37a..1ce2642d 100644 --- a/test/TEX/PDFLATEXCOM.py +++ b/test/TEX/PDFLATEXCOM.py @@ -33,7 +33,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -51,7 +51,7 @@ sys.exit(0) 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()) diff --git a/test/TEX/PDFLATEXCOMSTR.py b/test/TEX/PDFLATEXCOMSTR.py index 94cf1213..284a52ad 100644 --- a/test/TEX/PDFLATEXCOMSTR.py +++ b/test/TEX/PDFLATEXCOMSTR.py @@ -35,7 +35,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -53,7 +53,7 @@ sys.exit(0) 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()) diff --git a/test/TEX/PDFLATEXFLAGS.py b/test/TEX/PDFLATEXFLAGS.py index 0b6a9fca..a3948fe8 100644 --- a/test/TEX/PDFLATEXFLAGS.py +++ b/test/TEX/PDFLATEXFLAGS.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -55,10 +55,12 @@ sys.exit(0) """) 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 @@ -92,10 +94,10 @@ import os 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} diff --git a/test/TEX/PDFTEX.py b/test/TEX/PDFTEX.py index 5b99c230..ad77b8af 100644 --- a/test/TEX/PDFTEX.py +++ b/test/TEX/PDFTEX.py @@ -36,7 +36,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -59,9 +59,9 @@ sys.exit(0) """) 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 @@ -97,10 +97,10 @@ import os 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. diff --git a/test/TEX/PDFTEXCOM.py b/test/TEX/PDFTEXCOM.py index 2a7f06be..f7601253 100644 --- a/test/TEX/PDFTEXCOM.py +++ b/test/TEX/PDFTEXCOM.py @@ -33,7 +33,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -51,7 +51,7 @@ sys.exit(0) 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()) diff --git a/test/TEX/PDFTEXCOMSTR.py b/test/TEX/PDFTEXCOMSTR.py index dbb7b39d..ac32ae1e 100644 --- a/test/TEX/PDFTEXCOMSTR.py +++ b/test/TEX/PDFTEXCOMSTR.py @@ -35,7 +35,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -53,7 +53,7 @@ sys.exit(0) 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()) diff --git a/test/TEX/PDFTEXFLAGS.py b/test/TEX/PDFTEXFLAGS.py index 1a0f8df2..94c54669 100644 --- a/test/TEX/PDFTEXFLAGS.py +++ b/test/TEX/PDFTEXFLAGS.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -55,9 +55,11 @@ sys.exit(0) """) 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 @@ -85,10 +87,10 @@ import os 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. diff --git a/test/TEX/TEX.py b/test/TEX/TEX.py index 4645c7c6..7ea359b4 100644 --- a/test/TEX/TEX.py +++ b/test/TEX/TEX.py @@ -36,7 +36,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -59,9 +59,9 @@ sys.exit(0) """) 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 @@ -97,14 +97,14 @@ import os 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. diff --git a/test/TEX/TEXCOM.py b/test/TEX/TEXCOM.py index 4957427a..cf887a4f 100644 --- a/test/TEX/TEXCOM.py +++ b/test/TEX/TEXCOM.py @@ -33,7 +33,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -51,7 +51,7 @@ sys.exit(0) 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()) diff --git a/test/TEX/TEXCOMSTR.py b/test/TEX/TEXCOMSTR.py index 81e71234..66c26020 100644 --- a/test/TEX/TEXCOMSTR.py +++ b/test/TEX/TEXCOMSTR.py @@ -34,7 +34,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe test = TestSCons.TestSCons() @@ -52,7 +52,7 @@ sys.exit(0) 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()) diff --git a/test/TEX/TEXFLAGS.py b/test/TEX/TEXFLAGS.py index 7bd602fd..c27ffe52 100644 --- a/test/TEX/TEXFLAGS.py +++ b/test/TEX/TEXFLAGS.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -55,9 +55,11 @@ sys.exit(0) """) 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 @@ -85,10 +87,10 @@ import os 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. diff --git a/test/Value.py b/test/Value.py index 46f82322..85fcbd19 100644 --- a/test/Value.py +++ b/test/Value.py @@ -31,6 +31,8 @@ import sys 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 @@ -55,13 +57,25 @@ def create(target, source, env): 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 @@ -73,18 +87,25 @@ open(sys.argv[-1],'wb').write(string.join(sys.argv[1:-2])) 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='.') @@ -111,6 +132,8 @@ open(sys.argv[-1],'wb').write(string.join(sys.argv[1:-2])) 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', '.') @@ -119,5 +142,6 @@ open(sys.argv[-1],'wb').write(string.join(sys.argv[1:-2])) 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() diff --git a/test/YACC/YACC.py b/test/YACC/YACC.py index 9be19347..d3bc679f 100644 --- a/test/YACC/YACC.py +++ b/test/YACC/YACC.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe if sys.platform == 'win32': @@ -64,10 +64,10 @@ sys.exit(0) 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 @@ -113,13 +113,13 @@ os.system(string.join(sys.argv[1:], " ")) 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""" %%{ diff --git a/test/YACC/YACCCOM.py b/test/YACC/YACCCOM.py index 5f7cd380..1425eb83 100644 --- a/test/YACC/YACCCOM.py +++ b/test/YACC/YACCCOM.py @@ -30,7 +30,7 @@ Test the ability to configure the $YACCCOM construction variable. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -48,10 +48,10 @@ sys.exit(0) 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") diff --git a/test/YACC/YACCCOMSTR.py b/test/YACC/YACCCOMSTR.py index cfb48b76..b2c128d1 100644 --- a/test/YACC/YACCCOMSTR.py +++ b/test/YACC/YACCCOMSTR.py @@ -31,7 +31,7 @@ the displayed string when yacc is called. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,11 +49,11 @@ sys.exit(0) 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") diff --git a/test/YACC/YACCFLAGS.py b/test/YACC/YACCFLAGS.py index 2779597a..a94bc8f9 100644 --- a/test/YACC/YACCFLAGS.py +++ b/test/YACC/YACCFLAGS.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe if sys.platform == 'win32': @@ -62,9 +62,11 @@ sys.exit(0) """) 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 diff --git a/test/YACC/YACCHFILESUFFIX.py b/test/YACC/YACCHFILESUFFIX.py index 389018fb..231472df 100644 --- a/test/YACC/YACCHFILESUFFIX.py +++ b/test/YACC/YACCHFILESUFFIX.py @@ -31,7 +31,7 @@ utility that writes to an odd import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -58,12 +58,12 @@ sys.exit(0) 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") diff --git a/test/YACC/YACCHXXFILESUFFIX.py b/test/YACC/YACCHXXFILESUFFIX.py index b564d5e8..182f08b6 100644 --- a/test/YACC/YACCHXXFILESUFFIX.py +++ b/test/YACC/YACCHXXFILESUFFIX.py @@ -31,7 +31,7 @@ utility that writes to an odd import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -58,11 +58,11 @@ sys.exit(0) 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") diff --git a/test/ZIP/ZIP.py b/test/ZIP/ZIP.py index 33c54dd5..646677d1 100644 --- a/test/ZIP/ZIP.py +++ b/test/ZIP/ZIP.py @@ -31,7 +31,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -66,12 +66,12 @@ sys.exit(0) 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") diff --git a/test/ZIP/ZIPCOM.py b/test/ZIP/ZIPCOM.py index 42b8cff4..460abe42 100644 --- a/test/ZIP/ZIPCOM.py +++ b/test/ZIP/ZIPCOM.py @@ -33,7 +33,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -50,7 +50,7 @@ sys.exit(0) 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()) diff --git a/test/ZIP/ZIPCOMSTR.py b/test/ZIP/ZIPCOMSTR.py index 0ee90fd8..5284d0a0 100644 --- a/test/ZIP/ZIPCOMSTR.py +++ b/test/ZIP/ZIPCOMSTR.py @@ -31,7 +31,7 @@ the displayed string when zip is called. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -49,10 +49,10 @@ sys.exit(0) 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") diff --git a/test/bad-variables.py b/test/bad-variables.py index 59fc184b..cb6b357c 100644 --- a/test/bad-variables.py +++ b/test/bad-variables.py @@ -33,17 +33,24 @@ import TestSCons 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') """) @@ -52,9 +59,11 @@ env = Environment() 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() diff --git a/test/builderrors.py b/test/builderrors.py index 4eb6bfad..8c7c4ab7 100644 --- a/test/builderrors.py +++ b/test/builderrors.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -47,13 +47,13 @@ sys.exit(exitval) """) 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") @@ -67,13 +67,13 @@ test.fail_test(os.path.exists(test.workpath('f2.out'))) 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") @@ -87,13 +87,13 @@ test.fail_test(os.path.exists(test.workpath('f2.out'))) 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") @@ -120,4 +120,62 @@ err = test.stderr() 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() diff --git a/test/chdir.py b/test/chdir.py index b46764b3..1a1a2d72 100644 --- a/test/chdir.py +++ b/test/chdir.py @@ -31,7 +31,7 @@ Command() calls and execution work1s correctly. import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -99,7 +99,7 @@ ofp.close """) 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) @@ -229,14 +229,14 @@ work2_sub_f1_out = test.workpath('work2', 'sub', 'f1.out') 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()) @@ -246,13 +246,13 @@ test.write(['work2', 'sub', 'f2.in'], "work2/sub/f2.in") 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()) diff --git a/test/dependency-cycle.py b/test/dependency-cycle.py index 8d1275f2..b2a89743 100644 --- a/test/dependency-cycle.py +++ b/test/dependency-cycle.py @@ -40,6 +40,7 @@ env.Depends(foo3, foo1) """) test.write('f1.c', r""" +#include void f1(void) { diff --git a/test/errors.py b/test/errors.py index 120ea3a0..6e0a05f9 100644 --- a/test/errors.py +++ b/test/errors.py @@ -29,7 +29,7 @@ import TestSCons import string import sys -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons(match = TestCmd.match_re_dotall) @@ -85,7 +85,7 @@ a.append(2) test.run(status = 2, stderr = """\ AttributeError: 'int' object has no attribute 'append': - File "SConstruct", line 2: + File ".+SConstruct", line 2: a.append\(2\) """) @@ -98,7 +98,7 @@ a == 1 test.run(status = 2, stderr = """\ NameError: [^\n]* - File "SConstruct", line 1: + File ".+SConstruct", line 1: a == 1 """) @@ -110,7 +110,7 @@ a ! x """) test.run(stdout = "scons: Reading SConscript files ...\n", - stderr = """ File "SConstruct", line 2 + stderr = """ File ".+SConstruct", line 2 a ! x @@ -130,7 +130,7 @@ a[2] = 3 test.run(status = 2, stderr = """\ TypeError: object does not support item assignment: - File "SConstruct", line 2: + File ".+SConstruct", line 2: a\[2\] = 3 """) @@ -146,7 +146,7 @@ raise SCons.Errors.UserError, 'Depends() require both sources and targets.' 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) @@ -163,7 +163,7 @@ test.run(stdout = "scons: Reading SConscript files ...\ninternal error\n", 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) @@ -178,8 +178,10 @@ sys.exit(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") diff --git a/test/exceptions.py b/test/exceptions.py index 584d4f19..01a28552 100644 --- a/test/exceptions.py +++ b/test/exceptions.py @@ -25,16 +25,19 @@ __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) @@ -51,10 +54,10 @@ Traceback \((most recent call|innermost) last\): )*( 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) @@ -69,11 +72,11 @@ import sys 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") @@ -87,13 +90,13 @@ test.run(arguments = '-j2 .', status = 2, stderr = expected_stderr) # 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') diff --git a/test/expansion.py b/test/expansion.py index 2c22291b..0f721345 100644 --- a/test/expansion.py +++ b/test/expansion.py @@ -52,6 +52,8 @@ env.Program(r'%s') os.path.join('$SUBDIR', 'foo4.c'))) test.write(['sub', 'f1.c'], r""" +#include +#include int main(int argc, char *argv[]) { @@ -62,6 +64,8 @@ main(int argc, char *argv[]) """) test.write('f2.c', r""" +#include +#include int main(int argc, char *argv[]) { @@ -72,6 +76,8 @@ main(int argc, char *argv[]) """) test.write(['sub', 'f3.c'], r""" +#include +#include int main(int argc, char *argv[]) { @@ -82,6 +88,8 @@ main(int argc, char *argv[]) """) test.write(['sub', 'foo4.c'], r""" +#include +#include int main(int argc, char *argv[]) { diff --git a/test/explain.py b/test/explain.py index 7f0fbb54..f69b00f1 100644 --- a/test/explain.py +++ b/test/explain.py @@ -33,7 +33,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -85,7 +85,7 @@ kscan = Scanner(name = 'kfile', 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}, @@ -97,7 +97,7 @@ env.Install('../inc', 'aaa') env.InstallAs('../inc/bbb.k', 'bbb.k') env.Install('../inc', 'ddd') env.InstallAs('../inc/eee', 'eee.in') -""" % (python, cat_py) +""" % locals() args = '--debug=explain .' @@ -109,10 +109,12 @@ Import("env") 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'], """\ @@ -155,15 +157,15 @@ work1_inc_eee = test.workpath('work1', 'inc', 'eee') 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 @@ -173,10 +175,12 @@ Install file: "eee.in" as "%(work1_inc_eee)s" 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'], """\ @@ -203,23 +207,25 @@ test.write(['work1', 'src', 'yyy'], "yyy 2\n") 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'], """\ @@ -243,10 +249,12 @@ Import("env") 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") @@ -256,10 +264,12 @@ Import("env") 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") @@ -269,12 +279,14 @@ Import("env") 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") @@ -283,20 +295,22 @@ test.write(['work1', 'src', 'SConscript'], """\ 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") @@ -307,22 +321,24 @@ test.write(['work1', 'src', 'SConscript'], """\ 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") @@ -331,14 +347,18 @@ test.must_match(['work1', 'src', 'file3.yyy'], "zzz 2\nyyy 2\nxxx 1\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") @@ -363,7 +383,7 @@ Import("env") 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()) @@ -437,20 +457,20 @@ work4_inc_eee = test.workpath('work4', 'inc', 'eee') 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") diff --git a/test/gnutools.py b/test/gnutools.py index 82c83ef6..4bcea00c 100644 --- a/test/gnutools.py +++ b/test/gnutools.py @@ -31,7 +31,7 @@ Testing the gnu tool chain, i.e. the tools 'gcc', 'g++' and 'gnulink'. import TestSCons import string import sys -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe _dll = TestSCons._dll dll_ = TestSCons.dll_ @@ -91,10 +91,13 @@ test.write(['work1', 'cppfile2.cpp'],""" /* 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')) @@ -104,8 +107,7 @@ env.Program('c-and-cpp', Split('cfile1.c cppfile1.cpp')) 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') diff --git a/test/ignore-command.py b/test/ignore-command.py index 201c488a..d4de8d3a 100644 --- a/test/ignore-command.py +++ b/test/ignore-command.py @@ -36,7 +36,7 @@ import sys import TestCmd import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -53,13 +53,13 @@ sys.exit(1) 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()) diff --git a/test/implicit-cache/GetOption.py b/test/implicit-cache/GetOption.py new file mode 100644 index 00000000..5915cca6 --- /dev/null +++ b/test/implicit-cache/GetOption.py @@ -0,0 +1,53 @@ +#!/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() diff --git a/test/implicit-cache/SetOption.py b/test/implicit-cache/SetOption.py new file mode 100644 index 00000000..ee2afa5c --- /dev/null +++ b/test/implicit-cache/SetOption.py @@ -0,0 +1,70 @@ +#!/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 + +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() diff --git a/test/option--implicit-cache.py b/test/implicit-cache/basic.py similarity index 71% rename from test/option--implicit-cache.py rename to test/implicit-cache/basic.py index 2508cf24..0c9196cf 100644 --- a/test/option--implicit-cache.py +++ b/test/implicit-cache/basic.py @@ -24,10 +24,9 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" -import os -import sys +import os.path + import TestSCons -import string _exe = TestSCons._exe _obj = TestSCons._obj @@ -67,8 +66,7 @@ Import("env") env.Program(target='prog', source='prog.c') """) -test.write('nodeps.in', -r""" +test.write('nodeps.in', r""" int main(int argc, char *argv[]) { @@ -78,24 +76,20 @@ 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 """) -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 #include @@ -110,19 +104,16 @@ main(int argc, char *argv[]) } """) -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 void one(void) { } @@ -141,9 +132,10 @@ test.run(program = test.workpath(variant_prog), 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" """) @@ -161,10 +153,11 @@ test.run(program = test.workpath(variant_prog), 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" @@ -183,8 +176,9 @@ test.run(program = test.workpath(variant_prog), 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" @@ -203,19 +197,18 @@ test.run(program = test.workpath(variant_prog), 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 """) 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") @@ -225,9 +218,10 @@ test.run(program = test.workpath(subdir_prog), 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" """) @@ -243,11 +237,12 @@ test.run(program = test.workpath(subdir_prog), 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 int @@ -258,117 +253,65 @@ main(int argc, char *argv[]) } """) -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 - -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() diff --git a/test/import.py b/test/import.py index 3663f535..bb070ab3 100644 --- a/test/import.py +++ b/test/import.py @@ -33,6 +33,8 @@ import TestSCons test = TestSCons.TestSCons() +SConstruct_path = test.workpath('SConstruct') + platforms = [ 'aix', 'cygwin', @@ -139,27 +141,33 @@ tools = [ # 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, @@ -176,15 +184,20 @@ intel_warnings = [ 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, diff --git a/test/long-lines.py b/test/long-lines.py index afa84552..1c501e35 100644 --- a/test/long-lines.py +++ b/test/long-lines.py @@ -73,6 +73,8 @@ env.SharedLibrary(target = 'shared', source = 'shared.c', no_import_lib=1) """ % (arflag_init, arflag, linkflag_init, linkflag)) test.write('foo.c', r""" +#include +#include int main(int argc, char *argv[]) { @@ -83,6 +85,8 @@ main(int argc, char *argv[]) """) test.write('static.c', r""" +#include +#include int main(int argc, char *argv[]) { @@ -93,6 +97,8 @@ main(int argc, char *argv[]) """) test.write('shared.c', r""" +#include +#include int main(int argc, char *argv[]) { diff --git a/test/multi.py b/test/multi.py index 5a5d667b..c8b8df45 100644 --- a/test/multi.py +++ b/test/multi.py @@ -36,6 +36,7 @@ import TestSCons test = TestSCons.TestSCons(match=TestCmd.match_re) +_python_ = TestSCons._python_ # # A builder with "multi" set can be called multiple times and @@ -131,11 +132,11 @@ build(sys.argv[1],sys.argv[2],sys.argv[3:]) 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') @@ -162,17 +163,17 @@ build(sys.argv[1],sys.argv[2],sys.argv[3:]) 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=(""" diff --git a/test/multiline.py b/test/multiline.py index 302e17db..59eba604 100644 --- a/test/multiline.py +++ b/test/multiline.py @@ -29,6 +29,7 @@ import sys import TestSCons python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -42,14 +43,14 @@ sys.exit(0) """) 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") diff --git a/test/option--.py b/test/option--.py index 5f707695..95403973 100644 --- a/test/option--.py +++ b/test/option--.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -41,16 +41,16 @@ file.close() """) 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) diff --git a/test/option--D.py b/test/option--D.py index d1a118ee..cca8ed17 100644 --- a/test/option--D.py +++ b/test/option--D.py @@ -28,7 +28,7 @@ import sys import TestSCons import os -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -44,14 +44,14 @@ file.close() 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') diff --git a/test/option--Q.py b/test/option--Q.py index 4d1a0058..f99031ce 100644 --- a/test/option--Q.py +++ b/test/option--Q.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -41,19 +41,19 @@ file.close() """) 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'))) diff --git a/test/option--U.py b/test/option--U.py index db6532e4..3b0cc0de 100644 --- a/test/option--U.py +++ b/test/option--U.py @@ -32,7 +32,7 @@ import TestSCons test = TestSCons.TestSCons() -python = TestSCons.python +_python_ = TestSCons._python_ test.subdir('sub1', 'sub2', 'sub3') @@ -47,7 +47,7 @@ file.close() 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') @@ -56,7 +56,7 @@ BuildDir('sub2b', 'sub2') SConscript('sub2b/SConscript') Default(env.B(target = 'sub2/xxx.out', source = 'xxx.in')) SConscript('SConscript') -""" % python) +""" % locals()) test.write(['sub2', 'SConscript'], """ Import('env') diff --git a/test/option--Y.py b/test/option--Y.py index 62d8b7a1..99d69398 100644 --- a/test/option--Y.py +++ b/test/option--Y.py @@ -49,6 +49,7 @@ env.Program(target= 'foo', source = Split('aaa.c bbb.c foo.c')) """) test.write(['repository', 'aaa.c'], r""" +#include void aaa(void) { @@ -57,6 +58,7 @@ aaa(void) """) test.write(['repository', 'bbb.c'], r""" +#include void bbb(void) { @@ -65,6 +67,8 @@ bbb(void) """) test.write(['repository', 'foo.c'], r""" +#include +#include extern void aaa(void); extern void bbb(void); int @@ -95,6 +99,8 @@ test.up_to_date(chdir = 'work1', options = opts, arguments = '.') # test.write(['work1', 'bbb.c'], r""" +#include +#include void bbb(void) { @@ -113,6 +119,8 @@ test.up_to_date(chdir = 'work1', options = opts, arguments = '.') # test.write(['work1', 'aaa.c'], r""" +#include +#include void aaa(void) { @@ -121,6 +129,8 @@ aaa(void) """) test.write(['work1', 'foo.c'], r""" +#include +#include extern void aaa(void); extern void bbb(void); int @@ -175,6 +185,8 @@ test.write(['r.OLD', 'SConstruct'], SConstruct) test.write(['r.NEW', 'SConstruct'], SConstruct) test.write(['r.OLD', 'foo.c'], r""" +#include +#include int main(int argc, char *argv[]) { @@ -201,6 +213,8 @@ test.up_to_date(chdir = 'work2', options = opts, arguments = '.') test.writable('r.NEW', 1) test.write(['r.NEW', 'foo.c'], r""" +#include +#include int main(int argc, char *argv[]) { @@ -220,6 +234,8 @@ test.up_to_date(chdir = 'work2', options = opts, arguments = '.') # test.write(['work2', 'foo.c'], r""" +#include +#include int main(int argc, char *argv[]) { @@ -240,6 +256,8 @@ test.writable('r.OLD', 1) test.writable('r.NEW', 1) test.write(['r.OLD', 'foo.c'], r""" +#include +#include int main(int argc, char *argv[]) { @@ -250,6 +268,8 @@ main(int argc, char *argv[]) """) test.write(['r.NEW', 'foo.c'], r""" +#include +#include int main(int argc, char *argv[]) { diff --git a/test/option--cs.py b/test/option--cs.py index 16a3a73d..1e62c491 100644 --- a/test/option--cs.py +++ b/test/option--cs.py @@ -34,7 +34,7 @@ import shutil import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ _exe = TestSCons._exe _obj = TestSCons._obj @@ -51,6 +51,8 @@ for src in sys.argv[2:]: file.close() """) +cache = test.workpath('cache') + test.write(['src1', 'SConstruct'], """ def cat(env, source, target): target = str(target[0]) @@ -61,13 +63,13 @@ def cat(env, source, target): 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") @@ -103,14 +105,14 @@ test.run(chdir = 'src1', arguments = '-c .') # 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')) @@ -121,14 +123,14 @@ test.run(chdir = 'src1', arguments = '-c .') # 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')) @@ -158,6 +160,8 @@ CacheDir(r'%s') """ % (test.workpath('cache'))) test.write(['src2', 'hello.c'], r"""\ +#include +#include int main(int argc, char *argv[]) { diff --git a/test/option--debug.py b/test/option--debug.py index f60710d2..a56f261b 100644 --- a/test/option--debug.py +++ b/test/option--debug.py @@ -24,12 +24,15 @@ __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', """ @@ -70,7 +73,7 @@ test.write('bar.h', """ 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 @@ -93,7 +96,7 @@ FILE = Builder(action="$FILECOM") 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", @@ -116,7 +119,7 @@ env.LIST('file15.out', 'file15.in') 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") @@ -139,34 +142,34 @@ test.write('file18.in', "file18.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"]) @@ -178,42 +181,42 @@ Building file09.out with action: 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") diff --git a/test/option--max-drift.py b/test/option--max-drift.py index bc26f33b..1ac077a6 100644 --- a/test/option--max-drift.py +++ b/test/option--max-drift.py @@ -30,7 +30,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -43,11 +43,11 @@ file.close() """) 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") @@ -59,8 +59,8 @@ test.run(arguments = 'f1.out') 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')) @@ -72,11 +72,12 @@ os.utime(test.workpath('f1.in'), (atime,mtime)) 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', """ @@ -99,10 +100,10 @@ test.run(arguments='--max-drift=1') # 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') diff --git a/test/option-c.py b/test/option-c.py index 88148277..7ab4129a 100644 --- a/test/option-c.py +++ b/test/option-c.py @@ -32,7 +32,7 @@ import os.path import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -45,7 +45,7 @@ file.close() """) 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') @@ -67,7 +67,7 @@ if hasattr(os, 'symlink'): env.Command(['touch1.out', 'touch2.out'], [], [Touch('${TARGETS[0]}'), Touch('${TARGETS[1]}')]) -""" % python) +""" % locals()) test.write('foo1.in', "foo1.in\n") @@ -191,7 +191,7 @@ test.write(['subd', 'foox.in'], "foox.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') @@ -201,7 +201,7 @@ SConscript('subd/SConscript') Clean(foo2_xxx, ['aux1.x']) env.Clean(['${FOO}.xxx'], ['aux2.x']) Clean('.', ['subd']) -""" % python) +""" % locals()) test.write(['subd', 'SConscript'], """ Clean('.', 'foox.in') @@ -248,12 +248,12 @@ test.must_not_exist(test.workpath('subdir')) # 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') @@ -261,36 +261,36 @@ 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 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')) diff --git a/test/option-i.py b/test/option-i.py index b0a84f86..a4ea4ac5 100644 --- a/test/option-i.py +++ b/test/option-i.py @@ -28,7 +28,7 @@ import os.path import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -46,14 +46,14 @@ sys.exit(1) """) 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") diff --git a/test/option-j.py b/test/option-j.py index fdf7b839..8f4c1900 100644 --- a/test/option-j.py +++ b/test/option-j.py @@ -34,7 +34,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ try: import threading @@ -64,7 +64,7 @@ foo you """) 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') @@ -80,7 +80,7 @@ t = env.Command(target=['foo/foo1.out', 'foo/foo2.out'], 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""" @@ -160,7 +160,7 @@ os.environ['PYTHONPATH'] = save_pythonpath # 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') @@ -178,7 +178,7 @@ env.Install('out', t) 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 @@ -188,7 +188,7 @@ test.fail_test(not (start2 < finish1)) # 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') @@ -206,7 +206,7 @@ env.Install('out', t) 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 @@ -230,14 +230,14 @@ sys.exit(1) """) 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") diff --git a/test/option-k.py b/test/option-k.py index 45c31d2b..0a46606a 100644 --- a/test/option-k.py +++ b/test/option-k.py @@ -28,7 +28,7 @@ import os.path import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -50,13 +50,13 @@ sys.exit(1) """) 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") @@ -93,14 +93,14 @@ test.must_match(['work1', 'bbb.out'], "succeed.py: bbb.out\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") @@ -113,11 +113,11 @@ test.run(chdir = 'work2', 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']) diff --git a/test/option-n.py b/test/option-n.py index 769c4dd1..2e7694b7 100644 --- a/test/option-n.py +++ b/test/option-n.py @@ -47,7 +47,7 @@ import sys import TestCmd import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -61,14 +61,14 @@ file.close() """) 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") @@ -82,9 +82,9 @@ test.write(['src', 'f4.in'], "src/f4.in\n") 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'))) @@ -118,8 +118,8 @@ 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) diff --git a/test/option-q.py b/test/option-q.py index e8460f09..9b67d0a5 100644 --- a/test/option-q.py +++ b/test/option-q.py @@ -34,7 +34,7 @@ import TestSCons test = TestSCons.TestSCons() -python = TestSCons.python +_python_ = TestSCons._python_ test.write('build.py', r""" import sys @@ -45,11 +45,11 @@ file.close() """) 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") diff --git a/test/option-s.py b/test/option-s.py index c1061ba8..b3bde5f2 100644 --- a/test/option-s.py +++ b/test/option-s.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -41,11 +41,11 @@ file.close() """) 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") diff --git a/test/option/debug-dtree.py b/test/option/debug-dtree.py index 0a7f4d2d..06296b91 100644 --- a/test/option/debug-dtree.py +++ b/test/option/debug-dtree.py @@ -43,6 +43,8 @@ env.Program('foo', Split('foo.c bar.c')) """) test.write('foo.c', r""" +#include +#include #include "foo.h" int main(int argc, char *argv[]) { diff --git a/test/option/debug-findlibs.py b/test/option/debug-findlibs.py index b18841bd..42204027 100644 --- a/test/option/debug-findlibs.py +++ b/test/option/debug-findlibs.py @@ -24,12 +24,15 @@ __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') @@ -49,9 +52,9 @@ env = Environment(OBJSUFFIX = '.ooo', PROGSUFFIX = '.xxx', 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") @@ -198,8 +201,8 @@ test.run(arguments = "--debug=findlibs foo.xxx", 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") diff --git a/test/option/debug-includes.py b/test/option/debug-includes.py index eb7f818c..52d64a9d 100644 --- a/test/option/debug-includes.py +++ b/test/option/debug-includes.py @@ -43,6 +43,8 @@ env.Program('foo', Split('foo.c bar.c')) """) test.write('foo.c', r""" +#include +#include #include "foo.h" int main(int argc, char *argv[]) { diff --git a/test/option/debug-stacktrace.py b/test/option/debug-stacktrace.py index 1a3052ad..aff25f24 100644 --- a/test/option/debug-stacktrace.py +++ b/test/option/debug-stacktrace.py @@ -114,4 +114,25 @@ if err and must_contain_all_lines(test.stderr(), inner_lines): +# 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() diff --git a/test/option/debug-stree.py b/test/option/debug-stree.py index 69aab066..8ffadc6d 100644 --- a/test/option/debug-stree.py +++ b/test/option/debug-stree.py @@ -43,6 +43,8 @@ env.Program('foo', Split('foo.c bar.c')) """) test.write('foo.c', r""" +#include +#include #include "foo.h" int main(int argc, char *argv[]) { diff --git a/test/option/debug-time.py b/test/option/debug-time.py index 5766cff8..b1471bad 100644 --- a/test/option/debug-time.py +++ b/test/option/debug-time.py @@ -38,6 +38,8 @@ env.Program('foo', Split('foo.c bar.c')) """) test.write('foo.c', r""" +#include +#include #include "foo.h" int main(int argc, char *argv[]) { diff --git a/test/option/debug-tree.py b/test/option/debug-tree.py index faf85d97..4f025c28 100644 --- a/test/option/debug-tree.py +++ b/test/option/debug-tree.py @@ -47,6 +47,8 @@ env.Program('Foo', Split('Foo.c Bar.c')) # (UNIX/Linux) and case-insensitive (Windows) systems. test.write('Foo.c', r""" +#include +#include #include "Foo.h" int main(int argc, char *argv[]) { diff --git a/test/option/profile.py b/test/option/profile.py index b6a00279..92070667 100644 --- a/test/option/profile.py +++ b/test/option/profile.py @@ -33,7 +33,11 @@ import TestSCons 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') @@ -63,30 +67,30 @@ test.fail_test(string.find(s, 'option_parser.py') == -1) 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) diff --git a/test/overrides.py b/test/overrides.py index 69f7440d..dabf689b 100644 --- a/test/overrides.py +++ b/test/overrides.py @@ -31,7 +31,7 @@ import sys test = TestSCons.TestSCons() -python = TestSCons.python +_python_ = TestSCons._python_ test.write('SConstruct', """ env = Environment(CCFLAGS='-DFOO', LIBS=['a']) @@ -69,11 +69,11 @@ env['LIBS'] = buildlibs 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") @@ -97,13 +97,13 @@ test.up_to_date(arguments='hello.not_exe') 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") diff --git a/test/redirection.py b/test/redirection.py index 5aac5176..cededdbf 100644 --- a/test/redirection.py +++ b/test/redirection.py @@ -27,7 +27,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import os import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -44,14 +44,14 @@ sys.exit(0) 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') diff --git a/test/runtest/aegis/batch-output.py b/test/runtest/aegis/batch-output.py new file mode 100644 index 00000000..40202398 --- /dev/null +++ b/test/runtest/aegis/batch-output.py @@ -0,0 +1,60 @@ +#!/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() diff --git a/test/runtest/baseline/combined.py b/test/runtest/baseline/combined.py index 6382cb18..ab91e877 100644 --- a/test/runtest/baseline/combined.py +++ b/test/runtest/baseline/combined.py @@ -30,8 +30,14 @@ Test a combination of a passing test, failing test, and no-result 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') @@ -45,37 +51,37 @@ 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 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() diff --git a/test/runtest/baseline/fail.py b/test/runtest/baseline/fail.py index b650a8c3..b61e5dad 100644 --- a/test/runtest/baseline/fail.py +++ b/test/runtest/baseline/fail.py @@ -38,7 +38,7 @@ test.write_failing_test(['test', 'fail.py']) # 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 @@ -57,6 +57,6 @@ expect = r"""qmtest.py run --output baseline.qmr --format none --result-stream=s 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() diff --git a/test/runtest/baseline/no_result.py b/test/runtest/baseline/no_result.py index dc2586d9..9ef815d8 100644 --- a/test/runtest/baseline/no_result.py +++ b/test/runtest/baseline/no_result.py @@ -36,7 +36,7 @@ test.subdir('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 @@ -55,6 +55,6 @@ expect = r"""qmtest.py run --output baseline.qmr --format none --result-stream=s 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() diff --git a/test/runtest/baseline/pass.py b/test/runtest/baseline/pass.py index b32ecbe4..f574e573 100644 --- a/test/runtest/baseline/pass.py +++ b/test/runtest/baseline/pass.py @@ -38,7 +38,7 @@ test.write_passing_test(['test', 'pass.py']) # 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 @@ -53,6 +53,6 @@ expect = r"""qmtest.py run --output baseline.qmr --format none --result-stream=s 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() diff --git a/test/runtest/fallback.py b/test/runtest/fallback.py new file mode 100644 index 00000000..90cd4f2c --- /dev/null +++ b/test/runtest/fallback.py @@ -0,0 +1,104 @@ +#!/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() diff --git a/test/runtest/noqmtest.py b/test/runtest/noqmtest.py new file mode 100644 index 00000000..c4421258 --- /dev/null +++ b/test/runtest/noqmtest.py @@ -0,0 +1,94 @@ +#!/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() diff --git a/test/runtest/print_time.py b/test/runtest/print_time.py index 1d86baad..39bf810a 100644 --- a/test/runtest/print_time.py +++ b/test/runtest/print_time.py @@ -29,9 +29,16 @@ Test a combination of a passing test, failing test, and no-result 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') @@ -45,10 +52,10 @@ 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 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 @@ -56,7 +63,7 @@ expect = r"""qmtest.py run --output results.qmr --format none --result-stream=sc Total execution time: \d+\.\d+ seconds - test/no_result.py : NO_RESULT + %(test_no_result_py)s : NO_RESULT NO RESULT TEST STDOUT @@ -64,26 +71,26 @@ expect = r"""qmtest.py run --output results.qmr --format none --result-stream=sc 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() diff --git a/test/runtest/python.py b/test/runtest/python.py index 76eec7dc..1af32ddd 100644 --- a/test/runtest/python.py +++ b/test/runtest/python.py @@ -28,35 +28,40 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" 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 -------------------------------------------------- @@ -70,11 +75,6 @@ expect = r"""qmtest.py run --output results.qmr --format none --result-stream=sc 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() diff --git a/test/runtest/simple/combined.py b/test/runtest/simple/combined.py index 1640d94d..58d2f27d 100644 --- a/test/runtest/simple/combined.py +++ b/test/runtest/simple/combined.py @@ -30,10 +30,16 @@ Test a combination of a passing test, failing test, and no-result 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']) @@ -45,39 +51,39 @@ 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 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() diff --git a/test/runtest/simple/fail.py b/test/runtest/simple/fail.py index ba2cc97a..ec9f5323 100644 --- a/test/runtest/simple/fail.py +++ b/test/runtest/simple/fail.py @@ -38,7 +38,7 @@ test.write_failing_test(['test', 'fail.py']) # 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 @@ -59,6 +59,6 @@ expect = r"""qmtest.py run --output results.qmr --format none --result-stream=sc 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() diff --git a/test/runtest/simple/no_result.py b/test/runtest/simple/no_result.py index 7c9687e4..4ec6e78b 100644 --- a/test/runtest/simple/no_result.py +++ b/test/runtest/simple/no_result.py @@ -36,7 +36,7 @@ test.subdir('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 @@ -57,6 +57,6 @@ expect = r"""qmtest.py run --output results.qmr --format none --result-stream=sc 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() diff --git a/test/runtest/simple/pass.py b/test/runtest/simple/pass.py index 8dfc9964..c3a8b02b 100644 --- a/test/runtest/simple/pass.py +++ b/test/runtest/simple/pass.py @@ -38,7 +38,7 @@ test.write_passing_test(['test', 'pass.py']) # 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 @@ -55,6 +55,6 @@ expect = r"""qmtest.py run --output results.qmr --format none --result-stream=sc 1 (100%) tests PASS """ -test.run(arguments = '--qmtest test/pass.py', stdout = expect) +test.run(arguments = 'test/pass.py', stdout = expect) test.pass_test() diff --git a/test/runtest/src.py b/test/runtest/src.py index 2f723b45..3063a4eb 100644 --- a/test/runtest/src.py +++ b/test/runtest/src.py @@ -29,6 +29,8 @@ Verify that we find tests under the src/ tree only if they end with *Tests.py. """ +import os.path + import TestRuntest test = TestRuntest.TestRuntest(verbose=1) @@ -36,6 +38,9 @@ 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']) @@ -44,15 +49,15 @@ test.write_passing_test(['src', 'suite', 'pass.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 -------------------------------------------------- @@ -63,9 +68,9 @@ expect = r"""qmtest.py run --output results.qmr --format none --result-stream=sc 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() diff --git a/test/runtest/testlistfile.py b/test/runtest/testlistfile.py new file mode 100644 index 00000000..d7385304 --- /dev/null +++ b/test/runtest/testlistfile.py @@ -0,0 +1,77 @@ +#!/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() diff --git a/test/runtest/xml/output.py b/test/runtest/xml/output.py new file mode 100644 index 00000000..e1c14cf7 --- /dev/null +++ b/test/runtest/xml/output.py @@ -0,0 +1,191 @@ +#!/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 = """\ + + __build__='D456' + __buildsys__='another_fake_system' + __date__='Dec 31 1999' + __developer__='John Doe' + __version__='4\\.5\\.6' + +""" + +expect_script = """\ + + __build__='D123' + __buildsys__='fake_system' + __date__='Jan 1 1970' + __developer__='Anonymous' + __version__='1\\.2\\.3' + +""" + +# 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 = """\ + +""" + +expect_os_environ = """\ + +""" + +expect_fail = """\ + + + "1" + + + "<pre>FAILING TEST STDERR%(cr)s +</pre>" + + + "<pre>FAILING TEST STDOUT%(cr)s +</pre>" + + + "Non-zero exit_code\\." + + + "[\\d.]+" + + + "[\\d.]+" + + + "local" + + +""" % locals() + +expect_no_result = """\ + + + "2" + + + "<pre>NO RESULT TEST STDERR%(cr)s +</pre>" + + + "<pre>NO RESULT TEST STDOUT%(cr)s +</pre>" + + + "Non-zero exit_code\\." + + + "[\\d.]+" + + + "[\\d.]+" + + + "local" + + +""" % locals() + +expect_pass = """\ + + + "[\\d.]+" + + + "[\\d.]+" + + + "local" + + +""" % 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() diff --git a/test/same-name.py b/test/same-name.py index 99a0ea5b..8f71ac7c 100644 --- a/test/same-name.py +++ b/test/same-name.py @@ -41,6 +41,8 @@ env.Program(source = ['foo.c', 'bu/bu.c']) """) test.write('foo.c', r""" +#include +#include #include int main(int argc, char *argv[]) @@ -57,6 +59,7 @@ void bu(void); """) test.write(['bu', 'bu.c'], r""" +#include void bu(void) { diff --git a/test/sconsign/script.py b/test/sconsign/script.py index 9e0caa50..d94a956e 100644 --- a/test/sconsign/script.py +++ b/test/sconsign/script.py @@ -91,6 +91,8 @@ env2.Program('sub2/hello.c') """) test.write(['work1', 'sub1', 'hello.c'], r"""\ +#include +#include int main(int argc, char *argv[]) { @@ -101,6 +103,8 @@ main(int argc, char *argv[]) """) test.write(['work1', 'sub2', 'hello.c'], r"""\ +#include +#include #include #include int @@ -283,6 +287,8 @@ env2.Program('sub2/hello.c') """) test.write(['work2', 'sub1', 'hello.c'], r"""\ +#include +#include int main(int argc, char *argv[]) { @@ -293,6 +299,8 @@ main(int argc, char *argv[]) """) test.write(['work2', 'sub2', 'hello.c'], r"""\ +#include +#include #include #include int diff --git a/test/signature-order.py b/test/signature-order.py index 8fb15bf5..6ec839d8 100644 --- a/test/signature-order.py +++ b/test/signature-order.py @@ -65,6 +65,8 @@ env.Program(target = 'foo', source = 'foo.c') """) test.write(['work1', 'foo.c'], r""" +#include +#include #include #include int @@ -98,6 +100,8 @@ env.Program(target = 'foo', source = 'foo.c') """) test.write(['work2', 'foo.c'], r""" +#include +#include #include "aaa.h" #include "bbb.h" int diff --git a/test/silent-command.py b/test/silent-command.py index a5da7a81..91880bd3 100644 --- a/test/silent-command.py +++ b/test/silent-command.py @@ -36,7 +36,7 @@ import sys import TestCmd import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -52,13 +52,13 @@ fp.close() 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") @@ -70,7 +70,7 @@ test.write('f6.in', "f6.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) diff --git a/test/special-filenames.py b/test/special-filenames.py index 98096b7a..11930e51 100644 --- a/test/special-filenames.py +++ b/test/special-filenames.py @@ -30,6 +30,8 @@ import sys import TestSCons +_python_ = TestSCons._python_ + test = TestSCons.TestSCons() attempt_file_names = [ @@ -68,11 +70,13 @@ for fn in 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='.') diff --git a/test/srcchange.py b/test/srcchange.py index ef92aeaa..ac549f6c 100644 --- a/test/srcchange.py +++ b/test/srcchange.py @@ -33,6 +33,8 @@ import os.path import TestSCons +_python_ = TestSCons._python_ + test = TestSCons.TestSCons() test.write('getrevision', """ @@ -59,16 +61,18 @@ SubRevision = Action(subrevision) 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 +#include +#include int main(int argc, char *argv[]) { @@ -82,8 +86,8 @@ test.write('revnum.in', '3.2\n') 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) diff --git a/test/strfunction.py b/test/strfunction.py index a0b23447..62240ee4 100644 --- a/test/strfunction.py +++ b/test/strfunction.py @@ -30,7 +30,7 @@ Test how using strfunction() to report different types of import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -53,12 +53,12 @@ def func(target, source, env): 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' @@ -94,7 +94,7 @@ env = Environment(BUILDERS = { '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') @@ -139,27 +139,27 @@ test.write('dict7.list', "dict7.list\n") 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 diff --git a/test/subclassing.py b/test/subclassing.py index a040dd42..18be1bcc 100644 --- a/test/subclassing.py +++ b/test/subclassing.py @@ -49,6 +49,8 @@ env.Program('hello', 'hello.c') """) test.write('hello.c', """\ +#include +#include int main(int argc, char *argv[]) { printf("hello.c\\n"); diff --git a/test/subdir.py b/test/subdir.py index 03cbed34..991eb233 100644 --- a/test/subdir.py +++ b/test/subdir.py @@ -27,7 +27,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import TestSCons import os.path -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -42,13 +42,13 @@ file.close() """) 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") diff --git a/test/subdivide.py b/test/subdivide.py index 18219bf3..a8169575 100644 --- a/test/subdivide.py +++ b/test/subdivide.py @@ -63,6 +63,8 @@ env.Default(p) """ % TestSCons._obj) test.write('foo.c', """\ +#include +#include void foo(void) { printf("foo.c\\n"); @@ -70,6 +72,8 @@ foo(void) { """) test.write(['src', 'main.c'], """\ +#include +#include extern void foo(void); extern void bar(void); int @@ -82,6 +86,8 @@ main(int argc, char *argv[]) { """) test.write(['src', 'sub', 'bar.c'], """\ +#include +#include void bar(void) { printf("bar.c\\n"); diff --git a/test/symlink/BuildDir.py b/test/symlink/BuildDir.py new file mode 100644 index 00000000..eee0e4d3 --- /dev/null +++ b/test/symlink/BuildDir.py @@ -0,0 +1,64 @@ +#!/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() diff --git a/test/symlink.py b/test/symlink/dangling-include.py similarity index 79% rename from test/symlink.py rename to test/symlink/dangling-include.py index ef7a55c5..b5ea1e0c 100644 --- a/test/symlink.py +++ b/test/symlink/dangling-include.py @@ -25,11 +25,10 @@ __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 @@ -55,18 +54,6 @@ expect = """\ 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() diff --git a/test/symlink/dangling-source.py b/test/symlink/dangling-source.py new file mode 100644 index 00000000..e242e61e --- /dev/null +++ b/test/symlink/dangling-source.py @@ -0,0 +1,53 @@ +#!/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() diff --git a/test/up-to-date.py b/test/up-to-date.py index 460401a1..cec59525 100644 --- a/test/up-to-date.py +++ b/test/up-to-date.py @@ -29,7 +29,7 @@ import string import sys import TestSCons -python = TestSCons.python +_python_ = TestSCons._python_ test = TestSCons.TestSCons() @@ -42,13 +42,13 @@ file.close() """) 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") @@ -57,13 +57,14 @@ test.write('f4.in', "f4.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()