summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam Deegan <bill@baddogconsulting.com>2016-04-09 12:14:38 -0400
committerWilliam Deegan <bill@baddogconsulting.com>2016-04-09 12:14:38 -0400
commit086cf64f45a01d771d41793b1dcf3bf4221315eb (patch)
treefdc68838cd90dbb2b9481340770506bf938cb280
parent0ad6f1e93180e7d708ddf3d76e719e4e1bb1728e (diff)
parentcd026b0638710d4d68f295bba000ed2b3f1cba09 (diff)
downloadscons-086cf64f45a01d771d41793b1dcf3bf4221315eb.tar.gz
Merged in techtonik/scons (pull request #308)
Improve a few docs and messages
-rw-r--r--doc/man/scons.xml10
-rw-r--r--src/Announce.txt8
-rw-r--r--src/CHANGES.txt9
-rw-r--r--src/engine/SCons/CacheDir.py72
-rw-r--r--src/engine/SCons/CacheDirTests.py13
-rw-r--r--src/engine/SCons/Warnings.py4
-rw-r--r--src/script/scons-configure-cache.py139
-rw-r--r--test/Actions/pre-post.py2
-rw-r--r--test/Builder/multi/different-environments.py2
-rw-r--r--test/Builder/multi/same-overrides.py2
-rw-r--r--test/Builder/srcdir.py2
-rw-r--r--test/CacheDir/CacheDir.py3
-rw-r--r--test/CacheDir/environment.py3
-rw-r--r--test/CacheDir/option--cs.py3
-rw-r--r--test/Command.py6
-rw-r--r--test/Configure/Builder-call.py2
-rw-r--r--test/Configure/custom-tests.py4
-rw-r--r--test/Deprecated/SourceCode/BitKeeper/BITKEEPERCOM.py2
-rw-r--r--test/Deprecated/SourceCode/BitKeeper/BITKEEPERCOMSTR.py2
-rw-r--r--test/Deprecated/SourceCode/CVS/CVSCOM.py2
-rw-r--r--test/Deprecated/SourceCode/CVS/CVSCOMSTR.py2
-rw-r--r--test/Deprecated/SourceCode/Perforce/P4COM.py2
-rw-r--r--test/Deprecated/SourceCode/Perforce/P4COMSTR.py2
-rw-r--r--test/Deprecated/SourceCode/RCS/RCS_COCOM.py2
-rw-r--r--test/Deprecated/SourceCode/RCS/RCS_COCOMSTR.py2
-rw-r--r--test/Deprecated/SourceCode/SCCS/SCCSCOM.py2
-rw-r--r--test/Deprecated/SourceCode/SCCS/SCCSCOMSTR.py2
-rw-r--r--test/ESCAPE.py2
-rw-r--r--test/Execute.py16
-rw-r--r--test/MSVC/batch.py4
-rw-r--r--test/Parallel/duplicate-children.py4
-rw-r--r--test/SConsignFile/default.py2
-rw-r--r--test/SConsignFile/explicit-file.py2
-rw-r--r--test/SConsignFile/use-dbhash.py2
-rw-r--r--test/SConsignFile/use-dumbdbm.py2
-rw-r--r--test/file-names.py109
-rw-r--r--test/ignore-command.py14
-rw-r--r--test/option/debug-findlibs.py2
-rw-r--r--test/redirection.py8
-rw-r--r--test/silent-command.py14
-rw-r--r--test/special-filenames.py2
-rw-r--r--test/srcchange.py2
-rw-r--r--test/subdir.py2
43 files changed, 381 insertions, 110 deletions
diff --git a/doc/man/scons.xml b/doc/man/scons.xml
index c72178e4..4db5abb1 100644
--- a/doc/man/scons.xml
+++ b/doc/man/scons.xml
@@ -1707,6 +1707,16 @@ specifies the type of warnings to be enabled or disabled:</para>
</listitem>
</varlistentry>
<varlistentry>
+ <term>--warn=cache-version, --warn=no-cache-version</term>
+ <listitem>
+<para>Enables or disables warnings about the cache directory not using
+the latest configuration information
+<emphasis role="bold">CacheDir</emphasis>().
+These warnings are enabled by default.</para>
+
+ </listitem>
+ </varlistentry>
+ <varlistentry>
<term>--warn=cache-write-error, --warn=no-cache-write-error</term>
<listitem>
<para>Enables or disables warnings about errors trying to
diff --git a/src/Announce.txt b/src/Announce.txt
index c20d7dfd..0b589582 100644
--- a/src/Announce.txt
+++ b/src/Announce.txt
@@ -44,6 +44,12 @@ Notes:
a scanner found in SCANNERS (but not for built-in scanners), but now
the Install builder will not scan recursively regardless in order
to optimize Install behaviour and bring orthogonality to previous behaviour.
+* SCons handles cache directories a bit differently/
+** Cache files are now stored in 256 subdirectories in the cache directory by
+ default (this stresses NFS less). Existing cache directories will remain as
+ current, but SCons will prompt you to run scons-configure-cache which will
+ allow you to migrate to the new layout, or confirm you want to use the
+ existing layout.
+=================================================================
@@ -56,6 +62,8 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER
changes.
Please note the following important changes since release 2.4.0:
+ - New external tool scons-configurecache which allows some configuration of
+ how files in the cache are controlled.
- Fix to swig tool - pick-up 'swig', 'swig3.0' and 'swig2.0' (in order).
- Fix to swig tool - respect env['SWIG'] provided by user.
- Fix for Bug # 2791 - Setup.py fails unnecessarily under Jython.
diff --git a/src/CHANGES.txt b/src/CHANGES.txt
index 08317876..3d2cf1c3 100644
--- a/src/CHANGES.txt
+++ b/src/CHANGES.txt
@@ -6,6 +6,15 @@
RELEASE VERSION/DATE TO BE FILLED IN LATER
+ From Tom Tanner:
+ - change cache to use 2 character subdirectories, rather than one character,
+ so as not to give huge directories for large caches, a situation which
+ causes issues for NFS.
+ For existing caches, you will need to run the scons-configure-cache.py
+ script to update them to the new format. You will get a warning every time
+ you build until you co this.
+ - Fix a bunch of unit tests on windows
+
From Dirk Baechle:
- Removed a lot of compatibility methods and workarounds
for Python versions < 2.7, in order to prepare the work
diff --git a/src/engine/SCons/CacheDir.py b/src/engine/SCons/CacheDir.py
index 3b7d06fe..16906741 100644
--- a/src/engine/SCons/CacheDir.py
+++ b/src/engine/SCons/CacheDir.py
@@ -27,7 +27,8 @@ __doc__ = """
CacheDir support
"""
-import os.path
+import json
+import os
import stat
import sys
@@ -72,7 +73,8 @@ CacheRetrieve = SCons.Action.Action(CacheRetrieveFunc, CacheRetrieveString)
CacheRetrieveSilent = SCons.Action.Action(CacheRetrieveFunc, None)
def CachePushFunc(target, source, env):
- if cache_readonly: return
+ if cache_readonly:
+ return
t = target[0]
if t.nocache:
@@ -125,6 +127,10 @@ def CachePushFunc(target, source, env):
CachePush = SCons.Action.Action(CachePushFunc, None)
+# Nasty hack to cut down to one warning for each cachedir path that needs
+# upgrading.
+warned = dict()
+
class CacheDir(object):
def __init__(self, path):
@@ -133,11 +139,63 @@ class CacheDir(object):
except ImportError:
msg = "No hashlib or MD5 module available, CacheDir() not supported"
SCons.Warnings.warn(SCons.Warnings.NoMD5ModuleWarning, msg)
- self.path = None
- else:
- self.path = path
+ path = None
+ self.path = path
self.current_cache_debug = None
self.debugFP = None
+ self.config = dict()
+ if path is None:
+ return
+ # See if there's a config file in the cache directory. If there is,
+ # use it. If there isn't, and the directory exists and isn't empty,
+ # produce a warning. If the directory doesn't exist or is empty,
+ # write a config file.
+ config_file = os.path.join(path, 'config')
+ if not os.path.exists(config_file):
+ # A note: There is a race hazard here, if two processes start and
+ # attempt to create the cache directory at the same time. However,
+ # python doesn't really give you the option to do exclusive file
+ # creation (it doesn't even give you the option to error on opening
+ # an existing file for writing...). The ordering of events here
+ # as an attempt to alleviate this, on the basis that it's a pretty
+ # unlikely occurence (it'd require two builds with a brand new cache
+ # directory)
+ if os.path.isdir(path) and len(os.listdir(path)) != 0:
+ self.config['prefix_len'] = 1
+ # When building the project I was testing this on, the warning
+ # was output over 20 times. That seems excessive
+ global warned
+ if self.path not in warned:
+ msg = "Please upgrade your cache by running " +\
+ " scons-configure-cache.py " + self.path
+ SCons.Warnings.warn(SCons.Warnings.CacheVersionWarning, msg)
+ warned[self.path] = True
+ else:
+ if not os.path.isdir(path):
+ try:
+ os.makedirs(path)
+ except OSError:
+ # If someone else is trying to create the directory at
+ # the same time as me, bad things will happen
+ msg = "Failed to create cache directory " + path
+ raise SCons.Errors.EnvironmentError(msg)
+
+ self.config['prefix_len'] = 2
+ if not os.path.exists(config_file):
+ try:
+ with open(config_file, 'w') as config:
+ json.dump(self.config, config)
+ except:
+ msg = "Failed to write cache configuration for " + path
+ raise SCons.Errors.EnvironmentError(msg)
+ else:
+ try:
+ with open(config_file) as config:
+ self.config = json.load(config)
+ except ValueError:
+ msg = "Failed to read cache configuration for " + path
+ raise SCons.Errors.EnvironmentError(msg)
+
def CacheDebug(self, fmt, target, cachefile):
if cache_debug != self.current_cache_debug:
@@ -152,7 +210,7 @@ class CacheDir(object):
self.debugFP.write(fmt % (target, os.path.split(cachefile)[1]))
def is_enabled(self):
- return (cache_enabled and not self.path is None)
+ return cache_enabled and not self.path is None
def is_readonly(self):
return cache_readonly
@@ -164,7 +222,7 @@ class CacheDir(object):
return None, None
sig = node.get_cachedir_bsig()
- subdir = sig[0].upper()
+ subdir = sig[:self.config['prefix_len']].upper()
dir = os.path.join(self.path, subdir)
return dir, os.path.join(dir, sig)
diff --git a/src/engine/SCons/CacheDirTests.py b/src/engine/SCons/CacheDirTests.py
index 7ac97efa..82fba8fc 100644
--- a/src/engine/SCons/CacheDirTests.py
+++ b/src/engine/SCons/CacheDirTests.py
@@ -83,6 +83,11 @@ class BaseTestCase(unittest.TestCase):
#node.binfo.ninfo.bsig = bsig
return node
+ def tearDown(self):
+ os.remove(os.path.join(self._CacheDir.path, 'config'))
+ os.rmdir(self._CacheDir.path)
+ # Should that be shutil.rmtree?
+
class CacheDirTestCase(BaseTestCase):
"""
Test calling CacheDir code directly.
@@ -98,10 +103,12 @@ class CacheDirTestCase(BaseTestCase):
SCons.Util.MD5collect = my_collect
try:
- f5 = self.File("cd.f5", 'a_fake_bsig')
+ name = 'a_fake_bsig'
+ f5 = self.File("cd.f5", name)
result = self._CacheDir.cachepath(f5)
- dirname = os.path.join('cache', 'A')
- filename = os.path.join(dirname, 'a_fake_bsig')
+ len = self._CacheDir.config['prefix_len']
+ dirname = os.path.join('cache', name.upper()[:len])
+ filename = os.path.join(dirname, name)
assert result == (dirname, filename), result
finally:
SCons.Util.MD5collect = save_collect
diff --git a/src/engine/SCons/Warnings.py b/src/engine/SCons/Warnings.py
index 5c278252..2495b89c 100644
--- a/src/engine/SCons/Warnings.py
+++ b/src/engine/SCons/Warnings.py
@@ -41,10 +41,12 @@ class WarningOnByDefault(Warning):
# NOTE: If you add a new warning class, add it to the man page, too!
-
class TargetNotBuiltWarning(Warning): # Should go to OnByDefault
pass
+class CacheVersionWarning(WarningOnByDefault):
+ pass
+
class CacheWriteErrorWarning(Warning):
pass
diff --git a/src/script/scons-configure-cache.py b/src/script/scons-configure-cache.py
new file mode 100644
index 00000000..c1b7d591
--- /dev/null
+++ b/src/script/scons-configure-cache.py
@@ -0,0 +1,139 @@
+#! /usr/bin/env python
+#
+# SCons - a Software Constructor
+#
+# __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__"
+
+__version__ = "__VERSION__"
+
+__build__ = "__BUILD__"
+
+__buildsys__ = "__BUILDSYS__"
+
+__date__ = "__DATE__"
+
+__developer__ = "__DEVELOPER__"
+
+import argparse
+import glob
+import json
+import os
+
+def rearrange_cache_entries(current_prefix_len, new_prefix_len):
+ print 'Changing prefix length from', current_prefix_len, 'to', new_prefix_len
+ dirs = set()
+ old_dirs = set()
+ for file in glob.iglob(os.path.join('*', '*')):
+ name = os.path.basename(file)
+ dir = name[:current_prefix_len].upper()
+ if dir not in old_dirs:
+ print 'Migrating', dir
+ old_dirs.add(dir)
+ dir = name[:new_prefix_len].upper()
+ if dir not in dirs:
+ os.mkdir(dir)
+ dirs.add(dir)
+ os.rename(file, os.path.join(dir, name))
+
+ # Now delete the original directories
+ for dir in old_dirs:
+ os.rmdir(dir)
+
+# This dictionary should have one entry per entry in the cache config
+# Each entry should have the following:
+# implicit - (optional) This is to allow adding a new config entry and also
+# changing the behaviour of the system at the same time. This
+# indicates the value the config entry would have had if it had been
+# specified.
+# default - The value the config entry should have if it wasn't previously
+# specified
+# command-line - parameters to pass to ArgumentParser.add_argument
+# converter - (optional) Function to call if it's necessary to do some work
+# if this configuration entry changes
+config_entries = {
+ 'prefix_len' : {
+ 'implicit' : 1,
+ 'default' : 2 ,
+ 'command-line' : {
+ 'help' : 'Length of cache file name used as subdirectory prefix',
+ 'metavar' : '<number>',
+ 'type' : int
+ },
+ 'converter' : rearrange_cache_entries
+ }
+}
+parser = argparse.ArgumentParser(
+ description = 'Modify the configuration of an scons cache directory',
+ epilog = '''
+ Unless you specify an option, it will not be changed (if it is
+ already set in the cache config), or changed to an appropriate
+ default (it it is not set).
+ '''
+ )
+
+parser.add_argument('cache-dir', help='Path to scons cache directory')
+for param in config_entries:
+ parser.add_argument('--' + param.replace('_', '-'),
+ **config_entries[param]['command-line'])
+parser.add_argument('--version', action='version', version='%(prog)s 1.0')
+
+# Get the command line as a dict without any of the unspecified entries.
+args = dict(filter(lambda x: x[1], vars(parser.parse_args()).items()))
+
+# It seems somewhat strange to me, but positional arguments don't get the -
+# in the name changed to _, whereas optional arguments do...
+os.chdir(args['cache-dir'])
+del args['cache-dir']
+
+if not os.path.exists('config'):
+ # Validate the only files in the directory are directories 0-9, a-f
+ expected = [ '{:X}'.format(x) for x in range(0, 16) ]
+ if not set(os.listdir('.')).issubset(expected):
+ raise RuntimeError("This doesn't look like a version 1 cache directory")
+ config = dict()
+else:
+ with open('config') as conf:
+ config = json.load(conf)
+
+# Find any keys that aren't currently set but should be
+for key in config_entries:
+ if key not in config:
+ if 'implicit' in config_entries[key]:
+ config[key] = config_entries[key]['implicit']
+ else:
+ config[key] = config_entries[key]['default']
+ if key not in args:
+ args[key] = config_entries[key]['default']
+
+#Now we go through each entry in args to see if it changes an existing config
+#setting.
+for key in args:
+ if args[key] != config[key]:
+ if 'converter' in config_entries[key]:
+ config_entries[key]['converter'](config[key], args[key])
+ config[key] = args[key]
+
+# and write the updated config file
+with open('config', 'w') as conf:
+ json.dump(config, conf) \ No newline at end of file
diff --git a/test/Actions/pre-post.py b/test/Actions/pre-post.py
index e09ee028..38a55dfa 100644
--- a/test/Actions/pre-post.py
+++ b/test/Actions/pre-post.py
@@ -188,7 +188,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')
+ r'%(_python_)s build.py ${TARGETS[1]} $SOURCE')
env.AddPreAction(o, pre_action)
env.AddPostAction(o, post_action)
""" % locals())
diff --git a/test/Builder/multi/different-environments.py b/test/Builder/multi/different-environments.py
index 783b7f9d..c3e96c2c 100644
--- a/test/Builder/multi/different-environments.py
+++ b/test/Builder/multi/different-environments.py
@@ -47,7 +47,7 @@ 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=r'%(_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)
diff --git a/test/Builder/multi/same-overrides.py b/test/Builder/multi/same-overrides.py
index 33c4e7bb..ee169e45 100644
--- a/test/Builder/multi/same-overrides.py
+++ b/test/Builder/multi/same-overrides.py
@@ -45,7 +45,7 @@ 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=r'%(_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)
diff --git a/test/Builder/srcdir.py b/test/Builder/srcdir.py
index 63732d7a..669c5e1a 100644
--- a/test/Builder/srcdir.py
+++ b/test/Builder/srcdir.py
@@ -50,7 +50,7 @@ o.close()
test.write(['src', 'SConstruct'], """\
Command('output',
['file1', File('file2'), r'%(file3)s', 'file4'],
- '%(_python_)s cat.py $TARGET $SOURCES',
+ r'%(_python_)s cat.py $TARGET $SOURCES',
srcdir='foo')
""" % locals())
diff --git a/test/CacheDir/CacheDir.py b/test/CacheDir/CacheDir.py
index 9abe0e05..4c05634e 100644
--- a/test/CacheDir/CacheDir.py
+++ b/test/CacheDir/CacheDir.py
@@ -82,7 +82,8 @@ 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)))
+# Even if you do -n, the cache will be configured.
+test.fail_test(os.listdir(cache) != ['config'])
# Verify that a normal build works correctly, and clean up.
# This should populate the cache with our derived files.
diff --git a/test/CacheDir/environment.py b/test/CacheDir/environment.py
index 4fb9b51f..1378bb28 100644
--- a/test/CacheDir/environment.py
+++ b/test/CacheDir/environment.py
@@ -85,7 +85,8 @@ 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)))
+# Even if you do -n, the cache will be configured.
+test.fail_test(os.listdir(cache) != ['config'])
# Verify that a normal build works correctly, and clean up.
# This should populate the cache with our derived files.
diff --git a/test/CacheDir/option--cs.py b/test/CacheDir/option--cs.py
index b6bb52a2..6d228141 100644
--- a/test/CacheDir/option--cs.py
+++ b/test/CacheDir/option--cs.py
@@ -35,6 +35,7 @@ import shutil
import TestSCons
_python_ = TestSCons._python_
+
_exe = TestSCons._exe
_obj = TestSCons._obj
@@ -62,7 +63,7 @@ def cat(env, source, target):
f.write(open(str(src), "rb").read())
f.close()
env = Environment(BUILDERS={'Internal':Builder(action=cat),
- 'External':Builder(action='%(_python_)s build.py $TARGET $SOURCES')})
+ 'External':Builder(action=r'%(_python_)s build.py $TARGET $SOURCES')})
env.External('aaa.out', 'aaa.in')
env.External('bbb.out', 'bbb.in')
env.Internal('ccc.out', 'ccc.in')
diff --git a/test/Command.py b/test/Command.py
index 74046b10..5f72c94b 100644
--- a/test/Command.py
+++ b/test/Command.py
@@ -63,15 +63,15 @@ 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',
+env = Environment(COPY_THROUGH_TEMP = r'%(_python_)s build.py .tmp $SOURCE' + '\\n' + r'%(_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')
env.Command(target = 'f3.out', source = 'f3.in',
- action = [ [ r'%(python)s', 'build.py', 'temp3', '$SOURCES' ],
- [ r'%(python)s', 'build.py', '$TARGET', 'temp3'] ])
+ 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')
diff --git a/test/Configure/Builder-call.py b/test/Configure/Builder-call.py
index 037a2c77..b85b0398 100644
--- a/test/Configure/Builder-call.py
+++ b/test/Configure/Builder-call.py
@@ -48,7 +48,7 @@ def CustomTest(*args):
return 0
conf = env.Configure(custom_tests = {'MyTest' : CustomTest})
if not conf.MyTest():
- env.Command("hello", [], '%(_python_)s mycommand.py $TARGET')
+ env.Command("hello", [], r'%(_python_)s mycommand.py $TARGET')
env = conf.Finish()
""" % locals())
diff --git a/test/Configure/custom-tests.py b/test/Configure/custom-tests.py
index 687ba489..503eb4e4 100644
--- a/test/Configure/custom-tests.py
+++ b/test/Configure/custom-tests.py
@@ -63,8 +63,8 @@ def CheckCustom(test):
retLinkFAIL = test.TryLink( '%(linkFAIL)s', '.c' )
(retRunOK, outputRunOK) = test.TryRun( '%(runOK)s', '.c' )
(retRunFAIL, outputRunFAIL) = test.TryRun( '%(runFAIL)s', '.c' )
- (retActOK, outputActOK) = test.TryAction( '%(_python_)s pyAct.py 0 > $TARGET' )
- (retActFAIL, outputActFAIL) = test.TryAction( '%(_python_)s pyAct.py 1 > $TARGET' )
+ (retActOK, outputActOK) = test.TryAction( r'%(_python_)s pyAct.py 0 > $TARGET' )
+ (retActFAIL, outputActFAIL) = test.TryAction( r'%(_python_)s pyAct.py 1 > $TARGET' )
resOK = retCompileOK and retLinkOK and retRunOK and outputRunOK=="Hello"
resOK = resOK and retActOK and int(outputActOK)==0
resFAIL = retCompileFAIL or retLinkFAIL or retRunFAIL or outputRunFAIL!=""
diff --git a/test/Deprecated/SourceCode/BitKeeper/BITKEEPERCOM.py b/test/Deprecated/SourceCode/BitKeeper/BITKEEPERCOM.py
index d5af0ea0..8ff4cedd 100644
--- a/test/Deprecated/SourceCode/BitKeeper/BITKEEPERCOM.py
+++ b/test/Deprecated/SourceCode/BitKeeper/BITKEEPERCOM.py
@@ -74,7 +74,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=r'%(_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')
diff --git a/test/Deprecated/SourceCode/BitKeeper/BITKEEPERCOMSTR.py b/test/Deprecated/SourceCode/BitKeeper/BITKEEPERCOMSTR.py
index ef70cb82..5bbdea20 100644
--- a/test/Deprecated/SourceCode/BitKeeper/BITKEEPERCOMSTR.py
+++ b/test/Deprecated/SourceCode/BitKeeper/BITKEEPERCOMSTR.py
@@ -74,7 +74,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=r'%(_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/Deprecated/SourceCode/CVS/CVSCOM.py b/test/Deprecated/SourceCode/CVS/CVSCOM.py
index a0f84000..f3bd29d8 100644
--- a/test/Deprecated/SourceCode/CVS/CVSCOM.py
+++ b/test/Deprecated/SourceCode/CVS/CVSCOM.py
@@ -74,7 +74,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=r'%(_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')
diff --git a/test/Deprecated/SourceCode/CVS/CVSCOMSTR.py b/test/Deprecated/SourceCode/CVS/CVSCOMSTR.py
index f793d662..483a0ae2 100644
--- a/test/Deprecated/SourceCode/CVS/CVSCOMSTR.py
+++ b/test/Deprecated/SourceCode/CVS/CVSCOMSTR.py
@@ -74,7 +74,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=r'%(_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/Deprecated/SourceCode/Perforce/P4COM.py b/test/Deprecated/SourceCode/Perforce/P4COM.py
index 9b9bab1e..e58cb606 100644
--- a/test/Deprecated/SourceCode/Perforce/P4COM.py
+++ b/test/Deprecated/SourceCode/Perforce/P4COM.py
@@ -74,7 +74,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=r'%(_python_)s my-p4.py $TARGET')
env.Cat('aaa.out', 'aaa.in')
env.Cat('bbb.out', 'bbb.in')
env.Cat('ccc.out', 'ccc.in')
diff --git a/test/Deprecated/SourceCode/Perforce/P4COMSTR.py b/test/Deprecated/SourceCode/Perforce/P4COMSTR.py
index 7a240210..7b2fbba2 100644
--- a/test/Deprecated/SourceCode/Perforce/P4COMSTR.py
+++ b/test/Deprecated/SourceCode/Perforce/P4COMSTR.py
@@ -75,7 +75,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=r'%(_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/Deprecated/SourceCode/RCS/RCS_COCOM.py b/test/Deprecated/SourceCode/RCS/RCS_COCOM.py
index 765c88cb..c5934ace 100644
--- a/test/Deprecated/SourceCode/RCS/RCS_COCOM.py
+++ b/test/Deprecated/SourceCode/RCS/RCS_COCOM.py
@@ -74,7 +74,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=r'%(_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')
diff --git a/test/Deprecated/SourceCode/RCS/RCS_COCOMSTR.py b/test/Deprecated/SourceCode/RCS/RCS_COCOMSTR.py
index 57088fa6..cb542027 100644
--- a/test/Deprecated/SourceCode/RCS/RCS_COCOMSTR.py
+++ b/test/Deprecated/SourceCode/RCS/RCS_COCOMSTR.py
@@ -74,7 +74,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=r'%(_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/Deprecated/SourceCode/SCCS/SCCSCOM.py b/test/Deprecated/SourceCode/SCCS/SCCSCOM.py
index 6ad02ac1..ba89d87c 100644
--- a/test/Deprecated/SourceCode/SCCS/SCCSCOM.py
+++ b/test/Deprecated/SourceCode/SCCS/SCCSCOM.py
@@ -74,7 +74,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=r'%(_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')
diff --git a/test/Deprecated/SourceCode/SCCS/SCCSCOMSTR.py b/test/Deprecated/SourceCode/SCCS/SCCSCOMSTR.py
index a7574955..2351c059 100644
--- a/test/Deprecated/SourceCode/SCCS/SCCSCOMSTR.py
+++ b/test/Deprecated/SourceCode/SCCS/SCCSCOMSTR.py
@@ -74,7 +74,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=r'%(_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/ESCAPE.py b/test/ESCAPE.py
index 0651b92d..819d60b0 100644
--- a/test/ESCAPE.py
+++ b/test/ESCAPE.py
@@ -51,7 +51,7 @@ def my_escape(s):
s = s.replace('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', r'%(_python_)s cat.py $TARGET $SOURCES')
""" % locals())
test.write('file.in', "file.in\n")
diff --git a/test/Execute.py b/test/Execute.py
index 2e534447..e63cad5a 100644
--- a/test/Execute.py
+++ b/test/Execute.py
@@ -45,18 +45,18 @@ sys.exit(exitval)
""")
test.write('SConstruct', """\
-Execute('%(_python_)s my_copy.py a.in a.out')
-Execute(Action('%(_python_)s my_copy.py b.in b.out'))
+Execute(r'%(_python_)s my_copy.py a.in a.out')
+Execute(Action(r'%(_python_)s my_copy.py b.in b.out'))
env = Environment(COPY = 'my_copy.py')
-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')
+env.Execute(r'%(_python_)s my_copy.py c.in c.out')
+env.Execute(Action(r'%(_python_)s my_copy.py d.in d.out'))
+v = env.Execute(r'%(_python_)s $COPY e.in e.out')
assert v == 0, v
-v = env.Execute(Action('%(_python_)s $COPY f.in f.out'))
+v = env.Execute(Action(r'%(_python_)s $COPY f.in f.out'))
assert v == 0, v
-v = env.Execute('%(_python_)s $COPY g.in g.out 1')
+v = env.Execute(r'%(_python_)s $COPY g.in g.out 1')
assert v == 1, v
-v = env.Execute(Action('%(_python_)s $COPY h.in h.out 2'))
+v = env.Execute(Action(r'%(_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'))
diff --git a/test/MSVC/batch.py b/test/MSVC/batch.py
index fbb32180..86482926 100644
--- a/test/MSVC/batch.py
+++ b/test/MSVC/batch.py
@@ -72,8 +72,8 @@ for infile in sys.argv[2:]:
""")
test.write('SConstruct', """
-cccom = '%(_python_)s fake_cl.py $_MSVC_OUTPUT_FLAG $CHANGED_SOURCES'
-linkcom = '%(_python_)s fake_link.py ${TARGET.windows} $SOURCES'
+cccom = r'%(_python_)s fake_cl.py $_MSVC_OUTPUT_FLAG $CHANGED_SOURCES'
+linkcom = r'%(_python_)s fake_link.py ${TARGET.windows} $SOURCES'
env = Environment(tools=['msvc', 'mslink'],
CCCOM=cccom,
LINKCOM=linkcom,
diff --git a/test/Parallel/duplicate-children.py b/test/Parallel/duplicate-children.py
index c6c5c295..8b8f4cd1 100644
--- a/test/Parallel/duplicate-children.py
+++ b/test/Parallel/duplicate-children.py
@@ -53,8 +53,8 @@ test.write('SConstruct', """
# Test case for SCons issue #1608
# Create a file "foo.in" in the current directory before running scons.
env = Environment()
-env.Command('foo.out', ['foo.in'], '%(_python_)s cat.py $TARGET $SOURCE && %(_python_)s sleep.py 3')
-env.Command('foobar', ['foo.out'], '%(_python_)s cat.py $TARGET $SOURCES')
+env.Command('foo.out', ['foo.in'], r'%(_python_)s cat.py $TARGET $SOURCE && %(_python_)s sleep.py 3')
+env.Command('foobar', ['foo.out'], r'%(_python_)s cat.py $TARGET $SOURCES')
env.Depends('foobar', 'foo.out')
""" % locals())
diff --git a/test/SConsignFile/default.py b/test/SConsignFile/default.py
index f38aec8d..4d56a5ee 100644
--- a/test/SConsignFile/default.py
+++ b/test/SConsignFile/default.py
@@ -49,7 +49,7 @@ sys.exit(0)
#
test.write('SConstruct', """
SConsignFile()
-B = Builder(action = '%(_python_)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')
diff --git a/test/SConsignFile/explicit-file.py b/test/SConsignFile/explicit-file.py
index 33963c27..90c22417 100644
--- a/test/SConsignFile/explicit-file.py
+++ b/test/SConsignFile/explicit-file.py
@@ -49,7 +49,7 @@ file.close()
test.write('SConstruct', """
e = Environment(XXX = 'scons')
e.SConsignFile('my_${XXX}ign')
-B = Builder(action = '%(_python_)s build.py $TARGETS $SOURCES')
+B = Builder(action = r'%(_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')
diff --git a/test/SConsignFile/use-dbhash.py b/test/SConsignFile/use-dbhash.py
index 45e3e36f..bf9868b6 100644
--- a/test/SConsignFile/use-dbhash.py
+++ b/test/SConsignFile/use-dbhash.py
@@ -55,7 +55,7 @@ test.write('SConstruct', """
import sys
import dbhash
SConsignFile('.sconsign', dbhash)
-B = Builder(action = '%(_python_)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')
diff --git a/test/SConsignFile/use-dumbdbm.py b/test/SConsignFile/use-dumbdbm.py
index 9d48fe5d..434435ab 100644
--- a/test/SConsignFile/use-dumbdbm.py
+++ b/test/SConsignFile/use-dumbdbm.py
@@ -55,7 +55,7 @@ test.write('SConstruct', """
import sys
import dumbdbm
SConsignFile('.sconsign', dumbdbm)
-B = Builder(action = '%(_python_)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')
diff --git a/test/file-names.py b/test/file-names.py
index 95b4e4ec..d9f9c639 100644
--- a/test/file-names.py
+++ b/test/file-names.py
@@ -24,6 +24,7 @@
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+import sys
import TestSCons
test = TestSCons.TestSCons()
@@ -38,56 +39,90 @@ test = TestSCons.TestSCons()
# parsing and interpretation of redirection and piping. But that
# means we have to find ways to work with *all* of their quoting
# conventions.
-#
-# Until we sort that all out, short-circuit this test so we can
-# check it in and avoid having to re-invent this wheel later.
-test.pass_test()
def contents(c):
return "|" + c + "|\n"
+invalid_chars = '/\0'
+
if sys.platform == 'win32':
- def bad_char(c):
- return c in '/\\:'
-else:
- def bad_char(c):
- return c in '/'
+ invalid_chars = set(invalid_chars)
-# Only worry about ASCII characters right now.
-# Someone with more Unicode knowledge should enhance this later.
-for i in range(1, 255):
- c = chr(i)
- if not bad_char(c):
- test.write("in" + c + "in", contents(c))
+ # See the 'naming conventions' section of
+ # https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx
+ invalid_chars.update([ chr(c) for c in range(32) ])
+ invalid_chars.update(r'\/:*?"<>|')
+ invalid_chars.update(chr(127))
-test.write('SConstruct', r"""
-import sys
-if sys.platform == 'win32':
+ # Win32 filesystems are case insensitive so don't do half the alphabet.
+ import string
+ invalid_chars.update(string.lowercase)
+
+ # See the 'naming conventions' section of
+ # https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx
def bad_char(c):
- return (c == '/' or c == '\\' or c == ':')
+ return c in invalid_chars
+ def invalid_leading_char(c):
+ # the hash character as a leading character is interpreted to mean the project root
+ return c in ' #'
+ def invalid_trailing_char(c):
+ return c in ' .'
+ commandString = "copy $SOURCE $TARGET"
else:
+ invalid_chars = set(invalid_chars)
+ invalid_chars.add(chr(10))
+ invalid_chars.add(chr(13))
+ invalid_chars.add(chr(92)) # forward slash (dirsep)
+ invalid_chars.add(chr(96)) # backtick
+
+
def bad_char(c):
- return (c == '/')
-env = Environment()
-for i in range(1, 255):
- c = chr(i)
- if not bad_char(c):
- if c in '$':
- c = '\\' + c
- infile = "in" + c + "in"
- env.Command(c + "out", infile, "cp $SOURCE $TARGET")
- env.Command("out" + c + "out", infile, "cp $SOURCE $TARGET")
- env.Command("out" + c, infile, "cp $SOURCE $TARGET")
-""")
+ return c in invalid_chars
+ def invalid_leading_char(c):
+ # the hash character as a leading character is interpreted to mean the project root
+ return c in '#'
+ def invalid_trailing_char(c):
+ return False
+ commandString = "cp $SOURCE $TARGET"
+
+goodChars = [ chr(c) for c in range(1, 128) if not bad_char(chr(c)) ]
+
+def get_filename(ftype,c):
+ return ftype+"%d"%ord(c[-1])+c+ftype
+
+for c in goodChars:
+ test.write(get_filename("in",c), contents(c))
+
+def create_command(a, b, c):
+ a = ('', 'out')[a]
+ b = ('', 'out')[b]
+ return 'env.Command("' + a + get_filename('',c) + b + '", "'+get_filename("in",c)+ '","' + commandString + '")'
+
+sconstruct = [ 'import sys', 'env = Environment()' ]
+for c in goodChars:
+ if c == '$':
+ c = '$$'
+ if c == '"':
+ c = r'\"'
+ infile = get_filename("in",c)
+ if not invalid_leading_char(c):
+ sconstruct.append(create_command(False, True, c))
+ sconstruct.append(create_command(True, True, c))
+ if not invalid_trailing_char(c):
+ sconstruct.append(create_command(True, False, c))
+test.write('SConstruct', '\n'.join(sconstruct))
test.run(arguments = '.')
-for i in range(1, 255):
- c = chr(i)
- if not bad_char(c):
- test.fail_test(test.read(c + "out") != contents(c))
- test.fail_test(test.read("out" + c + "out") != contents(c))
- test.fail_test(test.read("out" + c) != contents(c))
+for c in goodChars:
+# print "Checking %d "%ord(c)
+
+ c_str = ("%d"%ord(c[-1]))+c
+ if not invalid_leading_char(c):
+ test.fail_test(test.read(c_str + "out") != contents(c))
+ test.fail_test(test.read("out" + c_str + "out") != contents(c))
+ if not invalid_trailing_char(c):
+ test.fail_test(test.read("out" + c_str) != contents(c))
test.pass_test()
diff --git a/test/ignore-command.py b/test/ignore-command.py
index 13431455..9fd24abe 100644
--- a/test/ignore-command.py
+++ b/test/ignore-command.py
@@ -49,13 +49,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', r'%(_python_)s build.py $TARGET $SOURCE')
+f2 = env.Command('f2.out', 'f2.in', r'-%(_python_)s build.py $TARGET $SOURCE')
+f3 = env.Command('f3.out', 'f3.in', r'- %(_python_)s build.py $TARGET $SOURCE')
+f4 = env.Command('f4.out', 'f4.in', r'@-%(_python_)s build.py $TARGET $SOURCE')
+f5 = env.Command('f5.out', 'f5.in', r'@- %(_python_)s build.py $TARGET $SOURCE')
+f6 = env.Command('f6.out', 'f6.in', r'-@%(_python_)s build.py $TARGET $SOURCE')
+f7 = env.Command('f7.out', 'f7.in', r'-@ %(_python_)s build.py $TARGET $SOURCE')
Default(f2, f3, f4, f5, f6, f7)
""" % locals())
diff --git a/test/option/debug-findlibs.py b/test/option/debug-findlibs.py
index ce971998..9d5c82ab 100644
--- a/test/option/debug-findlibs.py
+++ b/test/option/debug-findlibs.py
@@ -47,7 +47,7 @@ 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 = r'%(_python_)s cat.py $TARGET $SOURCES')
env.Program('foo', 'a.ooo',)
""" % locals())
diff --git a/test/redirection.py b/test/redirection.py
index 55ffeaeb..98bfc04d 100644
--- a/test/redirection.py
+++ b/test/redirection.py
@@ -43,13 +43,13 @@ sys.exit(0)
test.write('SConstruct', r"""
env = Environment()
env.Command(target='foo1', source='bar1',
- action= '%(_python_)s cat.py $SOURCES > $TARGET')
+ action= r'%(_python_)s cat.py $SOURCES > $TARGET')
env.Command(target='foo2', source='bar2',
- action= '%(_python_)s cat.py < $SOURCES > $TARGET')
+ action= r'%(_python_)s cat.py < $SOURCES > $TARGET')
env.Command(target='foo3', source='bar3',
- action='%(_python_)s cat.py $SOURCES | %(_python_)s cat.py > $TARGET')
+ action=r'%(_python_)s cat.py $SOURCES | %(_python_)s cat.py > $TARGET')
env.Command(target='foo4', source='bar4',
- action='%(_python_)s cat.py <$SOURCES |%(_python_)s cat.py >$TARGET')
+ action=r'%(_python_)s cat.py <$SOURCES |%(_python_)s cat.py >$TARGET')
""" % locals())
test.write('bar1', 'bar1\r\n')
diff --git a/test/silent-command.py b/test/silent-command.py
index 7704ee59..b0e4a2ef 100644
--- a/test/silent-command.py
+++ b/test/silent-command.py
@@ -48,13 +48,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', r'%(_python_)s build.py $TARGET $SOURCE')
+env.Command('f2.out', 'f2.in', r'@%(_python_)s build.py $TARGET $SOURCE')
+env.Command('f3.out', 'f3.in', r'@ %(_python_)s build.py $TARGET $SOURCE')
+env.Command('f4.out', 'f4.in', r'@-%(_python_)s build.py $TARGET $SOURCE')
+env.Command('f5.out', 'f5.in', r'@- %(_python_)s build.py $TARGET $SOURCE')
+env.Command('f6.out', 'f6.in', r'-@%(_python_)s build.py $TARGET $SOURCE')
+env.Command('f7.out', 'f7.in', r'-@ %(_python_)s build.py $TARGET $SOURCE')
""" % locals())
test.write('f1.in', "f1.in\n")
diff --git a/test/special-filenames.py b/test/special-filenames.py
index 00e4a3df..de09a526 100644
--- a/test/special-filenames.py
+++ b/test/special-filenames.py
@@ -69,7 +69,7 @@ def buildFileStr(fn):
xxx = '\n'.join(map(buildFileStr, file_names))
test.write("SConstruct", """
-env=Environment(BUILDERS = {'Build' : Builder(action = '%(_python_)s cat.py $TARGET $SOURCE')})
+env=Environment(BUILDERS = {'Build' : Builder(action = r'%(_python_)s cat.py $TARGET $SOURCE')})
%(xxx)s
""" % locals())
diff --git a/test/srcchange.py b/test/srcchange.py
index d1812973..f2fde91a 100644
--- a/test/srcchange.py
+++ b/test/srcchange.py
@@ -63,7 +63,7 @@ SubRevision = Action(subrevision)
env=Environment()
content_env=env.Clone()
-content_env.Command('revision.in', [], '%(_python_)s getrevision > $TARGET')
+content_env.Command('revision.in', [], r'%(_python_)s getrevision > $TARGET')
content_env.AlwaysBuild('revision.in')
env.Precious('main.c')
env.Command('main.c', 'revision.in', SubRevision)
diff --git a/test/subdir.py b/test/subdir.py
index fa10cff4..22d09121 100644
--- a/test/subdir.py
+++ b/test/subdir.py
@@ -42,7 +42,7 @@ file.close()
""")
test.write('SConstruct', """
-B = Builder(action = '%(_python_)s build.py $TARGETS $SOURCES')
+B = Builder(action = r'%(_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')