Issue 2102: Add support for Visual Studio 9 and newer Platform
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Mon, 15 Sep 2008 07:02:59 +0000 (07:02 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Mon, 15 Sep 2008 07:02:59 +0000 (07:02 +0000)
SDK versions.  (Dmitri Rubinstein)

git-svn-id: http://scons.tigris.org/svn/scons/trunk@3422 fdb21ef1-2011-0410-befe-b5e4ea1792b1

src/CHANGES.txt
src/engine/SCons/Tool/msvc.py
src/engine/SCons/Tool/msvs.py

index 618c9e29756ee93e7aa3b63a284a1d617b5ad5a7..a023c6a1588ec0a2e64a3a57ac696c723bca7f29 100644 (file)
@@ -93,6 +93,11 @@ RELEASE 1.X - XXX
     - Make the subdirectory in which the SConsignFile() file will
       live, if the subdirectory doesn't already exist.
 
+  From Dmitri Rubinstein:
+
+    - Add support for detecting Visual Studio 9 and newer Platform SDK
+      versions.
+
   From Ali Tofigh:
 
     - Add a test to verify duplication of files in VariantDir subdirectories.
index 8828d7da355b4e3d776c0360bcb269d3c94f1c8a..9c02806cd8a7b15e014081331ce8a73643539b75 100644 (file)
@@ -532,6 +532,70 @@ def _get_msvc8_default_paths(env, version, suite, use_mfc_dirs):
     exe_path = string.join(exe_paths, os.pathsep )
     return (include_path, lib_path, exe_path)
 
+def _get_msvc9_default_paths(env, version, suite, use_mfc_dirs):
+    """Return a 3-tuple of (INCLUDE, LIB, PATH) as the values of those
+    three environment variables that should be set in order to execute
+    the MSVC 9 tools properly, if the information wasn't available
+    from the registry."""
+
+    MVSdir = None
+    paths = {}
+    exe_paths = []
+    lib_paths = []
+    include_paths = []
+    try:
+        paths = SCons.Tool.msvs.get_msvs_install_dirs(version, suite)
+        MVSdir = paths['VSINSTALLDIR']
+    except (KeyError, SCons.Util.RegError, SCons.Errors.InternalError):
+        if os.environ.has_key('VSCOMNTOOLS'):
+            MVSdir = os.path.normpath(os.path.join(os.environ['VSCOMNTOOLS'],'..','..'))
+        else:
+            # last resort -- default install location
+            MVSdir = os.getenv('ProgramFiles') + r'\Microsoft Visual Studio ' + str(version)
+
+    if MVSdir:
+        if SCons.Util.can_read_reg and paths.has_key('VCINSTALLDIR'):
+            MVSVCdir = paths['VCINSTALLDIR']
+        else:
+            MVSVCdir = os.path.join(MVSdir,'VC')
+
+        MVSCommondir = os.path.join(MVSdir, 'Common7')
+        include_paths.append( os.path.join(MVSVCdir, 'include') )
+        lib_paths.append( os.path.join(MVSVCdir, 'lib') )
+        for base, subdir in [(MVSCommondir,'IDE'), (MVSVCdir,'bin'),
+                             (MVSCommondir,'Tools'), (MVSCommondir,r'Tools\bin')]:
+            exe_paths.append( os.path.join( base, subdir) )
+
+        if paths.has_key('PLATFORMSDKDIR'):
+            PlatformSdkDir = paths['PLATFORMSDKDIR']
+        else:
+            PlatformSdkDir = os.path.join(MVSVCdir,'PlatformSDK')
+        platform_include_path = os.path.join( PlatformSdkDir, 'Include' )
+        include_paths.append( platform_include_path )
+        lib_paths.append( os.path.join( PlatformSdkDir, 'Lib' ) )
+        if use_mfc_dirs:
+            if paths.has_key('PLATFORMSDKDIR'):
+                include_paths.append( os.path.join( platform_include_path, 'mfc' ) )
+                include_paths.append( os.path.join( platform_include_path, 'atl' ) )
+            else:
+                atlmfc_path = os.path.join( MVSVCdir, 'atlmfc' )
+                include_paths.append( os.path.join( atlmfc_path, 'include' ) )
+                lib_paths.append( os.path.join( atlmfc_path, 'lib' ) )
+
+        if SCons.Util.can_read_reg and paths.has_key('FRAMEWORKSDKDIR'):
+            fwdir = paths['FRAMEWORKSDKDIR']
+            include_paths.append( os.path.join( fwdir, 'include' ) )
+            lib_paths.append( os.path.join( fwdir, 'lib' ) )
+            exe_paths.append( os.path.join( fwdir, 'bin' ) )
+
+        if SCons.Util.can_read_reg and paths.has_key('FRAMEWORKDIR') and paths.has_key('FRAMEWORKVERSION'):
+            exe_paths.append( os.path.join( paths['FRAMEWORKDIR'], paths['FRAMEWORKVERSION'] ) )
+
+    include_path = string.join( include_paths, os.pathsep )
+    lib_path = string.join(lib_paths, os.pathsep )
+    exe_path = string.join(exe_paths, os.pathsep )
+    return (include_path, lib_path, exe_path)
+
 def get_msvc_paths(env, version=None, use_mfc_dirs=0):
     """Return a 3-tuple of (INCLUDE, LIB, PATH) as the values
     of those three environment variables that should be set
@@ -553,7 +617,10 @@ def get_msvc_paths(env, version=None, use_mfc_dirs=0):
     # base installation from the registry and deduce the default
     # directories.
     version_num, suite = SCons.Tool.msvs.msvs_parse_version(version)
-    if version_num >= 8.0:
+    if version_num >= 9.0:
+        suite = SCons.Tool.msvs.get_default_visualstudio9_suite(env)
+        defpaths = _get_msvc9_default_paths(env, version, suite, use_mfc_dirs)
+    elif version_num >= 8.0:
         suite = SCons.Tool.msvs.get_default_visualstudio8_suite(env)
         defpaths = _get_msvc8_default_paths(env, version, suite, use_mfc_dirs)
     elif version_num >= 7.0:
index e9d73dab50f41a4c18d00a8a0353d0b1a7a5bb9b..a0ac21b4c8fa7d385c33084c9b066fbe4675c6e0 100644 (file)
@@ -1217,8 +1217,10 @@ def get_visualstudio_versions():
                         vs = r'Microsoft Visual Studio\Common\MSDev98'
                     elif version_num < 8.0:
                         vs = r'Microsoft Visual Studio .NET\Common7\IDE'
-                    else:
+                    elif version_num < 9.0:
                         vs = r'Microsoft Visual Studio 8\Common7\IDE'
+                    else:
+                        vs = r'Microsoft Visual Studio 9.0\Common7\IDE'
                     id = [ os.path.join(files_dir, vs) ]
                 if os.path.exists(id[0]):
                     L.append(p + suite_suffix)
@@ -1305,6 +1307,74 @@ def get_visualstudio8_suites():
 
     return suites
 
+def get_default_visualstudio9_suite(env):
+    """
+    Returns the Visual Studio 2008 suite identifier set in the env, or the
+    highest suite installed.
+    """
+    if not env.has_key('MSVS') or not SCons.Util.is_Dict(env['MSVS']):
+        env['MSVS'] = {}
+
+    if env.has_key('MSVS_SUITE'):
+        suite = env['MSVS_SUITE'].upper()
+        suites = [suite]
+    else:
+        suite = 'EXPRESS'
+        suites = [suite]
+        if SCons.Util.can_read_reg:
+            suites = get_visualstudio9_suites()
+            if suites:
+                suite = suites[0] #use best suite by default
+
+    env['MSVS_SUITE'] = suite
+    env['MSVS']['SUITES'] = suites
+    env['MSVS']['SUITE'] = suite
+
+    return suite
+
+def get_visualstudio9_suites():
+    """
+    Returns a sorted list of all installed Visual Studio 2008 suites found
+    in the registry. The highest version should be the first entry in the list.
+    """
+    
+    suites = []
+
+    # Detect Standard, Professional and Team edition
+    try:
+        idk = SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE,
+            r'Software\Microsoft\VisualStudio\9.0')
+        SCons.Util.RegQueryValueEx(idk, 'InstallDir')
+        editions = { 'PRO': r'Setup\VS\Pro',
+                     'TS' : r'Setup\VS\VSTS' # Team system
+                     # ToDo: add standard and team editions
+                     }
+        for name, key_suffix in editions.items():
+            try:
+                idk = SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE,
+                    r'Software\Microsoft\VisualStudio\9.0' + '\\' + key_suffix )
+                suites.append(name)
+            except SCons.Util.RegError:
+                pass
+
+        # fallback suite is STD
+        if len(suites) == 0:
+            suites.append('STD')
+
+    except SCons.Util.RegError:
+        pass
+
+    # Detect Express edition
+    try:
+        idk = SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE,
+                                      r'Software\Microsoft\VCExpress\9.0')
+        SCons.Util.RegQueryValueEx(idk, 'InstallDir')
+        suites.append('EXPRESS')
+    except SCons.Util.RegError:
+        pass
+
+    return suites
+
 def is_msvs_installed():
     """
     Check the registry for an installed visual studio.
@@ -1334,7 +1404,17 @@ def get_msvs_install_dirs(version = None, vs8suite = None):
     version_num, suite = msvs_parse_version(version)
 
     K = 'Software\\Microsoft\\VisualStudio\\' + str(version_num)
-    if (version_num >= 8.0):
+    if (version_num >= 9.0):
+        if vs8suite == None:
+            # We've been given no guidance about which Visual Studio 9
+            # suite to use, so attempt to autodetect.
+            suites = get_visualstudio9_suites()
+            if suites:
+                vs8suite = suites[0]
+
+        if vs8suite == 'EXPRESS':
+            K = 'Software\\Microsoft\\VCExpress\\' + str(version_num)
+    elif (version_num >= 8.0):
         if vs8suite == None:
             # We've been given no guidance about which Visual Studio 8
             # suite to use, so attempt to autodetect.
@@ -1412,6 +1492,7 @@ def get_msvs_install_dirs(version = None, vs8suite = None):
             '7.0'   : 'v1.0',
             '7.1'   : 'v1.1',
             '8.0'   : 'v2.0',
+            '9.0'   : 'v3.5'
             # TODO: Does .NET 3.0 need to be worked into here somewhere?
         }
         try:
