Add support for new tools: Metroworks CodeWarrior compiler and linker (Russell Yanof...
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Fri, 19 Nov 2004 12:04:49 +0000 (12:04 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Fri, 19 Nov 2004 12:04:49 +0000 (12:04 +0000)
git-svn-id: http://scons.tigris.org/svn/scons/trunk@1167 fdb21ef1-2011-0410-befe-b5e4ea1792b1

doc/man/scons.1
src/CHANGES.txt
src/engine/MANIFEST.in
src/engine/SCons/Tool/__init__.py
src/engine/SCons/Tool/icl.py
src/engine/SCons/Tool/intelc.py [new file with mode: 0644]
src/engine/SCons/Tool/mwcc.py [new file with mode: 0644]
src/engine/SCons/Tool/mwld.py [new file with mode: 0644]
test/import.py

index b018e9842e2be6d696833de60a1c9f499c1b5df3..035af89594d48bebcbbc2c5459aa35f1f894ea6d 100644 (file)
@@ -1097,6 +1097,7 @@ ifl
 ifort
 ilink
 ilink32
+intelc
 jar
 javac
 javah
@@ -1112,6 +1113,8 @@ mslib
 mslink
 msvc
 msvs
+mwcc
+mwld
 nasm
 pdflatex
 pdftex
@@ -5873,6 +5876,14 @@ and
 .B .dsw
 when using earlier versions of Visual Studio.
 
+.IP MWCW_VERSION
+The version number of the MetroWerks CodeWarrior C compiler
+to be used.
+
+.IP MWCW_VERSIONS
+A list of installed versions of the MetroWerks CodeWarrior C compiler
+on this system.
+
 .IP no_import_lib
 When set to non-zero,
 suppresses creation of a corresponding Win32 static import lib by the
index 6bb6d09d80b62e27ce01f553f03730535a522c21..5a5c466277d1edab451b07c77782457b95b9d24b 100644 (file)
@@ -193,6 +193,11 @@ RELEASE 0.97 - XXX
   - Avoid copying __builtin__ values into a construction environment's
     dictionary when evaluating construction variables.
 
+  - Add a new cross-platform intelc.py Tool that can detect and configure
+    the Intel C++ v8 compiler on both Windows, where it's named icl,
+    and Linux, where it's named icc.  (Niall Douglas contributed an
+    early prototype of parts of this module.)
+
   From Chris Pawling:
 
   - Have the linkloc tool use $MSVS_VERSION to select the Microsoft
@@ -343,6 +348,11 @@ RELEASE 0.97 - XXX
   - Have the Qt Builder make uic-generated files dependent on the .ui.h
     file, if one exists.
 
+  From Russell Yanofsky:
+
+  - Add support for the Metrowerks Codewarrior compiler and linker
+    (mwcc and mwld).
+
 
 
 RELEASE 0.96.1 - XXX
index c93ac21f097f5ded1933289232cb33c6f8288ec6..b8ce8b667f7dcc379f3c89e7c8b64ca82f80fa48 100644 (file)
@@ -89,6 +89,7 @@ SCons/Tool/ifl.py
 SCons/Tool/ifort.py
 SCons/Tool/ilink.py
 SCons/Tool/ilink32.py
+SCons/Tool/intelc.py
 SCons/Tool/latex.py
 SCons/Tool/lex.py
 SCons/Tool/link.py
@@ -101,6 +102,8 @@ SCons/Tool/mslib.py
 SCons/Tool/mslink.py
 SCons/Tool/msvc.py
 SCons/Tool/msvs.py
+SCons/Tool/mwcc.py
+SCons/Tool/mwld.py
 SCons/Tool/nasm.py
 SCons/Tool/pdflatex.py
 SCons/Tool/pdftex.py
index 71ef082874363a72258bd28e12f644023582df19..2c793d97bed05c80f2b968e947909a458652773a 100644 (file)
@@ -264,8 +264,8 @@ def tool_list(platform, env):
     if str(platform) == 'win32':
         "prefer Microsoft tools on Windows"
         linkers = ['mslink', 'gnulink', 'ilink', 'linkloc', 'ilink32' ]
-        c_compilers = ['msvc', 'mingw', 'gcc', 'icl', 'icc', 'cc', 'bcc32' ]
-        cxx_compilers = ['msvc', 'icc', 'g++', 'c++', 'bcc32' ]
+        c_compilers = ['msvc', 'mingw', 'gcc', 'intelc', 'icl', 'icc', 'cc', 'bcc32' ]
+        cxx_compilers = ['msvc', 'intelc', 'icc', 'g++', 'c++', 'bcc32' ]
         assemblers = ['masm', 'nasm', 'gas', '386asm' ]
         fortran_compilers = ['g77', 'ifl', 'cvf', 'fortran']
         ars = ['mslib', 'ar', 'tlib']
@@ -312,8 +312,8 @@ def tool_list(platform, env):
     else:
         "prefer GNU tools on all other platforms"
         linkers = ['gnulink', 'mslink', 'ilink']
-        c_compilers = ['gcc', 'msvc', 'icc', 'cc']
-        cxx_compilers = ['g++', 'msvc', 'icc', 'c++']
+        c_compilers = ['gcc', 'msvc', 'intelc', 'icc', 'cc']
+        cxx_compilers = ['g++', 'msvc', 'intelc', 'icc', 'c++']
         assemblers = ['gas', 'nasm', 'masm']
         fortran_compilers = ['g77', 'ifort', 'ifl', 'fortran']
         ars = ['ar', 'mslib']
@@ -332,7 +332,7 @@ def tool_list(platform, env):
         ar = None
     else:
         # Don't use g++ if the C compiler has built-in C++ support:
-        if c_compiler in ('msvc', 'icc'):
+        if c_compiler in ('msvc', 'intelc', 'icc'):
             cxx_compiler = None
         else:
             cxx_compiler = FindTool(cxx_compilers, env) or cxx_compilers[0]
@@ -345,13 +345,15 @@ def tool_list(platform, env):
                                 'dmd',
                                 'dvipdf', 'dvips', 'gs',
                                 'jar', 'javac', 'javah',
-                                'latex', 'lex', 'm4', 'midl', 'msvs',
+                                'latex', 'lex',
+                                'm4', 'midl', 'msvs',
                                 'pdflatex', 'pdftex', 'Perforce',
                                 'RCS', 'rmic', 'rpcgen',
                                 'SCCS',
                                 # 'Subversion',
                                 'swig',
-                                'tar', 'tex', 'yacc', 'zip'],
+                                'tar', 'tex',
+                                'yacc', 'zip'],
                                env)
 
     tools = ([linker, c_compiler, cxx_compiler,
index eeed44743b0c5f51ae4f5f1f47c8ef70c82cd965..8d7aea74b565afc22eec9e674ac0b0c4febd6311 100644 (file)
@@ -33,106 +33,14 @@ selection method.
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
-import os.path
+import SCons.Tool.intelc
 
-import SCons.Tool.msvc
-import SCons.Util
-import SCons.Warnings
+# This has been completely superceded by intelc.py, which can
+# handle both Windows and Linux versions.
 
-# Find Intel compiler:
-# Could enumerate subkeys here to be more flexible.
-def get_intel_compiler_top(version):
-    """
-    Return the main path to the top-level dir of the Intel compiler,
-    using the given version or latest if 0.
-    The compiler will be in <top>/Bin/icl.exe,
-    the include dir is <top>/Include, etc.
-    """
-
-    if version == 0:
-        version = "7.0"                   # XXX: should scan for latest
-
-    if not SCons.Util.can_read_reg:
-        raise SCons.Errors.InternalError, "No Windows registry module was found"
-
-    K = ('Software\\Intel\\' +
-         'Intel(R) C/C++ Compiler for 32-bit apps, Version ' + version)
-    # Note: v5 had slightly different key:
-    #  HKCU\Software\Intel\Intel C/C++ Compiler for 32-bit apps, Version 5.0
-    # Note no (R).
-    try:
-        k = SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_CURRENT_USER, K)
-    except SCons.Util.RegError:
-        return None
-
-    try:
-        # On my machine, this returns:
-        #  c:\Program Files\Intel\Compiler70
-        top = SCons.Util.RegQueryValueEx(k, "Directory")[0]
-    except SCons.Util.RegError:
-        raise SCons.Errors.InternalError, "%s was not found in the registry."%K
-
-    if os.path.exists(os.path.join(top, "ia32")):
-        top = os.path.join(top, "ia32")
-
-    if not os.path.exists(os.path.join(top, "Bin", "icl.exe")):
-        raise SCons.Errors.InternalError, "Can't find Intel compiler in %s"%top
-
-    return top
-
-
-def generate(env):
+def generate(*args, **kw):
     """Add Builders and construction variables for icl to an Environment."""
-    SCons.Tool.msvc.generate(env)
-
-    try:
-        icltop = get_intel_compiler_top(0)
-    except (SCons.Util.RegError, SCons.Errors.InternalError):
-        icltop = None
-
-    if icltop:
-        env.PrependENVPath('INCLUDE', os.path.join(icltop, 'Include'))
-        env.PrependENVPath('LIB', os.path.join(icltop, 'Lib'))
-        env.PrependENVPath('PATH', os.path.join(icltop, 'Bin'))
-
-    env['CC']        = 'icl'
-    env['CXX']        = 'icl'
-    env['LINK']        = 'xilink'
-
-    # Look for license file dir.
-    envlicdir = os.environ.get("INTEL_LICENSE_FILE", '')
-    K = ('SOFTWARE\Intel\Licenses')
-    try:
-        k = SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE, K)
-        reglicdir = SCons.Util.RegQueryValueEx(k, "w_cpp")[0]
-    except (AttributeError, SCons.Util.RegError):
-        reglicdir = ""
-    defaultlicdir = r'C:\Program Files\Common Files\Intel\Licenses'
-
-    licdir = None
-    for ld in [envlicdir, reglicdir]:
-        if ld and os.path.exists(ld):
-            licdir = ld
-            break
-    if not licdir:
-        licdir = defaultlicdir
-        if not os.path.exists(licdir):
-            class ICLLicenseDirWarning(SCons.Warnings.Warning):
-                pass
-            SCons.Warnings.enableWarningClass(ICLLicenseDirWarning)
-            SCons.Warnings.warn(ICLLicenseDirWarning,
-                                "Intel license dir was not found."
-                                "  Tried using the INTEL_LICENSE_FILE environment variable (%s), the registry (%s) and the default path (%s)."
-                                "  Using the default path as a last resort."
-                                    % (envlicdir, reglicdir, defaultlicdir))
-    env['ENV']['INTEL_LICENSE_FILE'] = licdir
-
-def exists(env):
-    try:
-        top = get_intel_compiler_top(0)
-    except (SCons.Util.RegError, SCons.Errors.InternalError):
-        top = None
+    return apply(SCons.Tool.intelc.generate, args, kw)
 
