From: stevenknight Date: Thu, 27 Jun 2002 15:00:50 +0000 (+0000) Subject: Add support for assembly language (.s and .S) Tools. Still needs support for buildin... X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=4a7373d6f83430cfeb51f21b52663e64d45022e0;p=scons.git Add support for assembly language (.s and .S) Tools. Still needs support for building shared objects. git-svn-id: http://scons.tigris.org/svn/scons/trunk@397 fdb21ef1-2011-0410-befe-b5e4ea1792b1 --- diff --git a/HOWTO/new-tool.txt b/HOWTO/new-tool.txt new file mode 100644 index 00000000..c906b7fb --- /dev/null +++ b/HOWTO/new-tool.txt @@ -0,0 +1,79 @@ +Adding a new Tool to the SCons distribution: + + -- Add the following files (aenf): + + src/engine/SCons/Tool/xxx.py + + Use one of the other Tool files as a template. + + The tool should set and use construction variables: + + XXX (specific tool) + XXXCOM (the command line) + XXXFLAGS (flags for the command line) + + -- Modify the following files (aecp): + + doc/man/scons.1 + + Add the new tool to the default Platform lists + (if appropriate). + + If this creates object files from a new source + file type, add the new file suffixes. + + Document the new construction variables. + + rpm/scons.spec + + Add to the list at the bottom of the file: + + /usr/lib/scons/SCons/Tool/xxx.py + /usr/lib/scons/SCons/Tool/xxx.pyc + + [THIS LIST SHOULD BE GENERATED FROM MANIFEST.in, + AND WILL BE SOME DAY.] + + src/CHANGES.txt + + Add mention of the new Tool specification. + + src/engine/MANIFEST.in + + Add to the list: + + SCons/Tool/xxx.py + + src/engine/SCons/Defaults.py + + If there are any new Actions for the Tool, add them + here. + + src/engine/SCons/Platform/*.py + + Add the Tool to the list(s) returned by tool_list(). + + -- Add the following tests (aent): + + test/XXX.py + + Use one of the other tests as a template. + + The first part should be a platform-independent test + using dummy 'myxxx.py' utilities to test if $XXX is set. + + Remaining parts of the test can check to see if the + specific tool is installed on the system, and test + actually executing the tool. + + test/XXXFLAGS.py + + Use one of the other tests as a template. + + The first part should be a platform-independent test + using dummy 'myxxx.py' utilities to test if $XXXFLAGS is + set. + + Optionally, remaining parts of the test can check to see + if the specific tool is installed on the system, and + test actually executing the tool. diff --git a/doc/man/scons.1 b/doc/man/scons.1 index a81bae58..0241c9b2 100644 --- a/doc/man/scons.1 +++ b/doc/man/scons.1 @@ -720,10 +720,12 @@ dvipdf dvips g++ g77 +gas (if the GNU assembler is available) gcc gnulink latex lex +nasm (if the GNU assembler is not available) pdflatex pdftex tex @@ -743,6 +745,8 @@ lex lib mslink msvc +masm +nasm pdflatex pdftex tex @@ -791,6 +795,8 @@ Builds a static object file from one or more C, C++, or Fortran source files. Source files must have one of the following extensions: .ES + .asm assembly language file + .ASM assembly language file .c C file .C WIN32: C file POSIX: C++ file @@ -807,6 +813,11 @@ Source files must have one of the following extensions: .FOR Fortran file .fpp Fortran file + C pre-processor .FPP Fortran file + C pre-processor + .s assembly language file + .S WIN32: assembly language file + POSIX: assembly language file + C pre-processor + .spp assembly language file + C pre-processor + .SPP assembly language file + C pre-processor .EE .IP The target object file prefix and suffix (if any) are automatically @@ -994,14 +1005,21 @@ env.PostScript(target = 'bbb', source = 'bbb.dvi') .LP .B scons automatically scans -C source files, C++ source files, and +C source files, C++ source files, Fortran source files with .B .F (POSIX systems only), .B .fpp, or .B .FPP -file extensions +file extensions, +and assembly language files with +.B .S +(POSIX systems only), +.B .spp, +or +.B .SPP +files extensions for C preprocessor dependencies, so the dependencies do not need to be specified explicitly. In addition, all builder @@ -1177,6 +1195,30 @@ with the specified keyword arguments. env.Replace(CCFLAGS = '-g', FOO = 'foo.xxx') .EE +.TP +.RI SideEffect( side_effect , target ) +Declares +.I side_effect +as a side effect of building +.IR target . +Both +.I side_effect +and +.I target +can be a list, a file name, or a node. +A side effect is a target that is created +as a side effect of building other targets. +For example, a Windows PDB +file is created as a side effect of building the .obj +files for a static library. +If a target is a side effect of multiple build commands, +.B scons +will ensure that only one set of commands +is executed at a time. +Consequently, you only need to use this method +for side-effect targets that are built as a result of +multiple build commands. + .SS Construction Variables .\" XXX From Gary Ruben, 23 April 2002: .\" I think it would be good to have an example with each construction @@ -1204,11 +1246,28 @@ variables: .IP AR The static library archiver. +.IP ARCOM +The command line used to generate a static library from object files. + .IP ARFLAGS General options passed to the static library archiver. -.IP ARCOM -The command line used to generate a static library from object files. +.IP AS +The assembler. + +.IP ASCOM +The command line used to generate an object file +from an assembly-language source file. + +.IP ASFLAGS +General options passed to the assembler. + +.IP ASPPCOM +The command line used to assemble an assembly-language +source file into an object file +after first running the file through the C preprocessor. +Any options specified in the $CPPFLAGS construction variable +are included on this command line. .IP BUILDERS A dictionary mapping the names of the builders @@ -1244,9 +1303,11 @@ as C files. C preprocessor options. These will be included in any command that uses the C preprocessor, inluding not just compilation of C and C++ source files, -but also the $F77PPCOM -command line used to compile a Fortran source file to an object file -after first running the file through the C preprocessor. +but also the $F77PPCOM command line +used to compile a Fortran source file, +and the $ASPPCOM command line +used to assemble an assembly language source file, +after first running each file through the C preprocessor. .IP CPPPATH The list of directories that the C preprocessor will search for include diff --git a/rpm/scons.spec b/rpm/scons.spec index a2cb76da..6dbec214 100644 --- a/rpm/scons.spec +++ b/rpm/scons.spec @@ -108,6 +108,8 @@ rm -rf $RPM_BUILD_ROOT /usr/lib/scons/SCons/Tool/g++.pyc /usr/lib/scons/SCons/Tool/g77.py /usr/lib/scons/SCons/Tool/g77.pyc +/usr/lib/scons/SCons/Tool/gas.py +/usr/lib/scons/SCons/Tool/gas.pyc /usr/lib/scons/SCons/Tool/gcc.py /usr/lib/scons/SCons/Tool/gcc.pyc /usr/lib/scons/SCons/Tool/gnulink.py @@ -118,10 +120,14 @@ rm -rf $RPM_BUILD_ROOT /usr/lib/scons/SCons/Tool/lex.pyc /usr/lib/scons/SCons/Tool/lib.py /usr/lib/scons/SCons/Tool/lib.pyc +/usr/lib/scons/SCons/Tool/masm.py +/usr/lib/scons/SCons/Tool/masm.pyc /usr/lib/scons/SCons/Tool/mslink.py /usr/lib/scons/SCons/Tool/mslink.pyc /usr/lib/scons/SCons/Tool/msvc.py /usr/lib/scons/SCons/Tool/msvc.pyc +/usr/lib/scons/SCons/Tool/nasm.py +/usr/lib/scons/SCons/Tool/nasm.pyc /usr/lib/scons/SCons/Tool/pdflatex.py /usr/lib/scons/SCons/Tool/pdflatex.pyc /usr/lib/scons/SCons/Tool/pdftex.py diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 5f87eb91..8146a261 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -69,6 +69,8 @@ RELEASE 0.08 - - Add more specific version / build output to the -v option. + - Add support for the GNU as, Microsoft masm, and nasm assemblers. + From Jeff Petkau: - Fix --implicit-cache if the scanner returns an empty list. @@ -106,6 +108,12 @@ RELEASE 0.08 - - Print an error message if a file can't be unlinked before being built, rather than just silently terminating the build. + - Add a SideEffect() method that can be used to tell the build + engine that a given file is created as a side effect of building + a target. A file can be specified as a side effect of more than + one build comand, in which case the commands will not be executed + simultaneously. + From Zed Shaw: - Add an Append() method to Environments, to append values to diff --git a/src/engine/MANIFEST.in b/src/engine/MANIFEST.in index b67d63a7..9a057876 100644 --- a/src/engine/MANIFEST.in +++ b/src/engine/MANIFEST.in @@ -29,13 +29,16 @@ SCons/Tool/dvipdf.py SCons/Tool/dvips.py SCons/Tool/g++.py SCons/Tool/g77.py +SCons/Tool/gas.py SCons/Tool/gcc.py SCons/Tool/gnulink.py SCons/Tool/latex.py SCons/Tool/lex.py SCons/Tool/lib.py +SCons/Tool/masm.py SCons/Tool/mslink.py SCons/Tool/msvc.py +SCons/Tool/nasm.py SCons/Tool/pdflatex.py SCons/Tool/pdftex.py SCons/Tool/tex.py diff --git a/src/engine/SCons/Defaults.py b/src/engine/SCons/Defaults.py index 778517d3..2a616c8b 100644 --- a/src/engine/SCons/Defaults.py +++ b/src/engine/SCons/Defaults.py @@ -116,11 +116,15 @@ CAction = SCons.Action.Action([ StaticCheck, "$CCCOM" ]) ShCAction = SCons.Action.Action([ SharedCheck, "$SHCCCOM" ]) CXXAction = SCons.Action.Action([ StaticCheck, "$CXXCOM" ]) ShCXXAction = SCons.Action.Action([ SharedCheck, "$SHCXXCOM" ]) + F77Action = SCons.Action.Action([ StaticCheck, "$F77COM" ]) ShF77Action = SCons.Action.Action([ SharedCheck, "$SHF77COM" ]) F77PPAction = SCons.Action.Action([ StaticCheck, "$F77PPCOM" ]) ShF77PPAction = SCons.Action.Action([ SharedCheck, "$SHF77PPCOM" ]) +ASAction = SCons.Action.Action([ StaticCheck, "$ASCOM" ]) +ASPPAction = SCons.Action.Action([ StaticCheck, "$ASPPCOM" ]) + def StaticObject(): """A function for generating the static object Builder.""" diff --git a/src/engine/SCons/Platform/cygwin.py b/src/engine/SCons/Platform/cygwin.py index 6a21ae9a..8858dd1b 100644 --- a/src/engine/SCons/Platform/cygwin.py +++ b/src/engine/SCons/Platform/cygwin.py @@ -32,9 +32,20 @@ selection method. __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +import SCons.Util + def tool_list(): - return ['ar', 'dvipdf', 'dvips', 'g++', 'g77', 'gcc', 'latex', 'lex', - 'pdflatex', 'pdftex', 'tex', 'yacc', 'gnulink' ] + as = SCons.Util.WhereIs('as') + nasm = SCons.Util.WhereIs('nasm') + if nasm and not as: + assembler = 'nasm' + else: + assembler = 'gas' + return ['ar', 'dvipdf', 'dvips', + 'g++', 'g77', 'gcc', 'gnulink', + 'latex', 'lex', + 'pdflatex', 'pdftex', 'tex', 'yacc', + assembler] def generate(env): if not env.has_key('ENV'): diff --git a/src/engine/SCons/Platform/posix.py b/src/engine/SCons/Platform/posix.py index 3d20263a..79adebd5 100644 --- a/src/engine/SCons/Platform/posix.py +++ b/src/engine/SCons/Platform/posix.py @@ -32,9 +32,20 @@ selection method. __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +import SCons.Util + def tool_list(): - return ['ar', 'dvipdf', 'dvips', 'g++', 'g77', 'gcc', 'latex', 'lex', - 'pdflatex', 'pdftex', 'tex', 'yacc', 'gnulink' ] + as = SCons.Util.WhereIs('as') + nasm = SCons.Util.WhereIs('nasm') + if nasm and not as: + assembler = 'nasm' + else: + assembler = 'gas' + return ['ar', 'dvipdf', 'dvips', + 'g++', 'g77', 'gcc', 'gnulink', + 'latex', 'lex', + 'pdflatex', 'pdftex', 'tex', 'yacc', + assembler] def generate(env): if not env.has_key('ENV'): diff --git a/src/engine/SCons/Platform/win32.py b/src/engine/SCons/Platform/win32.py index 9bcea18e..957aead8 100644 --- a/src/engine/SCons/Platform/win32.py +++ b/src/engine/SCons/Platform/win32.py @@ -32,9 +32,19 @@ selection method. __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +import SCons.Util + def tool_list(): - return ['dvipdf', 'latex', 'dvips', 'g77', 'lex', 'lib', 'msvc', - 'pdflatex', 'pdftex', 'tex', 'yacc', 'mslink' ] + masm = SCons.Util.WhereIs('ml') + nasm = SCons.Util.WhereIs('nasm') + if nasm and not masm: + assembler = 'nasm' + else: + assembler = 'masm' + return ['dvipdf', 'dvips', 'g77', + 'latex', 'lex', 'lib', 'mslink', 'msvc', + 'pdflatex', 'pdftex', 'tex', 'yacc', + assembler] def generate(env): if not env.has_key('ENV'): diff --git a/src/engine/SCons/Tool/.aeignore b/src/engine/SCons/Tool/.aeignore new file mode 100644 index 00000000..22ebd62b --- /dev/null +++ b/src/engine/SCons/Tool/.aeignore @@ -0,0 +1,5 @@ +*,D +*.pyc +.*.swp +.consign +.sconsign diff --git a/src/engine/SCons/Tool/gas.py b/src/engine/SCons/Tool/gas.py new file mode 100644 index 00000000..6fc3d8c0 --- /dev/null +++ b/src/engine/SCons/Tool/gas.py @@ -0,0 +1,61 @@ +"""SCons.Tool.as + +Tool-specific initialization for as, the Gnu assembler. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002 Steven Knight +# +# 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 os.path + +import SCons.Defaults +import SCons.Tool + +ASSuffixes = ['.s', '.asm', '.ASM'] +ASPPSuffixes = ['.spp', '.SPP'] +if os.path.normcase('.s') == os.path.normcase('.S'): + ASSuffixes.extend(['.S']) +else: + ASPPSuffixes.extend(['.S']) + +def generate(env, platform): + """Add Builders and construction variables for as to an Environment.""" + static_obj, shared_obj = SCons.Tool.createObjBuilders(env) + + for suffix in ASSuffixes: + static_obj.add_action(suffix, SCons.Defaults.ASAction) + + for suffix in ASPPSuffixes: + static_obj.add_action(suffix, SCons.Defaults.ASPPAction) + + env['AS'] = 'as' + env['ASFLAGS'] = '' + env['ASCOM'] = '$AS $ASFLAGS -o $TARGET $SOURCES' + env['ASPPCOM'] = '$CC $ASFLAGS $CPPFLAGS -o $TARGET $SOURCES' diff --git a/src/engine/SCons/Tool/masm.py b/src/engine/SCons/Tool/masm.py new file mode 100644 index 00000000..e88266da --- /dev/null +++ b/src/engine/SCons/Tool/masm.py @@ -0,0 +1,61 @@ +"""SCons.Tool.masm + +Tool-specific initialization for the Microsoft Assembler. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002 Steven Knight +# +# 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 os.path + +import SCons.Defaults +import SCons.Tool + +ASSuffixes = ['.s', '.asm', '.ASM'] +ASPPSuffixes = ['.spp', '.SPP'] +if os.path.normcase('.s') == os.path.normcase('.S'): + ASSuffixes.extend(['.S']) +else: + ASPPSuffixes.extend(['.S']) + +def generate(env, platform): + """Add Builders and construction variables for masm to an Environment.""" + static_obj, shared_obj = SCons.Tool.createObjBuilders(env) + + for suffix in ASSuffixes: + static_obj.add_action(suffix, SCons.Defaults.ASAction) + + for suffix in ASPPSuffixes: + static_obj.add_action(suffix, SCons.Defaults.ASPPAction) + + env['AS'] = 'ml' + env['ASFLAGS'] = '/nologo' + env['ASCOM'] = '$AS $ASFLAGS /c /Fo$TARGET $SOURCES' + env['ASPPCOM'] = '$CC $ASFLAGS $CPPFLAGS /c /Fo$TARGET $SOURCES' diff --git a/src/engine/SCons/Tool/nasm.py b/src/engine/SCons/Tool/nasm.py new file mode 100644 index 00000000..b757a53a --- /dev/null +++ b/src/engine/SCons/Tool/nasm.py @@ -0,0 +1,61 @@ +"""SCons.Tool.nasm + +Tool-specific initialization for nasm, the famous Netwide Assembler. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002 Steven Knight +# +# 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 os.path + +import SCons.Defaults +import SCons.Tool + +ASSuffixes = ['.s', '.asm', '.ASM'] +ASPPSuffixes = ['.spp', '.SPP'] +if os.path.normcase('.s') == os.path.normcase('.S'): + ASSuffixes.extend(['.S']) +else: + ASPPSuffixes.extend(['.S']) + +def generate(env, platform): + """Add Builders and construction variables for nasm to an Environment.""" + static_obj, shared_obj = SCons.Tool.createObjBuilders(env) + + for suffix in ASSuffixes: + static_obj.add_action(suffix, SCons.Defaults.ASAction) + + for suffix in ASPPSuffixes: + static_obj.add_action(suffix, SCons.Defaults.ASPPAction) + + env['AS'] = 'nasm' + env['ASFLAGS'] = '' + env['ASCOM'] = '$AS $ASFLAGS -o $TARGET $SOURCES' + env['ASPPCOM'] = '$CC $ASFLAGS $CPPFLAGS -c -o $TARGET $SOURCES' diff --git a/test/AS.py b/test/AS.py new file mode 100644 index 00000000..97ad0ce2 --- /dev/null +++ b/test/AS.py @@ -0,0 +1,401 @@ +#!/usr/bin/env python +# +# Copyright (c) 2001, 2002 Steven Knight +# +# 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 os +import string +import sys +import TestSCons + +python = sys.executable + +if sys.platform == 'win32': + _exe = '.exe' +else: + _exe = '' + +test = TestSCons.TestSCons() + + + +if sys.platform == 'win32': + + test.write('mylink.py', r""" +import string +import sys +args = sys.argv[1:] +while args: + a = args[0] + if a[0] != '/': + break + args = args[1:] + if string.lower(a[:5]) == '/out:': out = a[5:] +infile = open(args[0], 'rb') +outfile = open(out, 'wb') +for l in infile.readlines(): + if l[:5] != '#link': + outfile.write(l) +sys.exit(0) +""") + + test.write('myas.py', r""" +import sys +args = sys.argv[1:] +inf = None +while args: + a = args[0] + args = args[1:] + if a[0] != '/': + if not inf: + inf = a + continue + if a[:3] == '/Fo': out = a[3:] +infile = open(inf, 'rb') +outfile = open(out, 'wb') +for l in infile.readlines(): + if l[:3] != '#as': + outfile.write(l) +sys.exit(0) +""") + +else: + + test.write('mylink.py', r""" +import getopt +import sys +opts, args = getopt.getopt(sys.argv[1:], 'o:') +for opt, arg in opts: + if opt == '-o': out = arg +infile = open(args[0], 'rb') +outfile = open(out, 'wb') +for l in infile.readlines(): + if l[:5] != '#link': + outfile.write(l) +sys.exit(0) +""") + + test.write('myas.py', r""" +import getopt +import sys +opts, args = getopt.getopt(sys.argv[1:], 'co:') +for opt, arg in opts: + if opt == '-o': out = arg +infile = open(args[0], 'rb') +outfile = open(out, 'wb') +for l in infile.readlines(): + if l[:3] != '#as': + outfile.write(l) +sys.exit(0) +""") + +test.write('SConstruct', """ +env = Environment(LINK = r'%s mylink.py', + AS = r'%s myas.py', + CC = r'%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)) + +test.write('test1.s', r"""This is a .s file. +#as +#link +""") + +test.write('test2.S', r"""This is a .S file. +#as +#link +""") + +test.write('test3.asm', r"""This is a .asm file. +#as +#link +""") + +test.write('test4.ASM', r"""This is a .ASM file. +#as +#link +""") + +test.write('test5.spp', r"""This is a .spp file. +#as +#link +""") + +test.write('test6.SPP', r"""This is a .SPP file. +#as +#link +""") + +test.run(arguments = '.', stderr = None) + +test.fail_test(test.read('test1' + _exe) != "This is a .s file.\n") + +test.fail_test(test.read('test2' + _exe) != "This is a .S file.\n") + +test.fail_test(test.read('test3' + _exe) != "This is a .asm file.\n") + +test.fail_test(test.read('test4' + _exe) != "This is a .ASM file.\n") + +test.fail_test(test.read('test5' + _exe) != "This is a .spp file.\n") + +test.fail_test(test.read('test6' + _exe) != "This is a .SPP file.\n") + + + +as = test.where_is('as') + +if as: + + test.write("wrapper.py", +"""import os +import string +import sys +open('%s', 'wb').write("wrapper.py\\n") +os.system(string.join(sys.argv[1:], " ")) +""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\')) + + test.write('SConstruct', """ +aaa = Environment() +bbb = aaa.Copy(AS = r'%s wrapper.py ' + WhereIs('as')) +aaa.Program(target = 'aaa', source = ['aaa.s', 'aaa_main.c']) +bbb.Program(target = 'bbb', source = ['bbb.s', 'bbb_main.c']) +""" % python) + + test.write('aaa.s', +""" .file "aaa.s" +.data +.align 4 +.globl name +name: + .ascii "aaa.s" + .byte 0 +""") + + test.write('bbb.s', +""" .file "bbb.s" +.data +.align 4 +.globl name +name: + .ascii "bbb.s" + .byte 0 +""") + + test.write('aaa_main.c', r""" +extern char name[]; + +int +main(int argc, char *argv[]) +{ + argv[argc++] = "--"; + printf("aaa_main.c %s\n", name); + exit (0); +} +""") + + test.write('bbb_main.c', r""" +extern char name[]; + +int +main(int argc, char *argv[]) +{ + argv[argc++] = "--"; + printf("bbb_main.c %s\n", name); + exit (0); +} +""") + + test.run(arguments = 'aaa' + _exe, stderr = None) + + test.run(program = test.workpath('aaa'), stdout = "aaa_main.c aaa.s\n") + + test.fail_test(os.path.exists(test.workpath('wrapper.out'))) + + test.run(arguments = 'bbb' + _exe) + + test.run(program = test.workpath('bbb'), stdout = "bbb_main.c bbb.s\n") + + test.fail_test(test.read('wrapper.out') != "wrapper.py\n") + + test.unlink('wrapper.out') + + + +ml = test.where_is('ml') + +if ml: + + test.write("wrapper.py", +"""import os +import string +import sys +open('%s', 'wb').write("wrapper.py\\n") +os.system(string.join(sys.argv[1:], " ")) +""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\')) + + test.write('SConstruct', """ +import os +ccc = Environment(tools = ['msvc', 'mslink', 'masm'], + ASFLAGS = '/nologo /coff') +ccc['ENV']['PATH'] = os.environ['PATH'] +ddd = ccc.Copy(AS = r'%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) + + test.write('ccc.asm', +""" +DSEG segment + PUBLIC _name +_name byte "ccc.asm",0 +DSEG ends + end +""") + + test.write('ddd.asm', +""" +DSEG segment + PUBLIC _name +_name byte "ddd.asm",0 +DSEG ends + end +""") + + test.write('ccc_main.c', r""" +extern char name[]; + +int +main(int argc, char *argv[]) +{ + argv[argc++] = "--"; + printf("ccc_main.c %s\n", name); + exit (0); +} +""") + + test.write('ddd_main.c', r""" +extern char name[]; + +int +main(int argc, char *argv[]) +{ + argv[argc++] = "--"; + printf("ddd_main.c %s\n", name); + exit (0); +} +""") + + test.run(arguments = 'ccc' + _exe, stderr = None) + + test.run(program = test.workpath('ccc'), stdout = "ccc_main.c ccc.asm\n") + + test.fail_test(os.path.exists(test.workpath('wrapper.out'))) + + test.run(arguments = 'ddd' + _exe) + + test.run(program = test.workpath('ddd'), stdout = "ddd_main.c ddd.asm\n") + + test.fail_test(test.read('wrapper.out') != "wrapper.py\n") + + + + +nasm = test.where_is('nasm') + +if nasm: + + test.write("wrapper.py", +"""import os +import string +import sys +open('%s', 'wb').write("wrapper.py\\n") +os.system(string.join(sys.argv[1:], " ")) +""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\')) + + test.write('SConstruct', """ +eee = Environment(tools = ['gcc', 'gnulink', 'nasm'], + ASFLAGS = '-f aout') +fff = eee.Copy(AS = r'%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']) +""" % python) + + test.write('eee.asm', +""" +global name +name: + db 'eee.asm',0 +""") + + test.write('fff.asm', +""" +global name +name: + db 'fff.asm',0 +""") + + test.write('eee_main.c', r""" +extern char name[]; + +int +main(int argc, char *argv[]) +{ + argv[argc++] = "--"; + printf("eee_main.c %s\n", name); + exit (0); +} +""") + + test.write('fff_main.c', r""" +extern char name[]; + +int +main(int argc, char *argv[]) +{ + argv[argc++] = "--"; + printf("fff_main.c %s\n", name); + exit (0); +} +""") + + test.run(arguments = 'eee' + _exe, stderr = None) + + test.run(program = test.workpath('eee'), stdout = "eee_main.c eee.asm\n") + + test.fail_test(os.path.exists(test.workpath('wrapper.out'))) + + test.run(arguments = 'fff' + _exe) + + test.run(program = test.workpath('fff'), stdout = "fff_main.c fff.asm\n") + + test.fail_test(test.read('wrapper.out') != "wrapper.py\n") + + + +test.pass_test() diff --git a/test/ASFLAGS.py b/test/ASFLAGS.py new file mode 100644 index 00000000..5d644b37 --- /dev/null +++ b/test/ASFLAGS.py @@ -0,0 +1,185 @@ +#!/usr/bin/env python +# +# Copyright (c) 2001, 2002 Steven Knight +# +# 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 os +import string +import sys +import TestSCons + +python = sys.executable + +test = TestSCons.TestSCons() + + +if sys.platform == 'win32': + + _exe = '.exe' + + o = ' -x' + + test.write('mylink.py', r""" +import string +import sys +args = sys.argv[1:] +while args: + a = args[0] + if a[0] != '/': + break + args = args[1:] + if string.lower(a[:5]) == '/out:': out = a[5:] +infile = open(args[0], 'rb') +outfile = open(out, 'wb') +for l in infile.readlines(): + if l[:5] != '#link': + outfile.write(l) +sys.exit(0) +""") + + test.write('myas.py', r""" +import sys +args = sys.argv[1:] +inf = None +optstring = '' +while args: + a = args[0] + args = args[1:] + if not a[0] in '/-': + if not inf: + inf = a + continue + if a[:2] == '/c': + continue + if a[:3] == '/Fo': + out = a[3:] + continue + optstring = optstring + ' ' + a +infile = open(inf, 'rb') +outfile = open(out, 'wb') +outfile.write(optstring + "\n") +for l in infile.readlines(): + if l[:3] != '#as': + outfile.write(l) +sys.exit(0) +""") + +else: + + _exe = '' + + o = ' -x' + + test.write('mylink.py', r""" +import getopt +import sys +opts, args = getopt.getopt(sys.argv[1:], 'o:') +for opt, arg in opts: + if opt == '-o': out = arg +infile = open(args[0], 'rb') +outfile = open(out, 'wb') +for l in infile.readlines(): + if l[:5] != '#link': + outfile.write(l) +sys.exit(0) +""") + + test.write('myas.py', r""" +import getopt +import sys +opts, args = getopt.getopt(sys.argv[1:], 'co:x') +optstring = '' +for opt, arg in opts: + if opt == '-o': out = arg + else: optstring = optstring + ' ' + opt +infile = open(args[0], 'rb') +outfile = open(out, 'wb') +outfile.write(optstring + "\n") +for l in infile.readlines(): + if l[:3] != '#as': + outfile.write(l) +sys.exit(0) +""") + + + +test.write('SConstruct', """ +env = Environment(LINK = r'%s mylink.py', + AS = r'%s myas.py', ASFLAGS = '-x', + CC = r'%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)) + +test.write('test1.s', r"""This is a .s file. +#as +#link +""") + +test.write('test2.S', r"""This is a .S file. +#as +#link +""") + +test.write('test3.asm', r"""This is a .asm file. +#as +#link +""") + +test.write('test4.ASM', r"""This is a .ASM file. +#as +#link +""") + +test.write('test5.spp', r"""This is a .spp file. +#as +#link +""") + +test.write('test6.SPP', r"""This is a .SPP file. +#as +#link +""") + +test.run(arguments = '.', stderr = None) + +test.fail_test(test.read('test1' + _exe) != "%s\nThis is a .s file.\n" % o) + +test.fail_test(test.read('test2' + _exe) != "%s\nThis is a .S file.\n" % o) + +test.fail_test(test.read('test3' + _exe) != "%s\nThis is a .asm file.\n" % o) + +test.fail_test(test.read('test4' + _exe) != "%s\nThis is a .ASM file.\n" % o) + +test.fail_test(test.read('test5' + _exe) != "%s\nThis is a .spp file.\n" % o) + +test.fail_test(test.read('test6' + _exe) != "%s\nThis is a .SPP file.\n" % o) + + + +test.pass_test()