summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSteven Knight <knight@baldmt.com>2003-01-22 13:51:44 (GMT)
committerSteven Knight <knight@baldmt.com>2003-01-22 13:51:44 (GMT)
commit301dbb53e3aa320ef6b8e635257a2acee1409f9c (patch)
tree404d6bacfc5573bc197806f73597765102d5497b /src
parentd09c74cccc89c9d58382ad7dcae6def5499da113 (diff)
downloadSCons-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.txt2
-rw-r--r--src/engine/MANIFEST.in3
-rw-r--r--src/engine/SCons/Tool/386asm.py72
-rw-r--r--src/engine/SCons/Tool/PharLapCommon.py124
-rw-r--r--src/engine/SCons/Tool/PharLapCommonTests.py55
-rw-r--r--src/engine/SCons/Tool/__init__.py6
-rw-r--r--src/engine/SCons/Tool/linkloc.py107
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')