summaryrefslogtreecommitdiff
path: root/src/engine/SCons/Tool/MSCommon
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine/SCons/Tool/MSCommon')
-rw-r--r--src/engine/SCons/Tool/MSCommon/__init__.py2
-rw-r--r--src/engine/SCons/Tool/MSCommon/arch.py4
-rw-r--r--src/engine/SCons/Tool/MSCommon/common.py62
-rw-r--r--src/engine/SCons/Tool/MSCommon/netframework.py10
-rw-r--r--src/engine/SCons/Tool/MSCommon/sdk.py22
-rw-r--r--src/engine/SCons/Tool/MSCommon/vc.py182
-rw-r--r--src/engine/SCons/Tool/MSCommon/vc.py.bak394
-rw-r--r--src/engine/SCons/Tool/MSCommon/vs.py36
8 files changed, 196 insertions, 516 deletions
diff --git a/src/engine/SCons/Tool/MSCommon/__init__.py b/src/engine/SCons/Tool/MSCommon/__init__.py
index a612d9b..6389078 100644
--- a/src/engine/SCons/Tool/MSCommon/__init__.py
+++ b/src/engine/SCons/Tool/MSCommon/__init__.py
@@ -21,7 +21,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/MSCommon/__init__.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/MSCommon/__init__.py 5023 2010/06/14 22:05:46 scons"
__doc__ = """
Common functions for Microsoft Visual Studio and Visual C/C++.
diff --git a/src/engine/SCons/Tool/MSCommon/arch.py b/src/engine/SCons/Tool/MSCommon/arch.py
index 34de46c..ba6d2d6 100644
--- a/src/engine/SCons/Tool/MSCommon/arch.py
+++ b/src/engine/SCons/Tool/MSCommon/arch.py
@@ -21,14 +21,14 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/MSCommon/arch.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/MSCommon/arch.py 5023 2010/06/14 22:05:46 scons"
__doc__ = """Module to define supported Windows chip architectures.
"""
import os
-class ArchDefinition:
+class ArchDefinition(object):
"""
A class for defining architecture-specific settings and logic.
"""
diff --git a/src/engine/SCons/Tool/MSCommon/common.py b/src/engine/SCons/Tool/MSCommon/common.py
index 2303d2b..ef1aae9 100644
--- a/src/engine/SCons/Tool/MSCommon/common.py
+++ b/src/engine/SCons/Tool/MSCommon/common.py
@@ -21,7 +21,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/MSCommon/common.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/MSCommon/common.py 5023 2010/06/14 22:05:46 scons"
__doc__ = """
Common helper functions for working with the Microsoft tool chain.
@@ -99,46 +99,78 @@ def has_reg(value):
# Functions for fetching environment variable settings from batch files.
-def normalize_env(env, keys):
+def normalize_env(env, keys, force=False):
"""Given a dictionary representing a shell environment, add the variables
from os.environ needed for the processing of .bat files; the keys are
controlled by the keys argument.
It also makes sure the environment values are correctly encoded.
- Note: the environment is copied"""
+ If force=True, then all of the key values that exist are copied
+ into the returned dictionary. If force=false, values are only
+ copied if the key does not already exist in the copied dictionary.
+
+ Note: the environment is copied."""
normenv = {}
if env:
for k in env.keys():
normenv[k] = copy.deepcopy(env[k]).encode('mbcs')
for k in keys:
- if os.environ.has_key(k):
+ if k in os.environ and (force or not k in normenv):
normenv[k] = os.environ[k].encode('mbcs')
return normenv
def get_output(vcbat, args = None, env = None):
"""Parse the output of given bat file, with given args."""
+
+ if env is None:
+ # Create a blank environment, for use in launching the tools
+ env = SCons.Environment.Environment(tools=[])
+
+ # TODO: This is a hard-coded list of the variables that (may) need
+ # to be imported from os.environ[] for v[sc]*vars*.bat file
+ # execution to work. This list should really be either directly
+ # controlled by vc.py, or else derived from the common_tools_var
+ # settings in vs.py.
+ vars = [
+ 'COMSPEC',
+ 'VS90COMNTOOLS',
+ 'VS80COMNTOOLS',
+ 'VS71COMNTOOLS',
+ 'VS70COMNTOOLS',
+ 'VS60COMNTOOLS',
+ ]
+ env['ENV'] = normalize_env(env['ENV'], vars, force=False)
+
if args:
debug("Calling '%s %s'" % (vcbat, args))
- popen = subprocess.Popen('"%s" %s & set' % (vcbat, args),
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- env=env)
+ popen = SCons.Action._subproc(env,
+ '"%s" %s & set' % (vcbat, args),
+ stdin = 'devnull',
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
else:
debug("Calling '%s'" % vcbat)
- popen = subprocess.Popen('"%s" & set' % vcbat,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- env=env)
+ popen = SCons.Action._subproc(env,
+ '"%s" & set' % vcbat,
+ stdin = 'devnull',
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
# Use the .stdout and .stderr attributes directly because the
# .communicate() method uses the threading module on Windows
# and won't work under Pythons not built with threading.
stdout = popen.stdout.read()
+ stderr = popen.stderr.read()
+ if stderr:
+ # TODO: find something better to do with stderr;
+ # this at least prevents errors from getting swallowed.
+ import sys
+ sys.stderr.write(stderr)
if popen.wait() != 0:
- raise IOError(popen.stderr.read().decode("mbcs"))
+ raise IOError(stderr.decode("mbcs"))
output = stdout.decode("mbcs")
return output
@@ -147,9 +179,7 @@ def parse_output(output, keep = ("INCLUDE", "LIB", "LIBPATH", "PATH")):
# dkeep is a dict associating key: path_list, where key is one item from
# keep, and pat_list the associated list of paths
- # TODO(1.5): replace with the following list comprehension:
- #dkeep = dict([(i, []) for i in keep])
- dkeep = dict(map(lambda i: (i, []), keep))
+ dkeep = dict([(i, []) for i in keep])
# rdk will keep the regex to match the .bat file output line starts
rdk = {}
diff --git a/src/engine/SCons/Tool/MSCommon/netframework.py b/src/engine/SCons/Tool/MSCommon/netframework.py
index bd123dc..30be811 100644
--- a/src/engine/SCons/Tool/MSCommon/netframework.py
+++ b/src/engine/SCons/Tool/MSCommon/netframework.py
@@ -19,16 +19,14 @@
# 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__ = "src/engine/SCons/Tool/MSCommon/netframework.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/MSCommon/netframework.py 5023 2010/06/14 22:05:46 scons"
__doc__ = """
"""
import os
import re
-import string
from common import read_reg, debug
@@ -58,14 +56,14 @@ def query_versions():
contents = os.listdir(froot)
l = re.compile('v[0-9]+.*')
- versions = filter(lambda e, l=l: l.match(e), contents)
+ versions = [e for e in contents if l.match(e)]
def versrt(a,b):
# since version numbers aren't really floats...
aa = a[1:]
bb = b[1:]
- aal = string.split(aa, '.')
- bbl = string.split(bb, '.')
+ aal = aa.split('.')
+ bbl = bb.split('.')
# sequence comparison in python is lexicographical
# which is exactly what we want.
# Note we sort backwards so the highest version is first.
diff --git a/src/engine/SCons/Tool/MSCommon/sdk.py b/src/engine/SCons/Tool/MSCommon/sdk.py
index 54be8ca..6debeb6 100644
--- a/src/engine/SCons/Tool/MSCommon/sdk.py
+++ b/src/engine/SCons/Tool/MSCommon/sdk.py
@@ -21,7 +21,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/MSCommon/sdk.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/MSCommon/sdk.py 5023 2010/06/14 22:05:46 scons"
__doc__ = """Module to detect the Platform/Windows SDK
@@ -58,7 +58,7 @@ _CURINSTALLED_SDK_HKEY_ROOT = \
r"Software\Microsoft\Microsoft SDKs\Windows\CurrentInstallFolder"
-class SDKDefinition:
+class SDKDefinition(object):
"""
An abstract base class for trying to find installed SDK directories.
"""
@@ -131,7 +131,7 @@ class WindowsSDK(SDKDefinition):
"""
HKEY_FMT = r'Software\Microsoft\Microsoft SDKs\Windows\v%s\InstallationFolder'
def __init__(self, *args, **kw):
- apply(SDKDefinition.__init__, (self,)+args, kw)
+ SDKDefinition.__init__(self, *args, **kw)
self.hkey_data = self.version
class PlatformSDK(SDKDefinition):
@@ -140,7 +140,7 @@ class PlatformSDK(SDKDefinition):
"""
HKEY_FMT = r'Software\Microsoft\MicrosoftSDK\InstalledSDKS\%s\Install Dir'
def __init__(self, *args, **kw):
- apply(SDKDefinition.__init__, (self,)+args, kw)
+ SDKDefinition.__init__(self, *args, **kw)
self.hkey_data = self.uuid
#
@@ -310,9 +310,9 @@ def get_cur_sdk_dir_from_reg():
return val
def get_sdk_by_version(mssdk):
- if not SupportedSDKMap.has_key(mssdk):
+ if mssdk not in SupportedSDKMap:
msg = "SDK version %s is not supported" % repr(mssdk)
- raise SCons.Errors.UserError, msg
+ raise SCons.Errors.UserError(msg)
get_installed_sdks()
return InstalledSDKMap.get(mssdk)
@@ -328,22 +328,22 @@ def get_default_sdk():
def mssdk_setup_env(env):
debug('sdk.py:mssdk_setup_env()')
- if env.has_key('MSSDK_DIR'):
+ if 'MSSDK_DIR' in env:
sdk_dir = env['MSSDK_DIR']
if sdk_dir is None:
return
sdk_dir = env.subst(sdk_dir)
debug('sdk.py:mssdk_setup_env: Using MSSDK_DIR:%s'%sdk_dir)
- elif env.has_key('MSSDK_VERSION'):
+ elif 'MSSDK_VERSION' in env:
sdk_version = env['MSSDK_VERSION']
if sdk_version is None:
msg = "SDK version %s is not installed" % repr(mssdk)
- raise SCons.Errors.UserError, msg
+ raise SCons.Errors.UserError(msg)
sdk_version = env.subst(sdk_version)
mssdk = get_sdk_by_version(sdk_version)
sdk_dir = mssdk.get_sdk_dir()
debug('sdk.py:mssdk_setup_env: Using MSSDK_VERSION:%s'%sdk_dir)
- elif env.has_key('MSVS_VERSION'):
+ elif 'MSVS_VERSION' in env:
msvs_version = env['MSVS_VERSION']
debug('sdk.py:mssdk_setup_env:Getting MSVS_VERSION from env:%s'%msvs_version)
if msvs_version is None:
@@ -382,7 +382,7 @@ def mssdk_exists(version=None):
sdks = get_installed_sdks()
if version is None:
return len(sdks) > 0
- return sdks.has_key(version)
+ return version in sdks
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/Tool/MSCommon/vc.py b/src/engine/SCons/Tool/MSCommon/vc.py
index 5ea5a53..f07f34c 100644
--- a/src/engine/SCons/Tool/MSCommon/vc.py
+++ b/src/engine/SCons/Tool/MSCommon/vc.py
@@ -30,15 +30,15 @@
# * test on 64 bits XP + VS 2005 (and VS 6 if possible)
# * SDK
# * Assembly
-__revision__ = "src/engine/SCons/Tool/MSCommon/vc.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/MSCommon/vc.py 5023 2010/06/14 22:05:46 scons"
__doc__ = """Module for Visual C/C++ detection and configuration.
"""
import SCons.compat
-import string
import os
import platform
+from string import digits as string_digits
import SCons.Warnings
@@ -71,13 +71,16 @@ class BatchFileExecutionError(VisualCException):
# Dict to 'canonalize' the arch
_ARCH_TO_CANONICAL = {
- "x86": "x86",
- "amd64": "amd64",
- "i386": "x86",
- "emt64": "amd64",
- "x86_64": "amd64",
- "itanium": "ia64",
- "ia64": "ia64",
+ "amd64" : "amd64",
+ "emt64" : "amd64",
+ "i386" : "x86",
+ "i486" : "x86",
+ "i586" : "x86",
+ "i686" : "x86",
+ "ia64" : "ia64",
+ "itanium" : "ia64",
+ "x86" : "x86",
+ "x86_64" : "amd64",
}
# Given a (host, target) tuple, return the argument for the bat file. Both host
@@ -91,6 +94,8 @@ _HOST_TARGET_ARCH_TO_BAT_ARCH = {
}
def get_host_target(env):
+ debug('vc.py:get_host_target()')
+
host_platform = env.get('HOST_ARCH')
if not host_platform:
host_platform = platform.machine()
@@ -99,22 +104,29 @@ def get_host_target(env):
# PROCESSOR_ARCHITECTURE.
if not host_platform:
host_platform = os.environ.get('PROCESSOR_ARCHITECTURE', '')
- target_platform = env.get('TARGET_ARCH')
- if not target_platform:
+
+ # Retain user requested TARGET_ARCH
+ req_target_platform = env.get('TARGET_ARCH')
+ debug('vc.py:get_host_target() req_target_platform:%s'%req_target_platform)
+
+ if req_target_platform:
+ # If user requested a specific platform then only try that one.
+ target_platform = req_target_platform
+ else:
target_platform = host_platform
-
+
try:
- host = _ARCH_TO_CANONICAL[host_platform]
+ host = _ARCH_TO_CANONICAL[host_platform.lower()]
except KeyError, e:
msg = "Unrecognized host architecture %s"
raise ValueError(msg % repr(host_platform))
try:
- target = _ARCH_TO_CANONICAL[target_platform]
+ target = _ARCH_TO_CANONICAL[target_platform.lower()]
except KeyError, e:
raise ValueError("Unrecognized target architecture %s" % target_platform)
- return (host, target)
+ return (host, target,req_target_platform)
_VCVER = ["10.0", "9.0", "9.0Exp","8.0", "8.0Exp","7.1", "7.0", "6.0"]
@@ -136,17 +148,19 @@ _VCVER_TO_PRODUCT_DIR = {
'6.0': [
r'Microsoft\VisualStudio\6.0\Setup\Microsoft Visual C++\ProductDir']
}
-
+
def msvc_version_to_maj_min(msvc_version):
- t = msvc_version.split(".")
- if not len(t) == 2:
- raise ValueError("Unrecognized version %s" % msvc_version)
- try:
- maj = int(t[0])
- min = int(t[1])
- return maj, min
- except ValueError, e:
- raise ValueError("Unrecognized version %s" % msvc_version)
+ msvc_version_numeric = ''.join([x for x in msvc_version if x in string_digits + '.'])
+
+ t = msvc_version_numeric.split(".")
+ if not len(t) == 2:
+ raise ValueError("Unrecognized version %s (%s)" % (msvc_version,msvc_version_numeric))
+ try:
+ maj = int(t[0])
+ min = int(t[1])
+ return maj, min
+ except ValueError, e:
+ raise ValueError("Unrecognized version %s (%s)" % (msvc_version,msvc_version_numeric))
def is_host_target_supported(host_target, msvc_version):
"""Return True if the given (host, target) tuple is supported given the
@@ -206,7 +220,7 @@ def find_vc_pdir(msvc_version):
raise MissingConfiguration("registry dir %s not found on the filesystem" % comps)
return None
-def find_batch_file(env,msvc_version):
+def find_batch_file(env,msvc_version,host_arch,target_arch):
"""
Find the location of the batch script which should set up the compiler
for any TARGET_ARCH whose compilers were installed by Visual Studio/VCExpress
@@ -218,7 +232,7 @@ def find_batch_file(env,msvc_version):
debug('vc.py: find_batch_file() pdir:%s'%pdir)
# filter out e.g. "Exp" from the version name
- msvc_ver_numeric = string.join(filter(lambda x: x in string.digits + ".", msvc_version), '')
+ msvc_ver_numeric = ''.join([x for x in msvc_version if x in string_digits + "."])
vernum = float(msvc_ver_numeric)
if 7 <= vernum < 8:
pdir = os.path.join(pdir, os.pardir, "Common7", "Tools")
@@ -234,7 +248,6 @@ def find_batch_file(env,msvc_version):
batfilename = None
installed_sdks=get_installed_sdks()
- (host_arch,target_arch)=get_host_target(env)
for _sdk in installed_sdks:
sdk_bat_file=_sdk.get_sdk_vc_script(host_arch,target_arch)
sdk_bat_file_path=os.path.join(pdir,sdk_bat_file)
@@ -330,6 +343,73 @@ def msvc_setup_env_once(env):
msvc_setup_env(env)
env["MSVC_SETUP_RUN"] = True
+def msvc_find_valid_batch_script(env,version):
+ debug('vc.py:msvc_find_valid_batch_script()')
+ # Find the host platform, target platform, and if present the requested
+ # target platform
+ (host_platform, target_platform,req_target_platform) = get_host_target(env)
+
+ # If the user hasn't specifically requested a TARGET_ARCH, and
+ # The TARGET_ARCH is amd64 then also try 32 bits if there are no viable
+ # 64 bit tools installed
+ try_target_archs = [target_platform]
+ if not req_target_platform and target_platform=='amd64':
+ try_target_archs.append('x86')
+
+ d = None
+ for tp in try_target_archs:
+ # Set to current arch.
+ env['TARGET_ARCH']=tp
+
+ debug("vc.py:msvc_find_valid_batch_script() trying target_platform:%s"%tp)
+ host_target = (host_platform, tp)
+ if not is_host_target_supported(host_target, version):
+ warn_msg = "host, target = %s not supported for MSVC version %s" % \
+ (host_target, version)
+ SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, warn_msg)
+ arg = _HOST_TARGET_ARCH_TO_BAT_ARCH[host_target]
+
+ # Try to locate a batch file for this host/target platform combo
+ try:
+ (vc_script,sdk_script) = find_batch_file(env,version,host_platform,tp)
+ debug('vc.py:msvc_find_valid_batch_script() vc_script:%s sdk_script:%s'%(vc_script,sdk_script))
+ except VisualCException, e:
+ msg = str(e)
+ debug('Caught exception while looking for batch file (%s)' % msg)
+ warn_msg = "VC version %s not installed. " + \
+ "C/C++ compilers are most likely not set correctly.\n" + \
+ " Installed versions are: %s"
+ warn_msg = warn_msg % (version, cached_get_installed_vcs())
+ SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, warn_msg)
+ continue
+
+ # Try to use the located batch file for this host/target platform combo
+ debug('vc.py:msvc_find_valid_batch_script() use_script 2 %s, args:%s\n' % (repr(vc_script), arg))
+ if vc_script:
+ try:
+ d = script_env(vc_script, args=arg)
+ except BatchFileExecutionError, e:
+ debug('vc.py:msvc_find_valid_batch_script() use_script 3: failed running VC script %s: %s: Error:%s'%(repr(vc_script),arg,e))
+ vc_script=None
+ if not vc_script and sdk_script:
+ debug('vc.py:msvc_find_valid_batch_script() use_script 4: trying sdk script: %s'%(sdk_script))
+ try:
+ d = script_env(sdk_script,args=[])
+ except BatchFileExecutionError,e:
+ debug('vc.py:msvc_find_valid_batch_script() use_script 5: failed running SDK script %s: Error:%s'%(repr(sdk_script),e))
+ continue
+ elif not vc_script and not sdk_script:
+ debug('vc.py:msvc_find_valid_batch_script() use_script 6: Neither VC script nor SDK script found')
+ continue
+
+ # If we cannot find a viable installed compiler, reset the TARGET_ARCH
+ # To it's initial value
+ if not d:
+ env['TARGET_ARCH']=req_target_platform
+
+ return d
+
+
def msvc_setup_env(env):
debug('msvc_setup_env()')
@@ -347,50 +427,16 @@ def msvc_setup_env(env):
env['MSVS_VERSION'] = version
env['MSVS'] = {}
- try:
- (vc_script,sdk_script) = find_batch_file(env,version)
- debug('vc.py:msvc_setup_env() vc_script:%s sdk_script:%s'%(vc_script,sdk_script))
- except VisualCException, e:
- msg = str(e)
- debug('Caught exception while looking for batch file (%s)' % msg)
- warn_msg = "VC version %s not installed. " + \
- "C/C++ compilers are most likely not set correctly.\n" + \
- " Installed versions are: %s"
- warn_msg = warn_msg % (version, cached_get_installed_vcs())
- SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, warn_msg)
- return None
- debug('vc.py:msvc_setup_env() vc_script:%s sdk_script:%s'%(vc_script,sdk_script))
use_script = env.get('MSVC_USE_SCRIPT', True)
if SCons.Util.is_String(use_script):
- debug('use_script 1 %s\n' % repr(use_script))
+ debug('vc.py:msvc_setup_env() use_script 1 %s\n' % repr(use_script))
d = script_env(use_script)
- elif use_script:
- host_platform, target_platform = get_host_target(env)
- host_target = (host_platform, target_platform)
- if not is_host_target_supported(host_target, version):
- warn_msg = "host, target = %s not supported for MSVC version %s" % \
- (host_target, version)
- SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, warn_msg)
- arg = _HOST_TARGET_ARCH_TO_BAT_ARCH[host_target]
- debug('use_script 2 %s, args:%s\n' % (repr(vc_script), arg))
- if vc_script:
- try:
- d = script_env(vc_script, args=arg)
- except BatchFileExecutionError, e:
- debug('use_script 3: failed running VC script %s: %s: Error:%s'%(repr(vc_script),arg,e))
- vc_script=None
- if not vc_script and sdk_script:
- debug('use_script 4: trying sdk script: %s'%(sdk_script))
- try:
- d = script_env(sdk_script,args=[])
- except BatchFileExecutionError,e:
- debug('use_script 5: failed running SDK script %s: Error:%s'%(repr(sdk_script),e))
- return None
- elif not vc_script and not sdk_script:
- debug('use_script 6: Neither VC script nor SDK script found')
- return None
-
+ elif use_script:
+ d = msvc_find_valid_batch_script(env,version)
+ debug('vc.py:msvc_setup_env() use_script 2 %s\n' % d)
+ if not d:
+ return d
else:
debug('MSVC_USE_SCRIPT set to False')
warn_msg = "MSVC_USE_SCRIPT set to False, assuming environment " \
diff --git a/src/engine/SCons/Tool/MSCommon/vc.py.bak b/src/engine/SCons/Tool/MSCommon/vc.py.bak
deleted file mode 100644
index 1bdd298..0000000
--- a/src/engine/SCons/Tool/MSCommon/vc.py.bak
+++ /dev/null
@@ -1,394 +0,0 @@
-#
-# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation
-#
-# 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__ = "src/engine/SCons/Tool/MSCommon/vc.py.bak 4720 2010/03/24 03:14:11 jars"
-
-__doc__ = """Module for Visual C/C++ detection and configuration.
-"""
-
-import os
-import platform
-
-import SCons.Warnings
-
-import common
-
-debug = common.debug
-
-class VisualC:
- """
- An base class for finding installed versions of Visual C/C++.
- """
- def __init__(self, version, **kw):
- self.version = version
- self.__dict__.update(kw)
- self._cache = {}
-
- def vcbin_arch(self):
- if common.is_win64():
- result = {
- 'x86_64' : ['amd64', r'BIN\x86_amd64'],
- 'ia64' : [r'BIN\ia64'],
- }.get(target_arch, [])
- else:
- result = {
- 'x86_64' : ['x86_amd64'],
- 'ia64' : ['x86_ia64'],
- }.get(target_arch, [])
- # TODO(1.5)
- #return ';'.join(result)
- return string.join(result, ';')
-
- # Support for searching for an appropriate .bat file.
- # The map is indexed by (target_architecture, host_architecture).
- # Entries where the host_architecture is None specify the
- # cross-platform "default" .bat file if there isn't sn entry
- # specific to the current host architecture.
-
- batch_file_map = {
- ('x86_64', 'x86_64') : [
- r'bin\amd64\vcvarsamd64.bat',
- r'bin\x86_amd64\vcvarsx86_amd64.bat',
- r'bin\vcvarsx86_amd64.bat',
- ],
- ('x86_64', 'x86') : [
- r'bin\x86_amd64\vcvarsx86_amd64.bat',
- ],
- ('ia64', 'ia64') : [
- r'bin\ia64\vcvarsia64.bat',
- r'bin\x86_ia64\vcvarsx86_ia64.bat',
- ],
- ('ia64', None) : [
- r'bin\x86_ia64\vcvarsx86_ia64.bat',
- ],
- ('x86', None) : [
- r'bin\vcvars32.bat',
- ],
- }
-
- def find_batch_file(self, target_architecture, host_architecture):
- key = (target_architecture, host_architecture)
- potential_batch_files = self.batch_file_map.get(key)
- if not potential_batch_files:
- key = (target_architecture, None)
- potential_batch_files = self.batch_file_map.get(key)
- if potential_batch_files:
- product_dir = self.get_vc_dir()
- for batch_file in potential_batch_files:
- bf = os.path.join(product_dir, batch_file)
- if os.path.isfile(bf):
- return bf
- return None
-
- def find_vc_dir(self):
- root = 'Software\\'
- if common.is_win64():
- root = root + 'Wow6432Node\\'
- for key in self.hkeys:
- key = root + key
- try:
- comps = common.read_reg(key)
- except WindowsError, e:
- debug('find_vc_dir(): no VC registry key %s' % repr(key))
- else:
- debug('find_vc_dir(): found VC in registry: %s' % comps)
- if os.path.exists(comps):
- return comps
- else:
- debug('find_vc_dir(): reg says dir is %s, but it does not exist. (ignoring)'\
- % comps)
- return None
- return None
-
- #
-
- def get_batch_file(self, target_architecture, host_architecture):
- try:
- return self._cache['batch_file']
- except KeyError:
- batch_file = self.find_batch_file(target_architecture, host_architecture)
- self._cache['batch_file'] = batch_file
- return batch_file
-
- def get_vc_dir(self):
- try:
- return self._cache['vc_dir']
- except KeyError:
- vc_dir = self.find_vc_dir()
- self._cache['vc_dir'] = vc_dir
- return vc_dir
-
- def reset(self):
- self._cache={}
-
-
-# The list of supported Visual C/C++ versions we know how to detect.
-#
-# The first VC found in the list is the one used by default if there
-# are multiple VC installed. Barring good reasons to the contrary,
-# this means we should list VC with from most recent to oldest.
-#
-# If you update this list, update the documentation in Tool/vc.xml.
-SupportedVCList = [
- VisualC('9.0',
- hkeys=[
- r'Microsoft\VisualStudio\9.0\Setup\VC\ProductDir',
- r'Microsoft\VCExpress\9.0\Setup\VC\ProductDir',
- ],
- default_install=r'Microsoft Visual Studio 9.0\VC',
- common_tools_var='VS90COMNTOOLS',
- vc_subdir=r'\VC',
- batch_file_base='vcvars',
- supported_arch=['x86', 'x86_64', 'ia64'],
- atlmc_include_subdir = [r'ATLMFC\INCLUDE'],
- atlmfc_lib_subdir = {
- 'x86' : r'ATLMFC\LIB',
- 'x86_64' : r'ATLMFC\LIB\amd64',
- 'ia64' : r'ATLMFC\LIB\ia64',
- },
- crt_lib_subdir = {
- 'x86_64' : r'LIB\amd64',
- 'ia64' : r'LIB\ia64',
- },
- ),
- VisualC('8.0',
- hkeys=[
- r'Microsoft\VisualStudio\8.0\Setup\VC\ProductDir',
- r'Microsoft\VCExpress\8.0\Setup\VC\ProductDir',
- ],
- default_install=r'%s\Microsoft Visual Studio 8\VC',
- common_tools_var='VS80COMNTOOLS',
- vc_subdir=r'\VC',
- batch_file_base='vcvars',
- supported_arch=['x86', 'x86_64', 'ia64'],
- atlmc_include_subdir = [r'ATLMFC\INCLUDE'],
- atlmfc_lib_subdir = {
- 'x86' : r'ATLMFC\LIB',
- 'x86_64' : r'ATLMFC\LIB\amd64',
- 'ia64' : r'ATLMFC\LIB\ia64',
- },
- crt_lib_subdir = {
- 'x86_64' : r'LIB\amd64',
- 'ia64' : r'LIB\ia64',
- },
- ),
- VisualC('7.1',
- hkeys=[
- r'Microsoft\VisualStudio\7.1\Setup\VC\ProductDir',
- ],
- default_install=r'%s\Microsoft Visual Studio 7.1.NET 2003\VC7',
- common_tools_var='VS71COMNTOOLS',
- vc_subdir=r'\VC7',
- batch_file_base='vcvars',
- supported_arch=['x86'],
- atlmc_include_subdir = [r'ATLMFC\INCLUDE'],
- atlmfc_lib_subdir = {
- 'x86' : r'ATLMFC\LIB',
- },
- ),
- VisualC('7.0',
- hkeys=[
- r'Microsoft\VisualStudio\7.0\Setup\VC\ProductDir',
- ],
- default_install=r'%s\Microsoft Visual Studio .NET\VC7',
- common_tools_var='VS70COMNTOOLS',
- vc_subdir=r'\VC7',
- batch_file_base='vcvars',
- supported_arch=['x86'],
- atlmc_include_subdir = [r'ATLMFC\INCLUDE'],
- atlmfc_lib_subdir = {
- 'x86' : r'ATLMFC\LIB',
- },
- ),
- VisualC('6.0',
- hkeys=[
- r'Microsoft\VisualStudio\6.0\Setup\Microsoft Visual C++\ProductDir',
- ],
- default_install=r'%s\Microsoft Visual Studio\VC98',
- common_tools_var='VS60COMNTOOLS',
- vc_subdir=r'\VC98',
- batch_file_base='vcvars',
- supported_arch=['x86'],
- atlmc_include_subdir = [r'ATL\INCLUDE', r'MFC\INCLUDE'],
- atlmfc_lib_subdir = {
- 'x86' : r'MFC\LIB',
- },
- ),
-]
-
-SupportedVCMap = {}
-for vc in SupportedVCList:
- SupportedVCMap[vc.version] = vc
-
-
-# Finding installed versions of Visual C/C++ isn't cheap, because it goes
-# not only to the registry but also to the disk to sanity-check that there
-# is, in fact, something installed there and that the registry entry isn't
-# just stale. Find this information once, when requested, and cache it.
-
-InstalledVCList = None
-InstalledVCMap = None
-
-def get_installed_vcs():
- global InstalledVCList
- global InstalledVCMap
- if InstalledVCList is None:
- InstalledVCList = []
- InstalledVCMap = {}
- for vc in SupportedVCList:
- debug('trying to find VC %s' % vc.version)
- if vc.get_vc_dir():
- debug('found VC %s' % vc.version)
- InstalledVCList.append(vc)
- InstalledVCMap[vc.version] = vc
- return InstalledVCList
-
-
-def set_vc_by_version(env, msvc):
- if not SupportedVCMap.has_key(msvc):
- msg = "VC version %s is not supported" % repr(msvc)
- raise SCons.Errors.UserError, msg
- get_installed_vcs()
- vc = InstalledVCMap.get(msvc)
- if not vc:
- msg = "VC version %s is not installed" % repr(msvc)
- raise SCons.Errors.UserError, msg
- set_vc_by_directory(env, vc.get_vc_dir())
-
-# New stuff
-
-def script_env(script, args=None):
- stdout = common.get_output(script, args)
- return common.parse_output(stdout)
-
-def get_default_version(env):
- debug('get_default_version()')
-
- msvc_version = env.get('MSVC_VERSION')
- if not msvc_version:
- installed_vcs = get_installed_vcs()
- debug('InstalledVCMap:%s'%InstalledVCMap)
- if not installed_vcs:
- msg = 'No installed VCs'
- debug('msv %s\n' % repr(msg))
- SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, msg)
- return None
- msvc = installed_vcs[0]
- msvc_version = msvc.version
- debug('msvc_setup_env: using default installed MSVC version %s\n' % repr(msvc_version))
-
- return msvc_version
-
-# Dict to 'canonalize' the arch
-_ARCH_TO_CANONICAL = {
- "x86": "x86",
- "amd64": "amd64",
- "i386": "x86",
- "emt64": "amd64",
- "x86_64": "amd64"
-}
-
-# Given a (host, target) tuple, return the argument for the bat file. Both host
-# and targets should be canonalized.
-_HOST_TARGET_ARCH_TO_BAT_ARCH = {
- ("x86", "x86"): "x86",
- ("x86", "amd64"): "x86_amd64",
- ("amd64", "amd64"): "amd64",
- ("amd64", "x86"): "x86"
-}
-
-def get_host_target(env):
- host_platform = env.get('HOST_ARCH')
- if not host_platform:
- #host_platform = get_default_host_platform()
- host_platform = platform.machine()
- target_platform = env.get('TARGET_ARCH')
- if not target_platform:
- target_platform = host_platform
-
- return (_ARCH_TO_CANONICAL[host_platform],
- _ARCH_TO_CANONICAL[target_platform])
-
-def msvc_setup_env_once(env):
- try:
- has_run = env["MSVC_SETUP_RUN"]
- except KeyError:
- has_run = False
-
- if not has_run:
- msvc_setup_env(env)
- env["MSVC_SETUP_RUN"] = False
-
-def msvc_setup_env(env):
- debug('msvc_setup_env()')
-
- version = get_default_version(env)
- host_platform, target_platform = get_host_target(env)
- debug('msvc_setup_env: using specified MSVC version %s\n' % repr(version))
- env['MSVC_VERSION'] = version
-
- msvc = InstalledVCMap.get(version)
- if not msvc:
- msg = 'VC version %s not installed' % version
- debug('msv %s\n' % repr(msg))
- SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, msg)
- return None
-
- use_script = env.get('MSVC_USE_SCRIPT', True)
- if SCons.Util.is_String(use_script):
- debug('use_script 1 %s\n' % repr(use_script))
- d = script_env(use_script)
- elif use_script:
- # XXX: this is VS 2008 specific, fix this
- script = os.path.join(msvc.find_vc_dir(), "vcvarsall.bat")
-
- arg = _HOST_TARGET_ARCH_TO_BAT_ARCH[(host_platform, target_platform)]
- debug('use_script 2 %s, args:%s\n' % (repr(script), arg))
- d = script_env(script, args=arg)
- else:
- debug('msvc.get_default_env()\n')
- d = msvc.get_default_env()
-
- for k, v in d.items():
- env.PrependENVPath(k, v, delete_existing=True)
-
-def msvc_exists(version=None):
- vcs = get_installed_vcs()
- if version is None:
- return len(vcs) > 0
- return InstalledVCMap.has_key(version)
-
-
-def reset_installed_vcs():
- global InstalledVCList
- global InstalledVCMap
- InstalledVCList = None
- InstalledVCMap = None
- for vc in SupportedVCList:
- vc.reset()
-
-# Local Variables:
-# tab-width:4
-# indent-tabs-mode:nil
-# End:
-# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/src/engine/SCons/Tool/MSCommon/vs.py b/src/engine/SCons/Tool/MSCommon/vs.py
index e634a18..06030e2 100644
--- a/src/engine/SCons/Tool/MSCommon/vs.py
+++ b/src/engine/SCons/Tool/MSCommon/vs.py
@@ -21,7 +21,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/MSCommon/vs.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/MSCommon/vs.py 5023 2010/06/14 22:05:46 scons"
__doc__ = """Module to detect Visual Studio and/or Visual C/C++
"""
@@ -40,7 +40,7 @@ from common import debug, \
import SCons.Tool.MSCommon.vc
-class VisualStudio:
+class VisualStudio(object):
"""
An abstract base class for trying to find installed versions of
Visual Studio.
@@ -385,9 +385,9 @@ def get_vs_by_version(msvs):
global SupportedVSMap
debug('vs.py:get_vs_by_version()')
- if not SupportedVSMap.has_key(msvs):
+ if msvs not in SupportedVSMap:
msg = "Visual Studio version %s is not supported" % repr(msvs)
- raise SCons.Errors.UserError, msg
+ raise SCons.Errors.UserError(msg)
get_installed_visual_studios()
vs = InstalledVSMap.get(msvs)
debug('InstalledVSMap:%s'%InstalledVSMap)
@@ -415,15 +415,13 @@ def get_default_version(env):
version: str
the default version.
"""
- if not env.has_key('MSVS') or not SCons.Util.is_Dict(env['MSVS']):
- # TODO(1.5):
- #versions = [vs.version for vs in get_installed_visual_studios()]
- versions = map(lambda vs: vs.version, get_installed_visual_studios())
+ if 'MSVS' not in env or not SCons.Util.is_Dict(env['MSVS']):
+ versions = [vs.version for vs in get_installed_visual_studios()]
env['MSVS'] = {'VERSIONS' : versions}
else:
versions = env['MSVS'].get('VERSIONS', [])
- if not env.has_key('MSVS_VERSION'):
+ if 'MSVS_VERSION' not in env:
if versions:
env['MSVS_VERSION'] = versions[0] #use highest version by default
else:
@@ -451,7 +449,7 @@ def get_default_arch(env):
arch = 'x86'
elif not arch in msvs.get_supported_arch():
fmt = "Visual Studio version %s does not support architecture %s"
- raise SCons.Errors.UserError, fmt % (env['MSVS_VERSION'], arch)
+ raise SCons.Errors.UserError(fmt % (env['MSVS_VERSION'], arch))
return arch
@@ -473,11 +471,15 @@ def msvs_setup_env(env):
vars = ('LIB', 'LIBPATH', 'PATH', 'INCLUDE')
msvs_list = get_installed_visual_studios()
- # TODO(1.5):
- #vscommonvarnames = [ vs.common_tools_var for vs in msvs_list ]
- vscommonvarnames = map(lambda vs: vs.common_tools_var, msvs_list)
- nenv = normalize_env(env['ENV'], vscommonvarnames + ['COMSPEC'])
- output = get_output(batfilename, arch, env=nenv)
+ vscommonvarnames = [vs.common_tools_var for vs in msvs_list]
+ save_ENV = env['ENV']
+ nenv = normalize_env(env['ENV'],
+ ['COMSPEC'] + vscommonvarnames,
+ force=True)
+ try:
+ output = get_output(batfilename, arch, env=nenv)
+ finally:
+ env['ENV'] = save_ENV
vars = parse_output(output, vars)
for k, v in vars.items():
@@ -487,9 +489,7 @@ def query_versions():
"""Query the system to get available versions of VS. A version is
considered when a batfile is found."""
msvs_list = get_installed_visual_studios()
- # TODO(1.5)
- #versions = [ msvs.version for msvs in msvs_list ]
- versions = map(lambda msvs: msvs.version, msvs_list)
+ versions = [msvs.version for msvs in msvs_list]
return versions
# Local Variables: