From 7c651e273c4db37f4babd91aaecf26800c50dd79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Thu, 28 Sep 2017 10:21:20 +0200 Subject: New upstream version 3.0.0 --- engine/SCons/Tool/MSCommon/__init__.py | 7 +- engine/SCons/Tool/MSCommon/arch.py | 4 +- engine/SCons/Tool/MSCommon/common.py | 100 ++++++++++-------- engine/SCons/Tool/MSCommon/netframework.py | 14 +-- engine/SCons/Tool/MSCommon/sdk.py | 51 +++++---- engine/SCons/Tool/MSCommon/vc.py | 162 ++++++++++++++++++----------- engine/SCons/Tool/MSCommon/vs.py | 31 ++++-- 7 files changed, 228 insertions(+), 141 deletions(-) (limited to 'engine/SCons/Tool/MSCommon') diff --git a/engine/SCons/Tool/MSCommon/__init__.py b/engine/SCons/Tool/MSCommon/__init__.py index 6b637fe..989ab08 100644 --- a/engine/SCons/Tool/MSCommon/__init__.py +++ b/engine/SCons/Tool/MSCommon/__init__.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2001 - 2016 The SCons Foundation +# Copyright (c) 2001 - 2017 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -21,7 +21,7 @@ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/MSCommon/__init__.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog" +__revision__ = "src/engine/SCons/Tool/MSCommon/__init__.py rel_3.0.0:4395:8972f6a2f699 2017/09/18 12:59:24 bdbaddog" __doc__ = """ Common functions for Microsoft Visual Studio and Visual C/C++. @@ -41,7 +41,8 @@ from SCons.Tool.MSCommon.sdk import mssdk_exists, \ from SCons.Tool.MSCommon.vc import msvc_exists, \ msvc_setup_env, \ - msvc_setup_env_once + msvc_setup_env_once, \ + msvc_version_to_maj_min from SCons.Tool.MSCommon.vs import get_default_version, \ get_vs_by_version, \ diff --git a/engine/SCons/Tool/MSCommon/arch.py b/engine/SCons/Tool/MSCommon/arch.py index 46fb601..96f05a8 100644 --- a/engine/SCons/Tool/MSCommon/arch.py +++ b/engine/SCons/Tool/MSCommon/arch.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2001 - 2016 The SCons Foundation +# Copyright (c) 2001 - 2017 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -21,7 +21,7 @@ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/MSCommon/arch.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog" +__revision__ = "src/engine/SCons/Tool/MSCommon/arch.py rel_3.0.0:4395:8972f6a2f699 2017/09/18 12:59:24 bdbaddog" __doc__ = """Module to define supported Windows chip architectures. """ diff --git a/engine/SCons/Tool/MSCommon/common.py b/engine/SCons/Tool/MSCommon/common.py index 1467543..fcf623f 100644 --- a/engine/SCons/Tool/MSCommon/common.py +++ b/engine/SCons/Tool/MSCommon/common.py @@ -1,5 +1,8 @@ +""" +Common helper functions for working with the Microsoft tool chain. +""" # -# Copyright (c) 2001 - 2016 The SCons Foundation +# Copyright (c) 2001 - 2017 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,12 +23,9 @@ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # +from __future__ import print_function -__revision__ = "src/engine/SCons/Tool/MSCommon/common.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog" - -__doc__ = """ -Common helper functions for working with the Microsoft tool chain. -""" +__revision__ = "src/engine/SCons/Tool/MSCommon/common.py rel_3.0.0:4395:8972f6a2f699 2017/09/18 12:59:24 bdbaddog" import copy import os @@ -35,17 +35,17 @@ import re import SCons.Util -logfile = os.environ.get('SCONS_MSCOMMON_DEBUG') -if logfile == '-': - def debug(x): - print x -elif logfile: +LOGFILE = os.environ.get('SCONS_MSCOMMON_DEBUG') +if LOGFILE == '-': + def debug(message): + print(message) +elif LOGFILE: try: import logging except ImportError: - debug = lambda x: open(logfile, 'a').write(x + '\n') + debug = lambda message: open(LOGFILE, 'a').write(message + '\n') else: - logging.basicConfig(filename=logfile, level=logging.DEBUG) + logging.basicConfig(filename=LOGFILE, level=logging.DEBUG) debug = logging.debug else: debug = lambda x: None @@ -75,7 +75,7 @@ def is_win64(): # I structured these tests to make it easy to add new ones or # add exceptions in the future, because this is a bit fragile. _is_win64 = False - if os.environ.get('PROCESSOR_ARCHITECTURE','x86') != 'x86': + if os.environ.get('PROCESSOR_ARCHITECTURE', 'x86') != 'x86': _is_win64 = True if os.environ.get('PROCESSOR_ARCHITEW6432'): _is_win64 = True @@ -113,21 +113,30 @@ def normalize_env(env, keys, force=False): Note: the environment is copied.""" normenv = {} if env: - for k in env.keys(): - normenv[k] = copy.deepcopy(env[k]).encode('mbcs') + for k in list(env.keys()): + normenv[k] = copy.deepcopy(env[k]) for k in keys: if k in os.environ and (force or not k in normenv): - normenv[k] = os.environ[k].encode('mbcs') + normenv[k] = os.environ[k] # This shouldn't be necessary, since the default environment should include system32, # but keep this here to be safe, since it's needed to find reg.exe which the MSVC # bat scripts use. - sys32_dir = os.path.join(os.environ.get("SystemRoot", os.environ.get("windir",r"C:\Windows\system32")),"System32") + sys32_dir = os.path.join(os.environ.get("SystemRoot", + os.environ.get("windir", r"C:\Windows\system32")), + "System32") if sys32_dir not in normenv['PATH']: normenv['PATH'] = normenv['PATH'] + os.pathsep + sys32_dir + # Without Wbem in PATH, vcvarsall.bat has a "'wmic' is not recognized" + # error starting with Visual Studio 2017, although the script still + # seems to work anyway. + sys32_wbem_dir = os.path.join(sys32_dir, 'Wbem') + if sys32_wbem_dir not in normenv['PATH']: + normenv['PATH'] = normenv['PATH'] + os.pathsep + sys32_wbem_dir + debug("PATH: %s"%normenv['PATH']) return normenv @@ -144,11 +153,13 @@ def get_output(vcbat, args = None, env = None): # 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 = [ + vs_vc_vars = [ 'COMSPEC', -# VS100 and VS110: Still set, but modern MSVC setup scripts will -# discard these if registry has values. However Intel compiler setup -# script still requires these as of 2013/2014. + # VS100 and VS110: Still set, but modern MSVC setup scripts will + # discard these if registry has values. However Intel compiler setup + # script still requires these as of 2013/2014. + 'VS140COMNTOOLS', + 'VS120COMNTOOLS', 'VS110COMNTOOLS', 'VS100COMNTOOLS', 'VS90COMNTOOLS', @@ -157,22 +168,22 @@ def get_output(vcbat, args = None, env = None): 'VS70COMNTOOLS', 'VS60COMNTOOLS', ] - env['ENV'] = normalize_env(env['ENV'], vars, force=False) + env['ENV'] = normalize_env(env['ENV'], vs_vc_vars, force=False) if args: debug("Calling '%s %s'" % (vcbat, args)) popen = SCons.Action._subproc(env, - '"%s" %s & set' % (vcbat, args), - stdin = 'devnull', - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) + '"%s" %s & set' % (vcbat, args), + stdin='devnull', + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) else: debug("Calling '%s'" % vcbat) popen = SCons.Action._subproc(env, - '"%s" & set' % vcbat, - stdin = 'devnull', - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) + '"%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 @@ -195,10 +206,14 @@ def get_output(vcbat, args = None, env = None): output = stdout.decode("mbcs") return output -def parse_output(output, keep = ("INCLUDE", "LIB", "LIBPATH", "PATH")): +def parse_output(output, keep=("INCLUDE", "LIB", "LIBPATH", "PATH")): + """ + Parse output from running visual c++/studios vcvarsall.bat and running set + To capture the values listed in keep + """ + # dkeep is a dict associating key: path_list, where key is one item from # keep, and pat_list the associated list of paths - dkeep = dict([(i, []) for i in keep]) # rdk will keep the regex to match the .bat file output line starts @@ -207,22 +222,21 @@ def parse_output(output, keep = ("INCLUDE", "LIB", "LIBPATH", "PATH")): rdk[i] = re.compile('%s=(.*)' % i, re.I) def add_env(rmatch, key, dkeep=dkeep): - plist = rmatch.group(1).split(os.pathsep) - for p in plist: + path_list = rmatch.group(1).split(os.pathsep) + for path in path_list: # Do not add empty paths (when a var ends with ;) - if p: - p = p.encode('mbcs') + if path: # XXX: For some reason, VC98 .bat file adds "" around the PATH # values, and it screws up the environment later, so we strip # it. - p = p.strip('"') - dkeep[key].append(p) + path = path.strip('"') + dkeep[key].append(str(path)) for line in output.splitlines(): - for k,v in rdk.items(): - m = v.match(line) - if m: - add_env(m, k) + for k, value in rdk.items(): + match = value.match(line) + if match: + add_env(match, k) return dkeep diff --git a/engine/SCons/Tool/MSCommon/netframework.py b/engine/SCons/Tool/MSCommon/netframework.py index 8d39cf6..b769c44 100644 --- a/engine/SCons/Tool/MSCommon/netframework.py +++ b/engine/SCons/Tool/MSCommon/netframework.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2001 - 2016 The SCons Foundation +# Copyright (c) 2001 - 2017 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,7 +20,7 @@ # 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 rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog" +__revision__ = "src/engine/SCons/Tool/MSCommon/netframework.py rel_3.0.0:4395:8972f6a2f699 2017/09/18 12:59:24 bdbaddog" __doc__ = """ """ @@ -29,7 +29,7 @@ import os import re import SCons.Util -from common import read_reg, debug +from .common import read_reg, debug # Original value recorded by dcournapeau _FRAMEWORKDIR_HKEY_ROOT = r'Software\Microsoft\.NETFramework\InstallRoot' @@ -40,13 +40,13 @@ def find_framework_root(): # XXX: find it from environment (FrameworkDir) try: froot = read_reg(_FRAMEWORKDIR_HKEY_ROOT) - debug("Found framework install root in registry: %s" % froot) - except SCons.Util.WinError, e: - debug("Could not read reg key %s" % _FRAMEWORKDIR_HKEY_ROOT) + debug("Found framework install root in registry: {}".format(froot)) + except SCons.Util.WinError as e: + debug("Could not read reg key {}".format(_FRAMEWORKDIR_HKEY_ROOT)) return None if not os.path.exists(froot): - debug("%s not found on fs" % froot) + debug("{} not found on fs".format(froot)) return None return froot diff --git a/engine/SCons/Tool/MSCommon/sdk.py b/engine/SCons/Tool/MSCommon/sdk.py index 53bb8aa..8bc9830 100644 --- a/engine/SCons/Tool/MSCommon/sdk.py +++ b/engine/SCons/Tool/MSCommon/sdk.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2001 - 2016 The SCons Foundation +# Copyright (c) 2001 - 2017 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -21,7 +21,7 @@ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -__revision__ = "src/engine/SCons/Tool/MSCommon/sdk.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog" +__revision__ = "src/engine/SCons/Tool/MSCommon/sdk.py rel_3.0.0:4395:8972f6a2f699 2017/09/18 12:59:24 bdbaddog" __doc__ = """Module to detect the Platform/Windows SDK @@ -33,7 +33,7 @@ import os import SCons.Errors import SCons.Util -import common +from . import common debug = common.debug @@ -76,23 +76,23 @@ class SDKDefinition(object): return None hkey = self.HKEY_FMT % self.hkey_data - debug('find_sdk_dir(): checking registry:%s'%hkey) + debug('find_sdk_dir(): checking registry:{}'.format(hkey)) try: sdk_dir = common.read_reg(hkey) - except SCons.Util.WinError, e: - debug('find_sdk_dir(): no SDK registry key %s' % repr(hkey)) + except SCons.Util.WinError as e: + debug('find_sdk_dir(): no SDK registry key {}'.format(repr(hkey))) return None - debug('find_sdk_dir(): Trying SDK Dir: %s'%sdk_dir) + debug('find_sdk_dir(): Trying SDK Dir: {}'.format(sdk_dir)) if not os.path.exists(sdk_dir): - debug('find_sdk_dir(): %s not on file system' % sdk_dir) + debug('find_sdk_dir(): {} not on file system'.format(sdk_dir)) return None 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 {} not found".format(ftc)) return None return sdk_dir @@ -105,7 +105,7 @@ class SDKDefinition(object): sdk_dir = self.find_sdk_dir() self._sdk_dir = sdk_dir return sdk_dir - + def get_sdk_vc_script(self,host_arch, target_arch): """ Return the script to initialize the VC compiler installed by SDK """ @@ -113,11 +113,11 @@ class SDKDefinition(object): if (host_arch == 'amd64' and target_arch == 'x86'): # No cross tools needed compiling 32 bits on 64 bit machine host_arch=target_arch - + arch_string=target_arch if (host_arch != target_arch): arch_string='%s_%s'%(host_arch,target_arch) - + debug("sdk.py: get_sdk_vc_script():arch_string:%s host_arch:%s target_arch:%s"%(arch_string, host_arch, target_arch)) @@ -164,6 +164,12 @@ SDK70VCSetupScripts = { 'x86' : r'bin\vcvars32.bat', 'x86_ia64' : r'bin\vcvarsx86_ia64.bat', 'ia64' : r'bin\vcvarsia64.bat'} +SDK100VCSetupScripts = {'x86' : r'bin\vcvars32.bat', + 'amd64' : r'bin\vcvars64.bat', + 'x86_amd64': r'bin\x86_amd64\vcvarsx86_amd64.bat', + 'x86_arm' : r'bin\x86_arm\vcvarsx86_arm.bat'} + + # The list of support SDKs which we know how to detect. # # The first SDK found in the list is the one used by default if there @@ -172,6 +178,16 @@ SDK70VCSetupScripts = { 'x86' : r'bin\vcvars32.bat', # # If you update this list, update the documentation in Tool/mssdk.xml. SupportedSDKList = [ + WindowsSDK('10.0', + sanity_check_file=r'bin\SetEnv.Cmd', + include_subdir='include', + lib_subdir={ + 'x86' : ['lib'], + 'x86_64' : [r'lib\x64'], + 'ia64' : [r'lib\ia64'], + }, + vc_setup_scripts = SDK70VCSetupScripts, + ), WindowsSDK('7.1', sanity_check_file=r'bin\SetEnv.Cmd', include_subdir='include', @@ -308,8 +324,7 @@ def set_sdk_by_directory(env, sdk_dir): def get_sdk_by_version(mssdk): if mssdk not in SupportedSDKMap: - msg = "SDK version %s is not supported" % repr(mssdk) - raise SCons.Errors.UserError(msg) + raise SCons.Errors.UserError("SDK version {} is not supported".format(repr(mssdk))) get_installed_sdks() return InstalledSDKMap.get(mssdk) @@ -327,16 +342,16 @@ def mssdk_setup_env(env): if sdk_dir is None: return sdk_dir = env.subst(sdk_dir) - debug('sdk.py:mssdk_setup_env: Using MSSDK_DIR:%s'%sdk_dir) + debug('sdk.py:mssdk_setup_env: Using MSSDK_DIR:{}'.format(sdk_dir)) elif 'MSSDK_VERSION' in env: sdk_version = env['MSSDK_VERSION'] if sdk_version is None: - msg = "SDK version is specified as None" + msg = "SDK version is specified as None" raise SCons.Errors.UserError(msg) sdk_version = env.subst(sdk_version) mssdk = get_sdk_by_version(sdk_version) if mssdk is None: - msg = "SDK version %s is not installed" % sdk_version + msg = "SDK version %s is not installed" % sdk_version raise SCons.Errors.UserError(msg) sdk_dir = mssdk.get_sdk_dir() debug('sdk.py:mssdk_setup_env: Using MSSDK_VERSION:%s'%sdk_dir) @@ -347,7 +362,7 @@ def mssdk_setup_env(env): debug('sdk.py:mssdk_setup_env thinks msvs_version is None') return msvs_version = env.subst(msvs_version) - import vs + from . import vs msvs = vs.get_vs_by_version(msvs_version) debug('sdk.py:mssdk_setup_env:msvs is :%s'%msvs) if not msvs: diff --git a/engine/SCons/Tool/MSCommon/vc.py b/engine/SCons/Tool/MSCommon/vc.py index ca8a2da..fba86af 100644 --- a/engine/SCons/Tool/MSCommon/vc.py +++ b/engine/SCons/Tool/MSCommon/vc.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2001 - 2016 The SCons Foundation +# Copyright (c) 2001 - 2017 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -30,24 +30,25 @@ # * test on 64 bits XP + VS 2005 (and VS 6 if possible) # * SDK # * Assembly -__revision__ = "src/engine/SCons/Tool/MSCommon/vc.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog" +__revision__ = "src/engine/SCons/Tool/MSCommon/vc.py rel_3.0.0:4395:8972f6a2f699 2017/09/18 12:59:24 bdbaddog" __doc__ = """Module for Visual C/C++ detection and configuration. """ import SCons.compat import SCons.Util +import subprocess import os import platform from string import digits as string_digits import SCons.Warnings -import common +from . import common debug = common.debug -import sdk +from . import sdk get_installed_sdks = sdk.get_installed_sdks @@ -108,7 +109,7 @@ def get_host_target(env): # PROCESSOR_ARCHITECTURE. if not host_platform: host_platform = os.environ.get('PROCESSOR_ARCHITECTURE', '') - + # 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) @@ -118,26 +119,28 @@ def get_host_target(env): target_platform = req_target_platform else: target_platform = host_platform - + try: host = _ARCH_TO_CANONICAL[host_platform.lower()] - except KeyError, e: + except KeyError as e: msg = "Unrecognized host architecture %s" raise ValueError(msg % repr(host_platform)) try: target = _ARCH_TO_CANONICAL[target_platform.lower()] - except KeyError, e: - all_archs = str(_ARCH_TO_CANONICAL.keys()) + except KeyError as e: + all_archs = str(list(_ARCH_TO_CANONICAL.keys())) raise ValueError("Unrecognized target architecture %s\n\tValid architectures: %s" % (target_platform, all_archs)) return (host, target,req_target_platform) # If you update this, update SupportedVSList in Tool/MSCommon/vs.py, and the # MSVC_VERSION documentation in Tool/msvc.xml. -_VCVER = ["14.0", "14.0Exp", "12.0", "12.0Exp", "11.0", "11.0Exp", "10.0", "10.0Exp", "9.0", "9.0Exp","8.0", "8.0Exp","7.1", "7.0", "6.0"] +_VCVER = ["14.1", "14.0", "14.0Exp", "12.0", "12.0Exp", "11.0", "11.0Exp", "10.0", "10.0Exp", "9.0", "9.0Exp","8.0", "8.0Exp","7.1", "7.0", "6.0"] _VCVER_TO_PRODUCT_DIR = { + '14.1' : [ + (SCons.Util.HKEY_LOCAL_MACHINE, r'')], # Visual Studio 2017 doesn't set this registry key anymore '14.0' : [ (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VisualStudio\14.0\Setup\VC\ProductDir')], '14.0Exp' : [ @@ -183,19 +186,19 @@ _VCVER_TO_PRODUCT_DIR = { (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VisualStudio\6.0\Setup\Microsoft Visual C++\ProductDir'), ] } - + def msvc_version_to_maj_min(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)) + 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 as 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 @@ -222,6 +225,35 @@ def is_host_target_supported(host_target, msvc_version): return True + +def find_vc_pdir_vswhere(msvc_version): + """ + Find the MSVC product directory using vswhere.exe . + Run it asking for specified version and get MSVS install location + :param msvc_version: + :return: MSVC install dir + """ + vswhere_path = os.path.join( + 'C:\\', + 'Program Files (x86)', + 'Microsoft Visual Studio', + 'Installer', + 'vswhere.exe' + ) + vswhere_cmd = [vswhere_path, '-version', msvc_version, '-property', 'installationPath'] + + if os.path.exists(vswhere_path): + sp = subprocess.Popen(vswhere_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + vsdir, err = sp.communicate() + vsdir = vsdir.decode("mbcs") + vsdir = vsdir.rstrip() + vc_pdir = os.path.join(vsdir, 'VC') + return vc_pdir + else: + # No vswhere on system, no install info available + return None + + def find_vc_pdir(msvc_version): """Try to find the product directory for the given version. @@ -240,26 +272,31 @@ def find_vc_pdir(msvc_version): for hkroot, key in hkeys: try: comps = None - if common.is_win64(): - try: - # ordinally at win64, try Wow6432Node first. - comps = common.read_reg(root + 'Wow6432Node\\' + key, hkroot) - except SCons.Util.WinError, e: - # at Microsoft Visual Studio for Python 2.7, value is not in Wow6432Node - pass - if not comps: - # not Win64, or Microsoft Visual Studio for Python 2.7 - comps = common.read_reg(root + key, hkroot) - except SCons.Util.WinError, e: - debug('find_vc_dir(): no VC registry key %s' % repr(key)) + if not key: + comps = find_vc_pdir_vswhere(msvc_version) + if not comps: + debug('find_vc_dir(): no VC found via vswhere for version {}'.format(repr(key))) + raise SCons.Util.WinError + else: + if common.is_win64(): + try: + # ordinally at win64, try Wow6432Node first. + comps = common.read_reg(root + 'Wow6432Node\\' + key, hkroot) + except SCons.Util.WinError as e: + # at Microsoft Visual Studio for Python 2.7, value is not in Wow6432Node + pass + if not comps: + # not Win64, or Microsoft Visual Studio for Python 2.7 + comps = common.read_reg(root + key, hkroot) + except SCons.Util.WinError as e: + debug('find_vc_dir(): no VC registry key {}'.format(repr(key))) else: - debug('find_vc_dir(): found VC in registry: %s' % comps) + debug('find_vc_dir(): found VC in registry: {}'.format(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) - raise MissingConfiguration("registry dir %s not found on the filesystem" % comps) + debug('find_vc_dir(): reg says dir is {}, but it does not exist. (ignoring)'.format(comps)) + raise MissingConfiguration("registry dir {} not found on the filesystem".format(comps)) return None def find_batch_file(env,msvc_version,host_arch,target_arch): @@ -270,8 +307,8 @@ def find_batch_file(env,msvc_version,host_arch,target_arch): pdir = find_vc_pdir(msvc_version) if pdir is None: raise NoVersionFound("No version of Visual Studio found") - - debug('vc.py: find_batch_file() pdir:%s'%pdir) + + debug('vc.py: find_batch_file() pdir:{}'.format(pdir)) # filter out e.g. "Exp" from the version name msvc_ver_numeric = ''.join([x for x in msvc_version if x in string_digits + "."]) @@ -282,13 +319,15 @@ def find_batch_file(env,msvc_version,host_arch,target_arch): elif vernum < 7: pdir = os.path.join(pdir, "Bin") batfilename = os.path.join(pdir, "vcvars32.bat") - else: # >= 8 + elif 8 <= vernum <= 14: batfilename = os.path.join(pdir, "vcvarsall.bat") + else: # vernum >= 14.1 VS2017 and above + batfilename = os.path.join(pdir, "Auxiliary", "Build", "vcvarsall.bat") if not os.path.exists(batfilename): debug("Not found: %s" % batfilename) batfilename = None - + installed_sdks=get_installed_sdks() for _sdk in installed_sdks: sdk_bat_file = _sdk.get_sdk_vc_script(host_arch,target_arch) @@ -296,7 +335,7 @@ def find_batch_file(env,msvc_version,host_arch,target_arch): debug("vc.py:find_batch_file() not found:%s"%_sdk) else: sdk_bat_file_path = os.path.join(pdir,sdk_bat_file) - if os.path.exists(sdk_bat_file_path): + if os.path.exists(sdk_bat_file_path): debug('vc.py:find_batch_file() sdk_bat_file_path:%s'%sdk_bat_file_path) return (batfilename,sdk_bat_file_path) return (batfilename,None) @@ -323,7 +362,7 @@ def get_installed_vcs(): installed_versions.append(ver) else: debug('find_vc_pdir return None for ver %s' % ver) - except VisualCException, e: + except VisualCException as e: debug('did not find VC %s: caught exception %s' % (ver, str(e))) return installed_versions @@ -359,7 +398,7 @@ def get_default_version(env): msvc_version = env.get('MSVC_VERSION') msvs_version = env.get('MSVS_VERSION') - + debug('get_default_version(): msvc_version:%s msvs_version:%s'%(msvc_version,msvs_version)) if msvs_version and not msvc_version: @@ -409,7 +448,7 @@ def msvc_find_valid_batch_script(env,version): try_target_archs = [target_platform] debug("msvs_find_valid_batch_script(): req_target_platform %s target_platform:%s"%(req_target_platform,target_platform)) - # VS2012 has a "cross compile" environment to build 64 bit + # VS2012 has a "cross compile" environment to build 64 bit # with x86_amd64 as the argument to the batch setup script if req_target_platform in ('amd64','x86_64'): try_target_archs.append('x86_amd64') @@ -427,7 +466,7 @@ def msvc_find_valid_batch_script(env,version): 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): @@ -436,11 +475,19 @@ def msvc_find_valid_batch_script(env,version): SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, warn_msg) arg = _HOST_TARGET_ARCH_TO_BAT_ARCH[host_target] + # Get just version numbers + maj, min = msvc_version_to_maj_min(version) + # VS2015+ + if maj >= 14: + if env.get('MSVC_UWP_APP') == '1': + # Initialize environment variables with store/universal paths + arg += ' store' + # 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: + except VisualCException as e: msg = str(e) debug('Caught exception while looking for batch file (%s)' % msg) warn_msg = "VC version %s not installed. " + \ @@ -449,13 +496,13 @@ def msvc_find_valid_batch_script(env,version): 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: + except BatchFileExecutionError as 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 continue @@ -463,23 +510,23 @@ def msvc_find_valid_batch_script(env,version): debug('vc.py:msvc_find_valid_batch_script() use_script 4: trying sdk script: %s'%(sdk_script)) try: d = script_env(sdk_script) - except BatchFileExecutionError,e: + except BatchFileExecutionError as 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 - + debug("vc.py:msvc_find_valid_batch_script() Found a working script/target: %s %s"%(repr(sdk_script),arg)) break # We've found a working target_platform, so stop looking - + # 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()') @@ -498,12 +545,12 @@ def msvc_setup_env(env): env['MSVS_VERSION'] = version env['MSVS'] = {} - + use_script = env.get('MSVC_USE_SCRIPT', True) if SCons.Util.is_String(use_script): debug('vc.py:msvc_setup_env() use_script 1 %s\n' % repr(use_script)) d = script_env(use_script) - elif use_script: + 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: @@ -524,4 +571,3 @@ def msvc_exists(version=None): if version is None: return len(vcs) > 0 return version in vcs - diff --git a/engine/SCons/Tool/MSCommon/vs.py b/engine/SCons/Tool/MSCommon/vs.py index 1f04cbe..dafdbaf 100644 --- a/engine/SCons/Tool/MSCommon/vs.py +++ b/engine/SCons/Tool/MSCommon/vs.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2001 - 2016 The SCons Foundation +# Copyright (c) 2001 - 2017 The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -21,7 +21,7 @@ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # -__revision__ = "src/engine/SCons/Tool/MSCommon/vs.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog" +__revision__ = "src/engine/SCons/Tool/MSCommon/vs.py rel_3.0.0:4395:8972f6a2f699 2017/09/18 12:59:24 bdbaddog" __doc__ = """Module to detect Visual Studio and/or Visual C/C++ """ @@ -31,7 +31,7 @@ import os import SCons.Errors import SCons.Util -from common import debug, \ +from .common import debug, \ get_output, \ is_win64, \ normalize_env, \ @@ -83,10 +83,10 @@ class VisualStudio(object): key = root + key try: comps = read_reg(key) - except SCons.Util.WinError, e: - debug('find_vs_dir_by_reg(): no VS registry key %s' % repr(key)) + except SCons.Util.WinError as e: + debug('find_vs_dir_by_reg(): no VS registry key {}'.format(repr(key))) else: - debug('find_vs_dir_by_reg(): found VS in registry: %s' % comps) + debug('find_vs_dir_by_reg(): found VS in registry: {}'.format(comps)) return comps return None @@ -105,12 +105,12 @@ class VisualStudio(object): def find_executable(self): vs_dir = self.get_vs_dir() if not vs_dir: - debug('find_executable(): no vs_dir (%s)'%vs_dir) + debug('find_executable(): no vs_dir ({})'.format(vs_dir)) return None executable = os.path.join(vs_dir, self.executable_path) executable = os.path.normpath(executable) if not os.path.isfile(executable): - debug('find_executable(): %s not on file system' % executable) + debug('find_executable(): {} not on file system'.format(executable)) return None return executable @@ -199,17 +199,28 @@ class VisualStudio(object): # Tool/MSCommon/vc.py, and the MSVC_VERSION documentation in Tool/msvc.xml. SupportedVSList = [ + # Visual Studio 2017 + VisualStudio('14.1', + vc_version='14.1', + sdk_version='10.0A', + hkeys=[], + common_tools_var='VS150COMNTOOLS', + executable_path=r'Common7\IDE\devenv.com', + batch_file_path=r'VC\Auxiliary\Build\vsvars32.bat', + supported_arch=['x86', 'amd64', "arm"], + ), + # Visual Studio 2015 VisualStudio('14.0', vc_version='14.0', - sdk_version='10.0A', + sdk_version='10.0', hkeys=[r'Microsoft\VisualStudio\14.0\Setup\VS\ProductDir'], common_tools_var='VS140COMNTOOLS', executable_path=r'Common7\IDE\devenv.com', batch_file_path=r'Common7\Tools\vsvars32.bat', supported_arch=['x86', 'amd64', "arm"], ), - + # Visual C++ 2015 Express Edition (for Desktop) VisualStudio('14.0Exp', vc_version='14.0', -- cgit v1.2.3