Commits

Anonymous committed 0524f78

Capture basically working snapshot.
src/engine/SCons/Tool/msvsTests.py and test/IDL/midl.py still fail,
and code needs clean up.

  • Participants
  • Parent commits b3ba5b7
  • Branches vs_revamp

Comments (0)

Files changed (13)

File src/engine/SCons/Tool/MSCommon/__init__.py

 import SCons.Platform.win32
 import SCons.Util
 
-from SCons.Tool.MSCommon.vs import detect_msvs, \
-                                   get_default_version, \
+from SCons.Tool.MSCommon.vc import msvc_exists, \
+                                   msvc_setup_env
+
+from SCons.Tool.MSCommon.vs import get_default_version, \
                                    get_vs_by_version, \
                                    merge_default_version, \
+                                   msvs_exists, \
                                    query_versions
 
 # Local Variables:

File src/engine/SCons/Tool/MSCommon/sdk.py

         Return None if failed or the directory does not exist.
         """
         if not SCons.Util.can_read_reg:
-            debug('find_sdk_dir():  can not read registry')
+            debug('find_sdk_dir(): can not read registry')
             return None
 
         hkey = self.HKEY_FMT % self.hkey_data
         try:
             sdk_dir = read_reg(hkey)
         except WindowsError, e:
-            debug('find_sdk_dir(): no registry key %s' % hkey)
+            debug('find_sdk_dir(): no SDK registry key %s' % repr(hkey))
             return None
 
         if not os.path.exists(sdk_dir):
 
         ftc = os.path.join(sdk_dir, self.sanity_check_file)
         if not os.path.exists(ftc):
-            debug("find_sdk_dir():  sanity check %s not found" % ftc)
+            debug("find_sdk_dir(): sanity check %s not found" % ftc)
             return None
 
         return sdk_dir
               ),
 
     WindowsSDK('6.0A',
-               sanity_check_file=r'include\windows.h'
+               sanity_check_file=r'include\windows.h',
                include_subdir='include',
                lib_subdir={
                    'x86'       : ['lib'],

File src/engine/SCons/Tool/MSCommon/vc.py

 
 import os
 
+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():
         ],
         ('ia64', None) : [
             r'bin\x86_ia64\vcvarsx86_ia64.bat',
+        ],
         ('x86', None) : [
             r'bin\vcvars32.bat',
         ],
     }
 
-    def find_batch_file(self):
+    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.msvc_root_dir()
+            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)
+                return comps
+        return None
+
     #
 
-    def get_batch_file(self):
+    def get_batch_file(self, target_architecture, host_architecture):
         try:
             return self._cache['batch_file']
         except KeyError:
-            executable = self.find_batch_file()
+            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
         
 
 # The list of supported Visual C/C++ versions we know how to detect.
 # this means we should list VC with from most recent to oldest.
 #
 # If you update this list, update the documentation in Tool/vc.xml.
-SupportedVisualCList = [
+SupportedVCList = [
     VisualC('9.0',
-            hkey_root=[
-                r'Software%sMicrosoft\VisualStudio\9.0\Setup\VC\ProductDir',
-                r'Software%sMicrosoft\VCExpress\9.0\Setup\VC\ProductDir',
+            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_sub_dir='VC\\',
+            vc_subdir=r'\VC',
             batch_file_base='vcvars',
             supported_arch=['x86', 'x86_64', 'ia64'],
             atlmc_include_subdir = [r'ATLMFC\INCLUDE'],
             },
     ),
     VisualC('8.0',
-            hkey_root=[
-                r'Software%sMicrosoft\VisualStudio\8.0\Setup\VC\ProductDir',
-                r'Software%sMicrosoft\VCExpress\8.0\Setup\VC\ProductDir',
+            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_sub_dir='VC\\',
+            vc_subdir=r'\VC',
             batch_file_base='vcvars',
             supported_arch=['x86', 'x86_64', 'ia64'],
             atlmc_include_subdir = [r'ATLMFC\INCLUDE'],
             },
     ),
     VisualC('7.1',
-            hkey_root=[
-                r'Software%sMicrosoft\VisualStudio\7.1\Setup\VC\ProductDir',
+            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_sub_dir='VC7\\',
+            vc_subdir=r'\VC7',
             batch_file_base='vcvars',
             supported_arch=['x86'],
             atlmc_include_subdir = [r'ATLMFC\INCLUDE'],
             },
     ),
     VisualC('7.0',
-            hkey_root=[
-                r'Software%sMicrosoft\VisualStudio\7.0\Setup\VC\ProductDir',
+            hkeys=[
+                r'Microsoft\VisualStudio\7.0\Setup\VC\ProductDir',
             ],
             default_install=r'%s\Microsoft Visual Studio .NET\VC7',
             common_tools_var='VS70COMNTOOLS',
-            vc_sub_dir='VC7\\',
+            vc_subdir=r'\VC7',
             batch_file_base='vcvars',
             supported_arch=['x86'],
             atlmc_include_subdir = [r'ATLMFC\INCLUDE'],
             },
     ),
     VisualC('6.0',
-            hkey_root=[
-                r'Software%sMicrosoft\VisualStudio\6.0\Setup\Microsoft Visual C++\ProductDir',
+            hkeys=[
+                r'Microsoft\VisualStudio\6.0\Setup\Microsoft Visual C++\ProductDir',
             ],
             default_install=r'%s\Microsoft Visual Studio\VC98',
             common_tools_var='VS60COMNTOOLS',
-            vc_sub_dir='VC98\\',
+            vc_subdir=r'\VC98',
             batch_file_base='vcvars',
             supported_arch=['x86'],
             atlmc_include_subdir = [r'ATL\INCLUDE', r'MFC\INCLUDE'],
     return InstalledVCList
 
 
-def detect_vc(version=None):
-    vcs = get_installed_vcs()
-    if version is None:
-        return len(vcs) > 0
-    return vcs.has_key(version)
-
 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
     set_vc_by_directory(env, vc.get_vc_dir())
 
+# New stuff
+
+def script_env(script):
+    stdout = common.get_output(script)
+    return common.parse_output(stdout)
+
+def msvc_setup_env(env):
+    debug('msvc_setup_env()')
+    installed_vcs = get_installed_vcs()
+    msvc_version = env.get('MSVC_VERSION')
+    if not msvc_version:
+        if not installed_vcs:
+            msg = 'No installed VCs'
+            debug('msv %s\n' % repr(msg))
+            SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, msg)
+            return
+        msvc = installed_vcs[0]
+        msvc_version = msvc.version
+        env['MSVC_VERSION'] = msvc_version
+    else:
+        msvc = InstalledVCMap.get(msvc_version)
+        if not msvc:
+            msg = 'VC version %s not installed' % msvc_version
+            debug('msv %s\n' % repr(msg))
+            SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, msg)
+            return
+
+    host_platform = env.get('HOST_PLATFORM')
+    if not host_platform:
+      #host_platform = get_default_host_platform()
+      host_platform = 'x86'
+    target_platform = env.get('TARGET_PLATFORM')
+    if not target_platform:
+      target_platform = host_platform
+
+    use_script = env.get('MSVC_USE_SCRIPT', True)
+    if SCons.Util.is_String(use_script):
+        d = script_env(use_script)
+        debug('use_script 1 %s\n' % repr(use_script))
+    elif use_script:
+        script = msvc.get_batch_file(target_platform, host_platform)
+        d = script_env(script)
+        debug('use_script 2 %s\n' % repr(script))
+    else:
+        d = msvc.get_default_env()
+        debug('msvc.get_default_env()\n')
+
+    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)
+
 # Local Variables:
 # tab-width:4
 # indent-tabs-mode:nil

File src/engine/SCons/Tool/MSCommon/vs.py

 import SCons.Errors
 import SCons.Util
 
-from SCons.Tool.MSCommon.common import debug, \
-                                       read_reg, \
-                                       normalize_env, \
-                                       get_output, \
-                                       parse_output
+from common import debug, \
+                   get_output, \
+                   is_win64, \
+                   normalize_env, \
+                   parse_output
+
+import vc
 
 class VisualStudio:
     """
     """
     def __init__(self, version, **kw):
         self.version = version
+        kw['vc_version'] = kw.get('vc_version', version)
         self.__dict__.update(kw)
         self._cache = {}
 
     #
 
-    def find_batch_file(self):
-        """Try to find the Visual Studio or Visual C/C++ batch file.
-
-        Return None if failed or the batch file does not exist.
-        """
-        pdir = self.get_vc_product_dir()
-        if not pdir:
-            debug('find_batch_file():  no pdir')
+    def find_vs_dir(self):
+        vc.get_installed_vcs()
+        ivc = vc.InstalledVCMap.get(self.vc_version)
+        if not ivc:
+            debug('find_vs_dir():  no installed VC %s' % self.vc_version)
             return None
-        batch_file = os.path.normpath(os.path.join(pdir, self.batch_file))
-        batch_file = os.path.normpath(batch_file)
-        if not os.path.isfile(batch_file):
-            debug('find_batch_file():  %s not on file system' % batch_file)
-            return None
-        return batch_file
+        return ivc.get_vc_dir()[:-len(ivc.vc_subdir)]
 
     def find_executable(self):
-        pdir = self.get_vc_product_dir()
+        pdir = self.get_vs_dir()
         if not pdir:
             debug('find_executable():  no pdir')
             return None
             return None
         return executable
 
-    def find_vc_product_dir(self):
-        if not SCons.Util.can_read_reg:
-            debug('find_vc_product_dir():  can not read registry')
-            return None
-        key = self.hkey_root + '\\' + self.vc_product_dir_key
-        try:
-            comps = read_reg(key)
-        except WindowsError, e:
-            debug('find_vc_product_dir():  no registry key %s' % key)
-        else:
-            if self.batch_file_dir_reg_relpath:
-                comps = os.path.join(comps, self.batch_file_dir_reg_relpath)
-                comps = os.path.normpath(comps)
-            if os.path.exists(comps):
-                return comps
-            else:
-                debug('find_vc_product_dir():  %s not on file system' % comps)
-
-        d = os.environ.get(self.common_tools_var)
-        if not d:
-            msg = 'find_vc_product_dir():  no %s variable'
-            debug(msg % self.common_tools_var)
-            return None
-        if not os.path.isdir(d):
-            debug('find_vc_product_dir():  %s not on file system' % d)
-            return None
-        if self.batch_file_dir_env_relpath:
-            d = os.path.join(d, self.batch_file_dir_env_relpath)
-            d = os.path.normpath(d)
-        return d
-
     #
 
-    def get_batch_file(self):
-        try:
-            return self._cache['batch_file']
-        except KeyError:
-            batch_file = self.find_batch_file()
-            self._cache['batch_file'] = batch_file
-            return batch_file
-
     def get_executable(self):
         try:
             return self._cache['executable']
             self._cache['executable'] = executable
             return executable
 
+    def get_vs_dir(self):
+        try:
+            return self._cache['vs_dir']
+        except KeyError:
+            vs_dir = self.find_vs_dir()
+            self._cache['vs_dir'] = vs_dir
+            return vs_dir
+
     def get_supported_arch(self):
         try:
             return self._cache['supported_arch']
             self._cache['supported_arch'] = self.supported_arch
             return self.supported_arch
 
-    def get_vc_product_dir(self):
-        try:
-            return self._cache['vc_product_dir']
-        except KeyError:
-            vc_product_dir = self.find_vc_product_dir()
-            self._cache['vc_product_dir'] = vc_product_dir
-            return vc_product_dir
-
     def reset(self):
         self._cache = {}
 
     #VisualStudio('TBD',
     #             hkey_root=r'TBD',
     #             common_tools_var='TBD',
-    #             batch_file='TBD',
-    #             vc_product_dir_key=r'TBD',
-    #             batch_file_dir_reg_relpath=None,
-    #             batch_file_dir_env_relpath=r'TBD',
     #             executable_path=r'TBD',
     #             default_dirname='TBD',
     #),
     # The batch file we look for is in the VC directory,
     # so the devenv.com executable is up in ..\..\Common7\IDE.
     VisualStudio('9.0',
-                 hkey_root=r'Software\Microsoft\VisualStudio\9.0',
+                 hkeys=[r'Microsoft\VisualStudio\9.0'],
                  common_tools_var='VS90COMNTOOLS',
-                 batch_file='vcvarsall.bat',
-                 vc_product_dir_key=r'Setup\VC\ProductDir',
-                 batch_file_dir_reg_relpath=None,
-                 batch_file_dir_env_relpath=r'..\..\VC',
                  executable_path=r'..\Common7\IDE\devenv.com',
                  default_dirname='Microsoft Visual Studio 9',
                  supported_arch=['x86', 'amd64'],
     # The batch file we look for is in the VC directory,
     # so the VCExpress.exe executable is up in ..\..\Common7\IDE.
     VisualStudio('9.0Exp',
-                 hkey_root=r'Software\Microsoft\VisualStudio\9.0',
+                 vc_version='9.0',
+                 hkeys=[r'Microsoft\VisualStudio\9.0'],
                  common_tools_var='VS90COMNTOOLS',
-                 batch_file='vcvarsall.bat',
-                 vc_product_dir_key=r'Setup\VC\ProductDir',
-                 batch_file_dir_reg_relpath=None,
-                 batch_file_dir_env_relpath=r'..\..\VC',
                  executable_path=r'..\Common7\IDE\VCExpress.exe',
                  default_dirname='Microsoft Visual Studio 9',
                  supported_arch=['x86'],
     # The batch file we look for is in the VC directory,
     # so the devenv.com executable is up in ..\..\Common7\IDE.
     VisualStudio('8.0',
-                 hkey_root=r'Software\Microsoft\VisualStudio\8.0',
+                 hkeys=[r'Microsoft\VisualStudio\8.0'],
                  common_tools_var='VS80COMNTOOLS',
-                 batch_file='vcvarsall.bat',
-                 vc_product_dir_key=r'Setup\VC\ProductDir',
-                 batch_file_dir_reg_relpath=None,
-                 batch_file_dir_env_relpath=r'..\..\VC',
                  executable_path=r'..\Common7\IDE\devenv.com',
                  default_dirname='Microsoft Visual Studio 8',
                  supported_arch=['x86', 'amd64'],
     # The batch file we look for is in the VC directory,
     # so the VCExpress.exe executable is up in ..\..\Common7\IDE.
     VisualStudio('8.0Exp',
-                 hkey_root=r'Software\Microsoft\VCExpress\8.0',
+                 vc_version='8.0',
+                 hkeys=[r'Microsoft\VCExpress\8.0'],
                  common_tools_var='VS80COMNTOOLS',
-                 batch_file='vcvarsall.bat',
-                 vc_product_dir_key=r'Setup\VC\ProductDir',
-                 batch_file_dir_reg_relpath=None,
-                 batch_file_dir_env_relpath=r'..\..\VC',
                  # The batch file is in the VC directory, so
                  # so the devenv.com executable is next door in ..\IDE.
                  executable_path=r'..\Common7\IDE\VCExpress.exe',
     # The batch file we look for is in the Common7\Tools directory,
     # so the devenv.com executable is next door in ..\IDE.
     VisualStudio('7.1',
-                 hkey_root=r'Software\Microsoft\VisualStudio\7.1',
+                 hkeys=[r'Microsoft\VisualStudio\7.1'],
                  common_tools_var='VS71COMNTOOLS',
-                 batch_file='vsvars32.bat',
-                 vc_product_dir_key=r'Setup\VC\ProductDir',
-                 batch_file_dir_reg_relpath=r'..\Common7\Tools',
-                 batch_file_dir_env_relpath=None,
                  executable_path=r'..\IDE\devenv.com',
                  default_dirname='Microsoft Visual Studio .NET',
                  supported_arch=['x86'],
     # The batch file we look for is in the Common7\Tools directory,
     # so the devenv.com executable is next door in ..\IDE.
     VisualStudio('7.0',
-                 hkey_root=r'Software\Microsoft\VisualStudio\7.0',
+                 hkeys=[r'Microsoft\VisualStudio\7.0'],
                  common_tools_var='VS70COMNTOOLS',
-                 batch_file='vsvars32.bat',
-                 vc_product_dir_key=r'Setup\VC\ProductDir',
-                 batch_file_dir_reg_relpath=r'..\Common7\Tools',
-                 batch_file_dir_env_relpath=None,
                  executable_path=r'..\IDE\devenv.com',
                  default_dirname='Microsoft Visual Studio .NET',
                  supported_arch=['x86'],
 
     # Visual Studio 6.0
     VisualStudio('6.0',
-                 hkey_root=r'Software\Microsoft\VisualStudio\6.0',
+                 hkeys=[r'Microsoft\VisualStudio\6.0'],
                  common_tools_var='VS60COMNTOOLS',
-                 batch_file='vcvars32.bat',
-                 vc_product_dir_key='Setup\Microsoft Visual C++\ProductDir',
-                 batch_file_dir_reg_relpath='Bin',
-                 batch_file_dir_env_relpath=None,
                  executable_path=r'Common\MSDev98\Bin\MSDEV.COM',
                  default_dirname='Microsoft Visual Studio',
                  supported_arch=['x86'],
 #    for variable, directory in env_tuple_list:
 #        env.PrependENVPath(variable, directory)
 
-def detect_msvs():
+def msvs_exists():
     return (len(get_installed_visual_studios()) > 0)
 
 def get_vs_by_version(msvs):

File src/engine/SCons/Tool/linkloc.py

 import SCons.Tool
 import SCons.Util
 
-from SCons.Tool.MSCommon import detect_msvs, merge_default_version
+from SCons.Tool.MSCommon import msvs_exists, merge_default_version
 from SCons.Tool.PharLapCommon import addPharLapPaths
 
 _re_linker_command = re.compile(r'(\s)@\s*([^\s]+)')
     addPharLapPaths(env)
 
 def exists(env):
-    if detect_msvs():
+    if msvs_exists():
         return env.Detect('linkloc')
     else:
         return 0

File src/engine/SCons/Tool/midl.py

 import SCons.Scanner.IDL
 import SCons.Util
 
-from MSCommon import detect_msvs
+from MSCommon import msvs_exists
 
 def midl_emitter(target, source, env):
     """Produces a list of outputs from the MIDL compiler"""
     env['BUILDERS']['TypeLibrary'] = midl_builder
 
 def exists(env):
-    return detect_msvs()
+    return msvs_exists()
 
 # Local Variables:
 # tab-width:4

File src/engine/SCons/Tool/mslib.py

 import SCons.Tool.msvc
 import SCons.Util
 
-from MSCommon import detect_msvs, merge_default_version
+from MSCommon import msvs_exists, merge_default_version
 
 def generate(env):
     """Add Builders and construction variables for lib to an Environment."""
     env['LIBSUFFIX']   = '.lib'
 
 def exists(env):
-    return detect_msvs()
+    return msvs_exists()
 
 # Local Variables:
 # tab-width:4

File src/engine/SCons/Tool/mslink.py

 import SCons.Tool.msvs
 import SCons.Util
 
-from MSCommon import merge_default_version, detect_msvs
+from MSCommon import merge_default_version, msvs_exists
 
 def pdbGenerator(env, target, source, for_signature):
     try:
     env['LDMODULECOM'] = compositeLdmodAction
 
 def exists(env):
-    return detect_msvs()
+    return msvs_exists()
 
 # Local Variables:
 # tab-width:4

File src/engine/SCons/Tool/msvc.py

 import SCons.Warnings
 import SCons.Scanner.RC
 
-from MSCommon import merge_default_version, detect_msvs
+from MSCommon import msvc_exists, msvc_setup_env
 
 CSuffixes = ['.c', '.C']
 CXXSuffixes = ['.cc', '.cpp', '.cxx', '.c++', '.C++']
     env['SHOBJSUFFIX']    = '$OBJSUFFIX'
 
     # Set-up ms tools paths for default version
-    merge_default_version(env)
+    msvc_setup_env(env)
 
     import mssdk
     mssdk.generate(env)
         env['ENV']['SystemRoot'] = SCons.Platform.win32.get_system_root()
 
 def exists(env):
-    return detect_msvs()
+    return msvc_exists('cl')
 
 # Local Variables:
 # tab-width:4

File src/engine/SCons/Tool/msvc.xml

 when the &cv-RCINCFLAGS; variable is expanded.
 </summary>
 </cvar>
+
+<cvar name="MSVC_VERSION">
+<summary>
+Sets the preferred  version of Microsoft Visual C/C++ to use.
+
+If &v-MSVC_VERSION; is not set,
+&SCons; will (by default) select the latest version
+of Visual C/C++ installed on your system.
+If the specified version isn't installed,
+tool initialization will fail.
+</summary>
+</cvar>

File src/engine/SCons/Tool/msvs.py

 import SCons.Util
 import SCons.Warnings
 
-from MSCommon import detect_msvs, merge_default_version
+from MSCommon import msvs_exists, merge_default_version
 
 ##############################################################################
 # Below here are the classes and functions for generation of
     env['SCONS_HOME'] = os.environ.get('SCONS_HOME')
 
 def exists(env):
-    return detect_msvs()
+    return msvs_exists()
 
 # Local Variables:
 # tab-width:4

File src/engine/SCons/Tool/msvsTests.py

         from SCons.Tool.MSCommon.vs import reset_installed_visual_studios
         reset_installed_visual_studios()
 
-    def test_detect_msvs(self):
-        """Test the detect_msvs() function"""
-        r = detect_msvs()
+    def test_msvs_exists(self):
+        """Test the msvs_exists() function"""
+        r = msvs_exists()
         assert r == (self.number_of_versions > 0), r
 
     def test_get_default_version(self):

File src/engine/SCons/Warnings.py

 class TaskmasterNeedsExecuteWarning(FutureDeprecatedWarning):
     pass
 
+class VisualCMissingWarning(Warning):
+    pass
+
+class VisualStudioMissingWarning(Warning):
+    pass
+
 class FortranCxxMixWarning(LinkWarning):
     pass