-    if not top:
-        return env.Detect('icl')
-    return top is not None
+def exists(*args, **kw):
+    return apply(SCons.Tool.intelc.exists, args, kw)
diff --git a/src/engine/SCons/Tool/intelc.py b/src/engine/SCons/Tool/intelc.py
new file mode 100644 (file)
index 0000000..f979700
--- /dev/null
@@ -0,0 +1,250 @@
+"""SCons.Tool.icl
+
+Tool-specific initialization for the Intel C/C++ compiler.
+Supports Linux and Windows compilers, v7 and up.
+
+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 sys, os.path, glob, re
+
+is_win32 = sys.platform == 'win32'
+is_linux = sys.platform == 'linux2'
+
+if is_win32:
+    import SCons.Tool.msvc
+elif is_linux:
+    import SCons.Tool.gcc
+import SCons.Util
+import SCons.Warnings
+
+
+def fltcmp(a, b):
+    """Compare strings as floats"""
+    return cmp(float(b), float(a))
+
+def get_intel_registry_value(valuename, version=None, abi=None):
+    """
+    Return a value from the Intel compiler registry tree. (Win32 only)
+    """
+
+    # Open the key:
+    K = 'Software\\Intel\\Compilers\\C++\\' + version + '\\'+abi.upper()
+    try:
+        k = SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE, K)
+    except SCons.Util.RegError:
+        raise SCons.Errors.InternalError, \
+              "%s was not found in the registry, for Intel compiler version %s"%(K, version)
+
+    # Get the value:
+    try:
+        v = SCons.Util.RegQueryValueEx(k, valuename)[0]
+        return v  # or v.encode('iso-8859-1', 'replace') to remove unicode?
+    except SCons.Util.RegError:
+        raise SCons.Errors.InternalError, \
+              "%s\\%s was not found in the registry."%(K, value)
+
+
+def get_all_compiler_versions():
+    """Returns a sorted list of strings, like "70" or "80"
+    with most recent compiler version first.
+    """
+    versions=[]
+    if is_win32:
+        keyname = 'Software\\Intel\\Compilers\\C++'
+        k = SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE,
+                                    keyname)
+        i = 0
+        versions = []
+        try:
+            while i < 100:
+                subkey = SCons.Util.RegEnumKey(k, i) # raises EnvironmentError
+                versions.append(subkey)
+                i = i + 1
+        except EnvironmentError:
+            # no more subkeys
+            pass
+    elif is_linux:
+        # Typical dir here is /opt/intel_cc_80.
+        for d in glob.glob('/opt/intel_cc_*'):
+            versions.append(re.search(r'cc_(.*)$', d).group(1))
+    versions.sort(fltcmp)
+    return versions
+
+def get_intel_compiler_top(version=None, abi=None):
+    """
+    Return the main path to the top-level dir of the Intel compiler,
+    using the given version or latest if None.
+    The compiler will be in <top>/bin/icl.exe (icc on linux),
+    the include dir is <top>/include, etc.
+    """
+
+    if is_win32:
+        if not SCons.Util.can_read_reg:
+            raise SCons.Errors.InternalError, "No Windows registry module was found"
+        top = get_intel_registry_value('ProductDir', version, abi)
+
+        if not os.path.exists(os.path.join(top, "Bin", "icl.exe")):
+            raise SCons.Errors.InternalError, \
+                  "Can't find Intel compiler in %s"%(top)
+    elif is_linux:
+        top = '/opt/intel_cc_%s'%version
+        if not os.path.exists(os.path.join(top, "bin", "icc")):
+            raise SCons.Errors.InternalError, \
+                  "Can't find version %s Intel compiler in %s"%(version,top)
+    return top
+
+
+def generate(env, version=None, abi=None, topdir=None, verbose=1):
+    """Add Builders and construction variables for Intel C/C++ compiler
+    to an Environment.
+    args:
+      version: (string) compiler version to use, like "80"
+      abi:     (string) 'win32' or whatever Itanium version wants
+      topdir:  (string) compiler top dir, like
+                         "c:\Program Files\Intel\Compiler70"
+                        If topdir is used, version and abi are ignored.
+      verbose: (int)    if >0, prints compiler version used.
+    """
+    if not (is_linux or is_win32):
+        # can't handle this platform
+        return
+
+    if is_win32:
+        SCons.Tool.msvc.generate(env)
+    elif is_linux:
+        SCons.Tool.gcc.generate(env)
+        
+    # if version is unspecified, use latest
+    vlist = get_all_compiler_versions()
+    if not version:
+        if vlist:
+            version = vlist[0]
+    else:
+        if version not in vlist:
+            raise SCons.Errors.UserError, \
+                  "Invalid Intel compiler version %s: "%version + \
+                  "installed versions are %s"%(', '.join(vlist))
+
+    # if abi is unspecified, use ia32 (ia64 is another possibility)
+    if abi is None:
+        abi = "ia32"                    # or ia64, I believe
+
+    if topdir is None:
+        try:
+            topdir = get_intel_compiler_top(version, abi)
+        except (SCons.Util.RegError, SCons.Errors.InternalError):
+            topdir = None
+
+    if topdir:
+
+        if verbose:
+            print "Intel C compiler: using version %s, abi %s, in '%s'"%(version,abi,topdir)
+
+        env['INTEL_C_COMPILER_TOP'] = topdir
+        if is_linux:
+            paths={'INCLUDE'         : 'include',
+                   'LIB'             : 'lib',
+                   'PATH'            : 'bin',
+                   'LD_LIBRARY_PATH' : 'lib'}
+            for p in paths:
+                env.PrependENVPath(p, os.path.join(topdir, paths[p]))
+        if is_win32:
+            #       env key    reg valname   default subdir of top
+            paths=(('INCLUDE', 'IncludeDir', 'Include'),
+                   ('LIB'    , 'LibDir',     'Lib'),
+                   ('PATH'   , 'BinDir',     'Bin'))
+            # Each path has a registry entry, use that or default to subdir
+            for p in paths:
+                try:
+                    path=get_intel_registry_value(p[1], version, abi)
+                    env.PrependENVPath(p[0], ';'.split(path))
+                    # print "ICL %s: %s, final=%s"%(p[0], path, str(env['ENV'][p[0]]))
+                except:
+                    env.PrependENVPath(p[0], os.path.join(topdir, p[2]))
+
+    if is_win32:
+        env['CC']        = 'icl'
+        env['CXX']       = 'icl'
+        env['LINK']      = 'xilink'
+    else:
+        env['CC']        = 'icc'
+        env['CXX']       = 'icpc'
+        env['LINK']      = '$CC'
+
+    if is_win32:
+        # Look for license file dir
+        # in system environment, registry, and default location.
+        envlicdir = os.environ.get("INTEL_LICENSE_FILE", '')
+        K = ('SOFTWARE\Intel\Licenses')
+        try:
+            k = SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE, K)
+            reglicdir = SCons.Util.RegQueryValueEx(k, "w_cpp")[0]
+        except (AttributeError, SCons.Util.RegError):
+            reglicdir = ""
+        defaultlicdir = r'C:\Program Files\Common Files\Intel\Licenses'
+
+        licdir = None
+        for ld in [envlicdir, reglicdir]:
+            if ld and os.path.exists(ld):
+                licdir = ld
+                break
+        if not licdir:
+            licdir = defaultlicdir
+            if not os.path.exists(licdir):
+                class ICLLicenseDirWarning(SCons.Warnings.Warning):
+                    pass
+                SCons.Warnings.enableWarningClass(ICLLicenseDirWarning)
+                SCons.Warnings.warn(ICLLicenseDirWarning,
+                                    "Intel license dir was not found."
+                                    "  Tried using the INTEL_LICENSE_FILE environment variable (%s), the registry (%s) and the default path (%s)."
+                                    "  Using the default path as a last resort."
+                                        % (envlicdir, reglicdir, defaultlicdir))
+        env['ENV']['INTEL_LICENSE_FILE'] = licdir
+
+def exists(env):
+    if not (is_linux or is_win32):
+        # can't handle this platform
+        return 0
+
+    try:
+        top = get_intel_compiler_top()
+    except (SCons.Util.RegError, SCons.Errors.InternalError):
+        top = None
+    if not top:
+        # try env.Detect, maybe that will work
+        if is_win32:
+            return env.Detect('icl')
+        elif is_linux:
+            return env.Detect('icc')
+    return top is not None
+
+# end of file
diff --git a/src/engine/SCons/Tool/mwcc.py b/src/engine/SCons/Tool/mwcc.py
new file mode 100644 (file)
index 0000000..52f55ee
--- /dev/null
@@ -0,0 +1,199 @@
+"""SCons.Tool.mwcc
+
+Tool-specific initialization for the Metrowerks CodeWarrior compiler.
+
+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 SCons.Util
+import os
+import os.path
+import string
+
+
+def set_vars(env):
+    """Set MWCW_VERSION, MWCW_VERSIONS, and some codewarrior environment vars
+
+    MWCW_VERSIONS is set to a list of objects representing installed versions
+
+    MWCW_VERSION  is set to the version object that will be used for building.
+                  MWCW_VERSION can be set to a string during Environment
+                  construction to influence which version is chosen, otherwise
+                  the latest one from MWCW_VERSIONS is used.
+
+    Returns true if at least one version is found, false otherwise
+    """
+    desired = env.get('MWCW_VERSION', '')
+
+    # return right away if the variables are already set
+    if isinstance(desired, MWVersion):
+        return 1
+    elif desired is None:
+        return 0
+
+    versions = find_versions()
+    version = None
+
+    if desired:
+        for v in versions:
+            if str(v) == desired:
+                version = v
+    elif versions:
+        version = versions[-1]
+
+    env['MWCW_VERSIONS'] = versions
+    env['MWCW_VERSION'] = version
+
+    if version is None:
+      return 0
+
+    env.PrependENVPath('PATH', version.clpath)
+    env.PrependENVPath('PATH', version.dllpath)
+    ENV = env['ENV']
+    ENV['CWFolder'] = version.path
+    ENV['LM_LICENSE_FILE'] = version.license
+    plus = lambda x: '+%s' % x
+    ENV['MWCIncludes'] = string.join(map(plus, version.includes), os.pathsep)
+    ENV['MWLibraries'] = string.join(map(plus, version.libs), os.pathsep)
+    return 1
+
+
+def find_versions():
+    """Return a list of MWVersion objects representing installed versions"""
+    versions = []
+
+    ### This function finds CodeWarrior by reading from the registry on
+    ### Windows. Some other method needs to be implemented for other
+    ### platforms, maybe something that calls env.WhereIs('mwcc')
+
+    if SCons.Util.can_read_reg:
+        try:
+            HLM = SCons.Util.HKEY_LOCAL_MACHINE
+            product = 'SOFTWARE\\Metrowerks\\CodeWarrior\\Product Versions'
+            product_key = SCons.Util.RegOpenKeyEx(HLM, product)
+
+            i = 0
+            while 1:
+                name = product + '\\' + SCons.Util.RegEnumKey(product_key, i)
+                name_key = SCons.Util.RegOpenKeyEx(HLM, name)
+
+                try:
+                    version = SCons.Util.RegQueryValueEx(name_key, 'VERSION')
+                    path = SCons.Util.RegQueryValueEx(name_key, 'PATH')
+                    mwv = MWVersion(version[0], path[0], 'Win32-X86')
+                    versions.append(mwv)
+                except SCons.Util.RegError:
+                    pass
+
+                i = i + 1
+
+        except SCons.Util.RegError:
+            pass
+
+    return versions
+
+
+class MWVersion:
+    def __init__(self, version, path, platform):
+        self.version = version
+        self.path = path
+        self.platform = platform
+        self.clpath = os.path.join(path, 'Other Metrowerks Tools',
+                                   'Command Line Tools')
+        self.dllpath = os.path.join(path, 'Bin')
+
+        # The Metrowerks tools don't store any configuration data so they
+        # are totally dumb when it comes to locating standard headers,
+        # libraries, and other files, expecting all the information
+        # to be handed to them in environment variables. The members set
+        # below control what information scons injects into the environment
+
+        ### The paths below give a normal build environment in CodeWarrior for
+        ### Windows, other versions of CodeWarrior might need different paths.
+
+        msl = os.path.join(path, 'MSL')
+        support = os.path.join(path, '%s Support' % platform)
+
+        self.license = os.path.join(path, 'license.dat')
+        self.includes = [msl, support]
+        self.libs = [msl, support]
+
+    def __str__(self):
+        return self.version
+
+
+CSuffixes = ['.c', '.C']
+CXXSuffixes = ['.cc', '.cpp', '.cxx', '.c++', '.C++']
+
+
+def generate(env):
+    """Add Builders and construction variables for the mwcc to an Environment."""
+
+    set_vars(env)
+
+    static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
+
+    for suffix in CSuffixes:
+        static_obj.add_action(suffix, SCons.Defaults.CAction)
+        shared_obj.add_action(suffix, SCons.Defaults.ShCAction)
+
+    for suffix in CXXSuffixes:
+        static_obj.add_action(suffix, SCons.Defaults.CXXAction)
+        shared_obj.add_action(suffix, SCons.Defaults.ShCXXAction)
+
+    env['CCCOMFLAGS'] = '$CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -nolink -o $TARGET $SOURCES'
+
+    env['CC']         = 'mwcc'
+    env['CCCOM']      = '$CC $CCFLAGS $CCCOMFLAGS'
+
+    env['CXX']        = 'mwcc'
+    env['CXXCOM']     = '$CXX $CXXFLAGS $CCCOMFLAGS'
+
+    env['SHCC']       = '$CC'
+    env['SHCCFLAGS']  = '$CCFLAGS'
+    env['SHCCCOM']    = '$SHCC $SHCCFLAGS $CCCOMFLAGS'
+
+    env['SHCXX']       = '$CXX'
+    env['SHCXXFLAGS']  = '$CXXFLAGS'
+    env['SHCXXCOM']    = '$SHCXX $SHCXXFLAGS $CCCOMFLAGS'
+
+    env['CFILESUFFIX'] = '.c'
+    env['CXXFILESUFFIX'] = '.cpp'
+    env['CPPDEFPREFIX']  = '-D'
+    env['CPPDEFSUFFIX']  = ''
+    env['INCPREFIX']  = '-I'
+    env['INCSUFFIX']  = ''
+
+    #env['PCH'] = ?
+    #env['PCHSTOP'] = ?
+
+
+def exists(env):
+    return set_vars(env)
diff --git a/src/engine/SCons/Tool/mwld.py b/src/engine/SCons/Tool/mwld.py
new file mode 100644 (file)
index 0000000..5e90a9c
--- /dev/null
@@ -0,0 +1,101 @@
+"""SCons.Tool.mwld
+
+Tool-specific initialization for the Metrowerks CodeWarrior linker.
+
+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 SCons.Tool
+import SCons.Tool.mwcc
+
+
+def generate(env):
+    """Add Builders and construction variables for lib to an Environment."""
+    SCons.Tool.createStaticLibBuilder(env)
+    SCons.Tool.createSharedLibBuilder(env)
+    SCons.Tool.createProgBuilder(env)
+
+    env['AR'] = 'mwld'
+    env['ARCOM'] = '$AR $ARFLAGS -library -o $TARGET $SOURCES'
+
+    env['LIBDIRPREFIX'] = '-L'
+    env['LIBDIRSUFFIX'] = ''
+    env['LIBLINKPREFIX'] = '-l'
+    env['LIBLINKSUFFIX'] = '.lib'
+
+    env['LINK'] = 'mwld'
+    env['LINKCOM'] = '$LINK $LINKFLAGS -o $TARGET $SOURCES $_LIBDIRFLAGS $_LIBFLAGS'
+
+    env['SHLINK'] = '$LINK'
+    env['SHLINKFLAGS'] = '$LINKFLAGS'
+    env['SHLINKCOM']   = shlib_action
+    env['SHLIBEMITTER']= shlib_emitter
+
+
+def exists(env):
+    return mwcc.set_versions(env)
+
+
+def shlib_generator(target, source, env, for_signature):
+    cmd = ['$SHLINK', '$SHLINKFLAGS', '-shared']
+
+    no_import_lib = env.get('no_import_lib', 0)
+    if no_import_lib: cmd.extend('-noimplib')
+
+    dll = env.FindIxes(target, 'SHLIBPREFIX', 'SHLIBSUFFIX')
+    if dll: cmd.extend(['-o', dll])
+
+    implib = env.FindIxes(target, 'LIBPREFIX', 'LIBSUFFIX')
+    if implib: cmd.extend(['-implib', implib.get_string(for_signature)])
+
+    cmd.extend(['$SOURCES', '$_LIBDIRFLAGS', '$_LIBFLAGS'])
+
+    return [cmd]
+
+
+def shlib_emitter(target, source, env):
+    dll = env.FindIxes(target, 'SHLIBPREFIX', 'SHLIBSUFFIX')
+    no_import_lib = env.get('no_import_lib', 0)
+
+    if not dll:
+        raise SCons.Errors.UserError, "A shared library should have exactly one target with the suffix: %s" % env.subst("$SHLIBSUFFIX")
+
+    if not no_import_lib and \
+       not env.FindIxes(target, 'LIBPREFIX', 'LIBSUFFIX'):
+
+        # Append an import library to the list of targets.
+        target.append(env.ReplaceIxes(dll,
+                                      'SHLIBPREFIX', 'SHLIBSUFFIX',
+                                      'LIBPREFIX', 'LIBSUFFIX'))
+
+    return target, source
+
+
+shlib_action = SCons.Action.CommandGenerator(shlib_generator)
index 0e72ec47a020bae8bbb51c7f8eced7a6205f1cdb..cfe72e6a214a5dc3e6d59d3241c965ca4c97820d 100644 (file)
@@ -90,6 +90,7 @@ tools = [
     'ifl',
     'ilink',
     'ilink32',
+    'intelc',
     'jar',
     'javac',
     'javah',
@@ -105,6 +106,8 @@ tools = [
     'mslink',
     'msvc',
     'msvs',
+    'mwcc',
+    'mwld',
     'nasm',
     'pdflatex',
     'pdftex',