The command line used to generate an object file
from an assembly-language source file.
+.IP ASCOMSTR
+The string displayed when an object file
+is generated from an assembly-language source file.
+If this is not set, then $ASCOM (the command line) is displayed.
+
+.ES
+env = Environment(ASCOMSTR = "Assembling $TARGET")
+.EE
+
.IP ASFLAGS
General options passed to the assembler.
Any options specified in the $CCFLAGS and $CPPFLAGS construction variables
are included on this command line.
+.IP CCCOMSTR
+The string displayed when a C source file
+is compiled to a (static) object file.
+If this is not set, then $CCCOM (the command line) is displayed.
+
+.ES
+env = Environment(CCCOMSTR = "Compiling $TARGET")
+.EE
+
.IP CCFLAGS
General options that are passed to the C compiler.
Any options specified in the $CXXFLAGS and $CPPFLAGS construction variables
are included on this command line.
+.IP CXXCOMSTR
+The string displayed when a C++ source file
+is compiled to a (static) object file.
+If this is not set, then $CXXCOM (the command line) is displayed.
+
+.ES
+env = Environment(CXXCOMSTR = "Compiling $TARGET")
+.EE
+
.IP CXXFLAGS
General options that are passed to the C++ compiler.
- Fix expansion of env.Command() overrides within target and
source file names.
+ - Support easier configurability of what's displayed by various default
+ actions through new construction variables: $ASCOMSTR, $CCCOMSTR,
+ $CXXCOMSTR.
+
From Wayne Lee:
- Avoid "maximum recursion limit" errors when removing $(-$) pairs
class CommandAction(_ActionAction):
"""Class for command-execution actions."""
- def __init__(self, cmd, *args, **kw):
+ def __init__(self, cmd, cmdstr=None, *args, **kw):
# Cmd can actually be a list or a single item; if it's a
# single item it should be the command string to execute; if a
# list then it should be the words of the command string to
raise TypeError, "CommandAction should be given only " \
"a single command"
self.cmd_list = cmd
+ self.cmdstr = cmdstr
def __str__(self):
if SCons.Util.is_List(self.cmd_list):
return str(self.cmd_list)
def strfunction(self, target, source, env):
+ if not self.cmdstr is None:
+ c = env.subst(self.cmdstr, 0, target, source)
+ if c:
+ return c
cmd_list = env.subst_list(self.cmd_list, 0, target, source)
return _string_from_cmd_list(cmd_list[0])
"""
a = SCons.Action.CommandAction(["xyzzy"])
assert a.cmd_list == [ "xyzzy" ], a.cmd_list
+ assert a.cmdstr is None, a.cmdstr
+
+ a = SCons.Action.CommandAction(["abra"], "cadabra")
+ assert a.cmd_list == [ "abra" ], a.cmd_list
+ assert a.cmdstr == "cadabra", a.cmdstr
def test___str__(self):
"""Test fetching the pre-substitution string for command Actions
s = act.strfunction([t1, t2], [s1, s2], env)
assert s == 'xyzzy t1 s1', s
+ act = SCons.Action.CommandAction('xyzzy $TARGET $SOURCE',
+ 'cmdstr - $SOURCE - $TARGET -')
+ s = act.strfunction([], [], env)
+ assert s == 'cmdstr - - -', s
+ s = act.strfunction([t1], [s1], env)
+ assert s == 'cmdstr - s1 - t1 -', s
+ s = act.strfunction([t1, t2], [s1, s2], env)
+ assert s == 'cmdstr - s1 - t1 -', s
+
act = SCons.Action.CommandAction('xyzzy $TARGETS $SOURCES')
s = act.strfunction([], [], env)
assert s == 'xyzzy', s
s = act.strfunction([t1, t2], [s1, s2], env)
assert s == 'xyzzy t1 t2 s1 s2', s
+ act = SCons.Action.CommandAction('xyzzy $TARGETS $SOURCES',
+ 'cmdstr = $SOURCES = $TARGETS =')
+ s = act.strfunction([], [], env)
+ assert s == 'cmdstr = = =', s
+ s = act.strfunction([t1], [s1], env)
+ assert s == 'cmdstr = s1 = t1 =', s
+ s = act.strfunction([t1, t2], [s1, s2], env)
+ assert s == 'cmdstr = s1 s2 = t1 t2 =', s
+
act = SCons.Action.CommandAction(['xyzzy',
'$TARGET', '$SOURCE',
'$TARGETS', '$SOURCES'])
del suffix
# Actions for common languages.
-CAction = SCons.Action.Action("$CCCOM")
+CAction = SCons.Action.Action("$CCCOM", "$CCCOMSTR")
DAction = SCons.Action.Action("$DCOM")
ShCAction = SCons.Action.Action("$SHCCCOM")
-CXXAction = SCons.Action.Action("$CXXCOM")
+CXXAction = SCons.Action.Action("$CXXCOM", "$CXXCOMSTR")
ShCXXAction = SCons.Action.Action("$SHCXXCOM")
-ASAction = SCons.Action.Action("$ASCOM")
+ASAction = SCons.Action.Action("$ASCOM", "$ASCOMSTR")
ASPPAction = SCons.Action.Action("$ASPPCOM")
LinkAction = SCons.Action.Action("$LINKCOM")
--- /dev/null
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Test the ability to configure the $ASCOM construction variable.
+"""
+
+import os
+import string
+import sys
+import TestSCons
+
+python = TestSCons.python
+
+test = TestSCons.TestSCons()
+
+
+
+test.write('myas.py', r"""
+import sys
+infile = open(sys.argv[2], 'rb')
+outfile = open(sys.argv[1], 'wb')
+for l in filter(lambda l: l != "#as\n", infile.readlines()):
+ outfile.write(l)
+sys.exit(0)
+""")
+
+if os.path.normcase('.s') == os.path.normcase('.S'):
+ alt_s_suffix = '.S'
+ alt_asm_suffix = '.ASM'
+else:
+ alt_s_suffix = '.s'
+ alt_asm_suffix = '.asm'
+
+test.write('SConstruct', """
+env = Environment(ASCOM = r'%(python)s myas.py $TARGET $SOURCE',
+ OBJSUFFIX = '.obj')
+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')
+""" % 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.run(arguments = '.')
+
+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.pass_test()
--- /dev/null
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Test that the $ASCOMSTR construction variable allows you to configure
+the assembly output.
+"""
+
+import os
+import string
+import sys
+import TestSCons
+
+python = TestSCons.python
+
+test = TestSCons.TestSCons()
+
+
+
+test.write('myas.py', r"""
+import sys
+infile = open(sys.argv[2], 'rb')
+outfile = open(sys.argv[1], 'wb')
+for l in filter(lambda l: l != "#as\n", infile.readlines()):
+ outfile.write(l)
+sys.exit(0)
+""")
+
+if os.path.normcase('.s') == os.path.normcase('.S'):
+ alt_s_suffix = '.S'
+ alt_asm_suffix = '.ASM'
+else:
+ alt_s_suffix = '.s'
+ alt_asm_suffix = '.asm'
+
+test.write('SConstruct', """
+env = Environment(ASCOM = r'%(python)s myas.py $TARGET $SOURCE',
+ ASCOMSTR = 'Assembling $TARGET from $SOURCE',
+ OBJSUFFIX = '.obj')
+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')
+""" % 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.run(stdout = test.wrap_stdout("""\
+Assembling test1.obj from test1.s
+Assembling test2.obj from test2%(alt_s_suffix)s
+Assembling test3.obj from test3.asm
+Assembling test4.obj from test4%(alt_asm_suffix)s
+""" % locals()))
+
+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.pass_test()
--- /dev/null
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Test the ability to configure the $CCCOM construction variable.
+"""
+
+import os
+import string
+import sys
+import TestSCons
+
+python = TestSCons.python
+_exe = TestSCons._exe
+
+test = TestSCons.TestSCons()
+
+
+
+test.write('mycc.py', r"""
+import sys
+outfile = open(sys.argv[1], 'wb')
+infile = open(sys.argv[2], 'rb')
+for l in filter(lambda l: l[:6] != '/*cc*/', infile.readlines()):
+ outfile.write(l)
+sys.exit(0)
+""")
+
+if os.path.normcase('.c') == os.path.normcase('.C'):
+ alt_c_suffix = '.C'
+else:
+ alt_c_suffix = '.c'
+
+test.write('SConstruct', """
+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')
+""" % locals())
+
+test.write('test1.c', """\
+test1.c
+/*cc*/
+""")
+
+test.write('test2'+alt_c_suffix, """\
+test2.C
+/*cc*/
+""")
+
+test.run()
+
+test.must_match('test1.obj', "test1.c\n")
+test.must_match('test2.obj', "test2.C\n")
+
+
+
+test.pass_test()
--- /dev/null
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Test that the $CCCOMSTR construction variable allows you to configure
+the C compilation output.
+"""
+
+import os
+import string
+import sys
+import TestSCons
+
+python = TestSCons.python
+_exe = TestSCons._exe
+
+test = TestSCons.TestSCons()
+
+
+
+test.write('mycc.py', r"""
+import sys
+outfile = open(sys.argv[1], 'wb')
+infile = open(sys.argv[2], 'rb')
+for l in filter(lambda l: l[:6] != '/*cc*/', infile.readlines()):
+ outfile.write(l)
+sys.exit(0)
+""")
+
+if os.path.normcase('.c') == os.path.normcase('.C'):
+ alt_c_suffix = '.C'
+else:
+ alt_c_suffix = '.c'
+
+test.write('SConstruct', """
+env = Environment(CCCOM = r'%(python)s mycc.py $TARGET $SOURCE',
+ CCCOMSTR = 'Building $TARGET from $SOURCE',
+ OBJSUFFIX='.obj')
+env.Object(target = 'test1', source = 'test1.c')
+env.Object(target = 'test2', source = 'test2%(alt_c_suffix)s')
+""" % locals())
+
+test.write('test1.c', """\
+test1.c
+/*cc*/
+""")
+
+test.write('test2'+alt_c_suffix, """\
+test2.C
+/*cc*/
+""")
+
+test.run(stdout = test.wrap_stdout("""\
+Building test1.obj from test1.c
+Building test2.obj from test2%(alt_c_suffix)s
+""" % locals()))
+
+test.must_match('test1.obj', "test1.c\n")
+test.must_match('test2.obj', "test2.C\n")
+
+
+
+test.pass_test()
--- /dev/null
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Test the ability to configure the $CXXCOM construction variable.
+"""
+
+import os
+import string
+import sys
+import TestSCons
+
+python = TestSCons.python
+_exe = TestSCons._exe
+
+test = TestSCons.TestSCons()
+
+
+
+test.write('mycc.py', r"""
+import sys
+outfile = open(sys.argv[1], 'wb')
+infile = open(sys.argv[2], 'rb')
+for l in filter(lambda l: l[:7] != '/*c++*/', infile.readlines()):
+ outfile.write(l)
+sys.exit(0)
+""")
+
+if os.path.normcase('.c') == os.path.normcase('.C'):
+ alt_cc_suffix = '.CC'
+else:
+ alt_cc_suffix = '.cc'
+
+test.write('SConstruct', """
+env = Environment(CXXCOM = r'%(python)s mycc.py $TARGET $SOURCE',
+ OBJSUFFIX='.obj')
+env.Object(target = 'test1', source = 'test1.cc')
+env.Object(target = 'test2', source = 'test2%(alt_cc_suffix)s')
+""" % locals())
+
+test.write('test1.cc', """\
+test1.cc
+/*c++*/
+""")
+
+test.write('test2'+alt_cc_suffix, """\
+test2.CC
+/*c++*/
+""")
+
+test.run()
+
+test.must_match('test1.obj', "test1.cc\n")
+test.must_match('test2.obj', "test2.CC\n")
+
+
+
+test.pass_test()
--- /dev/null
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Test that the $CXXCOMSTR construction variable allows you to configure
+the C++ compilation output.
+"""
+
+import os
+import string
+import sys
+import TestSCons
+
+python = TestSCons.python
+_exe = TestSCons._exe
+
+test = TestSCons.TestSCons()
+
+
+
+test.write('mycc.py', r"""
+import sys
+outfile = open(sys.argv[1], 'wb')
+infile = open(sys.argv[2], 'rb')
+for l in filter(lambda l: l[:6] != '/*cc*/', infile.readlines()):
+ outfile.write(l)
+sys.exit(0)
+""")
+
+if os.path.normcase('.c') == os.path.normcase('.C'):
+ alt_cc_suffix = '.CC'
+else:
+ alt_cc_suffix = '.cc'
+
+test.write('SConstruct', """
+env = Environment(CXXCOM = r'%(python)s mycc.py $TARGET $SOURCE',
+ CXXCOMSTR = 'Building $TARGET from $SOURCE',
+ OBJSUFFIX='.obj')
+env.Object(target = 'test1', source = 'test1.cc')
+env.Object(target = 'test2', source = 'test2%(alt_cc_suffix)s')
+""" % locals())
+
+test.write('test1.cc', """\
+test1.cc
+/*cc*/
+""")
+
+test.write('test2'+alt_cc_suffix, """\
+test2.CC
+/*cc*/
+""")
+
+test.run(stdout = test.wrap_stdout("""\
+Building test1.obj from test1.cc
+Building test2.obj from test2%(alt_cc_suffix)s
+""" % locals()))
+
+test.must_match('test1.obj', "test1.cc\n")
+test.must_match('test2.obj', "test2.CC\n")
+
+
+
+test.pass_test()