diff options
author | Steven Knight <knight@baldmt.com> | 2003-01-22 13:51:44 (GMT) |
---|---|---|
committer | Steven Knight <knight@baldmt.com> | 2003-01-22 13:51:44 (GMT) |
commit | 301dbb53e3aa320ef6b8e635257a2acee1409f9c (patch) | |
tree | 404d6bacfc5573bc197806f73597765102d5497b /src | |
parent | d09c74cccc89c9d58382ad7dcae6def5499da113 (diff) | |
download | SCons-301dbb53e3aa320ef6b8e635257a2acee1409f9c.zip SCons-301dbb53e3aa320ef6b8e635257a2acee1409f9c.tar.gz SCons-301dbb53e3aa320ef6b8e635257a2acee1409f9c.tar.bz2 |
Add support for the PharLap ETS tools. (Charles Crain)
Diffstat (limited to 'src')
-rw-r--r-- | src/CHANGES.txt | 2 | ||||
-rw-r--r-- | src/engine/MANIFEST.in | 3 | ||||
-rw-r--r-- | src/engine/SCons/Tool/386asm.py | 72 | ||||
-rw-r--r-- | src/engine/SCons/Tool/PharLapCommon.py | 124 | ||||
-rw-r--r-- | src/engine/SCons/Tool/PharLapCommonTests.py | 55 | ||||
-rw-r--r-- | src/engine/SCons/Tool/__init__.py | 6 | ||||
-rw-r--r-- | src/engine/SCons/Tool/linkloc.py | 107 |
7 files changed, 366 insertions, 3 deletions
diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 83dbc9a..1f5a6d5 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -15,6 +15,8 @@ RELEASE 0.11 - XXX - Added new AddPreAction() and AddPostAction() functions that support taking additional actions before or after building specific targets. + - Add support for the PharLap ETS tool chain. + From Steven Knight: - Allow Python function Actions to specify a list of construction diff --git a/src/engine/MANIFEST.in b/src/engine/MANIFEST.in index cf27274..a51277b 100644 --- a/src/engine/MANIFEST.in +++ b/src/engine/MANIFEST.in @@ -30,6 +30,7 @@ SCons/Sig/MD5.py SCons/Sig/TimeStamp.py SCons/Taskmaster.py SCons/Tool/__init__.py +SCons/Tool/386asm.py SCons/Tool/ar.py SCons/Tool/default.py SCons/Tool/dvipdf.py @@ -44,6 +45,7 @@ SCons/Tool/ifl.py SCons/Tool/ilink.py SCons/Tool/latex.py SCons/Tool/lex.py +SCons/Tool/linkloc.py SCons/Tool/masm.py SCons/Tool/mingw.py SCons/Tool/mslib.py @@ -52,6 +54,7 @@ SCons/Tool/msvc.py SCons/Tool/nasm.py SCons/Tool/pdflatex.py SCons/Tool/pdftex.py +SCons/Tool/PharLapCommon.py SCons/Tool/tar.py SCons/Tool/tex.py SCons/Tool/yacc.py diff --git a/src/engine/SCons/Tool/386asm.py b/src/engine/SCons/Tool/386asm.py new file mode 100644 index 0000000..c07f856 --- /dev/null +++ b/src/engine/SCons/Tool/386asm.py @@ -0,0 +1,72 @@ +"""SCons.Tool.386asm + +Tool specification for the 386ASM assembler for the Phar Lap ETS embedded +operating system. + +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__ +# +# 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 string +import re + +import SCons.Action +import SCons.Defaults +import SCons.Tool + +from SCons.Tool.PharLapCommon import addPharLapPaths + +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 ar 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'] = '386asm' + env['ASFLAGS'] = '' + env['ASCOM'] = '$AS $ASFLAGS $SOURCES -o $TARGET' + env['ASPPCOM'] = '$CC $ASFLAGS $CPPFLAGS $SOURCES -o $TARGET' + + addPharLapPaths(env) + +def exists(env): + return env.Detect('386asm') diff --git a/src/engine/SCons/Tool/PharLapCommon.py b/src/engine/SCons/Tool/PharLapCommon.py new file mode 100644 index 0000000..ddcaba6 --- /dev/null +++ b/src/engine/SCons/Tool/PharLapCommon.py @@ -0,0 +1,124 @@ +"""SCons.Tool.PharLapCommon + +This module contains common code used by all Tools for the +Phar Lap ETS tool chain. Right now, this is linkloc and +386asm. + +""" + +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import os +import os.path +import SCons.Errors +import SCons.Util +import re +import string + +def getPharLapPath(): + """Reads the registry to find the installed path of the Phar Lap ETS + development kit. + + Raises UserError if no installed version of Phar Lap can + be found.""" + + if not SCons.Util.can_read_reg: + raise SCons.Errors.InternalError, "No Windows registry module was found" + try: + k=SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE, + 'SOFTWARE\\Pharlap\\ETS') + val, type = SCons.Util.RegQueryValueEx(k, 'BaseDir') + + # The following is a hack...there is (not surprisingly) + # an odd issue in the Phar Lap plug in that inserts + # a bunch of junk data after the phar lap path in the + # registry. We must trim it. + idx=val.find('\0') + if idx >= 0: + val = val[:idx] + + return os.path.normpath(val) + except SCons.Util.RegError: + raise SCons.Errors.UserError, "Cannot find Phar Lap ETS path in the registry. Is it installed properly?" + +REGEX_ETS_VER = re.compile(r'#define\s+ETS_VER\s+([0-9]+)') + +def getPharLapVersion(): + """Returns the version of the installed ETS Tool Suite as a + decimal number. This version comes from the ETS_VER #define in + the embkern.h header. For example, '#define ETS_VER 1010' (which + is what Phar Lap 10.1 defines) would cause this method to return + 1010. Phar Lap 9.1 does not have such a #define, but this method + will return 910 as a default. + + Raises UserError if no installed version of Phar Lap can + be found.""" + + include_path = os.path.join(getPharLapPath(), os.path.normpath("include/embkern.h")) + if not os.path.exists(include_path): + raise SCons.Errors.UserError, "Cannot find embkern.h in ETS include directory.\nIs Phar Lap ETS installed properly?" + mo = REGEX_ETS_VER.search(open(include_path, 'r').read()) + if mo: + return int(mo.group(1)) + # Default return for Phar Lap 9.1 + return 910 + +def addPathIfNotExists(env_dict, key, path, sep=os.pathsep): + """This function will take 'key' out of the dictionary + 'env_dict', then add the path 'path' to that key if it is not + already there. This treats the value of env_dict[key] as if it + has a similar format to the PATH variable...a list of paths + separated by tokens. The 'path' will get added to the list if it + is not already there.""" + try: + paths = string.split(env_dict[key], sep) + if not os.path.normcase(path) in map(os.path.normcase, paths): + env_dict[key] = string.join([ path ] + paths, sep) + except KeyError: + env_dict[key] = path + +def addPharLapPaths(env): + """This function adds the path to the Phar Lap binaries, includes, + and libraries, if they are not already there.""" + ph_path = getPharLapPath() + + try: + env_dict = env['ENV'] + except KeyError: + env_dict = {} + env['ENV'] = env_dict + addPathIfNotExists(env_dict, 'PATH', + os.path.join(ph_path, 'bin')) + addPathIfNotExists(env_dict, 'INCLUDE', + os.path.join(ph_path, 'include')) + addPathIfNotExists(env_dict, 'LIB', + os.path.join(ph_path, 'lib')) + addPathIfNotExists(env_dict, 'LIB', + os.path.join(ph_path, os.path.normpath('lib/vclib'))) + + env['PHARLAP_PATH'] = getPharLapPath() + env['PHARLAP_VERSION'] = str(getPharLapVersion()) + diff --git a/src/engine/SCons/Tool/PharLapCommonTests.py b/src/engine/SCons/Tool/PharLapCommonTests.py new file mode 100644 index 0000000..663b25e --- /dev/null +++ b/src/engine/SCons/Tool/PharLapCommonTests.py @@ -0,0 +1,55 @@ +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import unittest +import os.path +import os +import sys + +import SCons.Errors +from SCons.Tool.PharLapCommon import * + +class PharLapCommonTestCase(unittest.TestCase): + def test_addPathIfNotExists(self): + """Test the addPathIfNotExists() function""" + env_dict = { 'FOO' : os.path.normpath('/foo/bar') + os.pathsep + \ + os.path.normpath('/baz/blat'), + 'BAR' : os.path.normpath('/foo/bar') + os.pathsep + \ + os.path.normpath('/baz/blat') } + addPathIfNotExists(env_dict, 'FOO', os.path.normpath('/foo/bar')) + addPathIfNotExists(env_dict, 'BAR', os.path.normpath('/bar/foo')) + addPathIfNotExists(env_dict, 'BAZ', os.path.normpath('/foo/baz')) + + assert env_dict['FOO'] == os.path.normpath('/foo/bar') + os.pathsep + \ + os.path.normpath('/baz/blat'), env_dict['FOO'] + assert env_dict['BAR'] == os.path.normpath('/bar/foo') + os.pathsep + \ + os.path.normpath('/foo/bar') + os.pathsep + \ + os.path.normpath('/baz/blat'), env_dict['BAR'] + assert env_dict['BAZ'] == os.path.normpath('/foo/baz'), env_dict['BAZ'] + +if __name__ == "__main__": + suite = unittest.makeSuite(PharLapCommonTestCase, 'test_') + if not unittest.TextTestRunner().run(suite).wasSuccessful(): + sys.exit(1) diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py index 3621826..50ab456 100644 --- a/src/engine/SCons/Tool/__init__.py +++ b/src/engine/SCons/Tool/__init__.py @@ -145,9 +145,9 @@ def tool_list(platform, env): # the tool files themselves. if str(platform) == 'win32': "prefer Microsoft tools on Windows" - linkers = ['mslink', 'gnulink', 'ilink'] - c_compilers = ['msvc', 'mingw', 'gcc', 'icc'] - assemblers = ['masm', 'nasm', 'gas'] + linkers = ['mslink', 'gnulink', 'ilink', 'linkloc' ] + c_compilers = ['msvc', 'mingw', 'gcc', 'icc' ] + assemblers = ['masm', 'nasm', 'gas', '386asm' ] fortran_compilers = ['g77', 'ifl'] ars = ['mslib', 'ar'] elif str(platform) == 'os2': diff --git a/src/engine/SCons/Tool/linkloc.py b/src/engine/SCons/Tool/linkloc.py new file mode 100644 index 0000000..51ce60c --- /dev/null +++ b/src/engine/SCons/Tool/linkloc.py @@ -0,0 +1,107 @@ +"""SCons.Tool.linkloc + +Tool specification for the LinkLoc linker for the Phar Lap ETS embedded +operating system. + +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__ +# +# 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 string +import re + +import SCons.Action +import SCons.Defaults +import SCons.Errors +import SCons.Util + +from SCons.Platform.win32 import TempFileMunge +from SCons.Tool.msvc import get_msdev_paths +from SCons.Tool.PharLapCommon import addPharLapPaths + +_re_linker_command = re.compile(r'(\s)@\s*([^\s]+)') + +def repl_linker_command(m): + # Replaces any linker command file directives (e.g. "@foo.lnk") with + # the actual contents of the file. + try: + f=open(m.group(2), "r") + return m.group(1) + f.read() + except IOError: + # the linker should return an error if it can't + # find the linker command file so we will remain quiet. + # However, we will replace the @ with a # so we will not continue + # to find it with recursive substitution + return m.group(1) + '#' + m.group(2) + +class LinklocGenerator: + def __init__(self, cmdline): + self.cmdline = cmdline + + def __call__(self, env, target, source, for_signature): + if for_signature: + # Expand the contents of any linker command files recursively + subs = 1 + strsub = env.subst(self.cmdline) + while subs: + strsub, subs = _re_linker_command.subn(repl_linker_command, strsub) + return strsub + else: + return TempFileMunge(env, string.split(self.cmdline), 0) + +_linklocLinkAction = SCons.Action.Action(SCons.Action.CommandGenerator(LinklocGenerator("$LINK $LINKFLAGS $( $_LIBDIRFLAGS $) $_LIBFLAGS -exe $TARGET $SOURCES"))) +_linklocShLinkAction = SCons.Action.Action(SCons.Action.CommandGenerator(LinklocGenerator("$SHLINK $SHLINKFLAGS $( $_LIBDIRFLAGS $) $_LIBFLAGS -dll $TARGET $SOURCES"))) + +def generate(env, platform): + """Add Builders and construction variables for ar to an Environment.""" + env['BUILDERS']['SharedLibrary'] = SCons.Defaults.SharedLibrary + env['BUILDERS']['Program'] = SCons.Defaults.Program + + env['SHLINK'] = '$LINK' + env['SHLINKFLAGS'] = '$LINKFLAGS' + env['SHLINKCOM'] = _linklocShLinkAction + env['SHLIBEMITTER']= None + env['LINK'] = "linkloc" + env['LINKFLAGS'] = '' + env['LINKCOM'] = _linklocLinkAction + env['LIBDIRPREFIX']='-libpath ' + env['LIBDIRSUFFIX']='' + env['LIBLINKPREFIX']='-lib ' + env['LIBLINKSUFFIX']='$LIBSUFFIX' + + include_path, lib_path, exe_path = get_msdev_paths() + env['ENV']['LIB'] = lib_path + env['ENV']['PATH'] = exe_path + + addPharLapPaths(env) + +def exists(env): + return env.Detect('linkloc') |