@@ -1489,6 +1570,52 @@ def get_msvs_install_dirs(version = None, vs8suite = None):
         except SCons.Util.RegError:
             pass
 
+    # Newer MS SDK versions
+    if not rv.has_key('PLATFORMSDKDIR'):
+        
+        # list of  main registry keys to check
+        locs = [
+            # MS SDK v6.0a (later versions too?)
+            r'Software\Microsoft\Microsoft SDKs\Windows', 
+            r'Software\Microsoft\MicrosoftSDK\InstalledSDKs'
+            ]
+        rootKeys = [SCons.Util.HKEY_LOCAL_MACHINE, SCons.Util.HKEY_CURRENT_USER]
+        
+        installDirs = []
+
+        for location in locs:
+            try:
+                for rootKey in rootKeys:
+                    k = SCons.Util.RegOpenKeyEx(rootKey, location)
+                    i = 0
+                    while 1:
+                        try:
+                            key = SCons.Util.RegEnumKey(k,i)
+                            sdk = SCons.Util.RegOpenKeyEx(k,key)
+                            j = 0
+                            installDir = ''
+                            while 1:
+                                try:
+                                    (vk,vv,t) = SCons.Util.RegEnumValue(sdk,j)
+
+                                    if (vk.lower() == 'installationfolder' or 
+                                        vk.lower() == 'install dir'):
+                                        installDir = vv
+                                        break
+                                    j = j + 1
+                                except SCons.Util.RegError:
+                                    break
+                            if installDir:
+                                installDirs.append(installDir)
+                            i = i + 1
+                        except SCons.Util.RegError:
+                            break
+            except SCons.Util.RegError:
+                pass
+
+        if len(installDirs) > 0:
+            rv['PLATFORMSDKDIR'] = installDirs[0]
+
     return rv
 
 def GetMSVSProjectSuffix(target, source, env, for_signature):