# MIT License # # Copyright 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. """ Constants and initialized data structures for Microsoft Visual C/C++. """ from collections import ( namedtuple, ) from . import Util from .Exceptions import ( MSVCInternalError, ) from . import Dispatcher Dispatcher.register_modulename(__name__) UNDEFINED = object() BOOLEAN_SYMBOLS = {} BOOLEAN_EXTERNAL = {} for bool_val, symbol_list, symbol_case_list in [ (False, (False, 0, '0', None, ''), ('False', 'No', 'F', 'N')), (True, (True, 1, '1'), ('True', 'Yes', 'T', 'Y')), ]: BOOLEAN_SYMBOLS[bool_val] = list(symbol_list) for symbol in symbol_case_list: BOOLEAN_SYMBOLS[bool_val].extend([symbol, symbol.lower(), symbol.upper()]) for symbol in BOOLEAN_SYMBOLS[bool_val]: BOOLEAN_EXTERNAL[symbol] = bool_val MSVC_PLATFORM_DEFINITION = namedtuple('MSVCPlatform', [ 'vc_platform', 'is_uwp', ]) MSVC_PLATFORM_DEFINITION_LIST = [] MSVC_PLATFORM_INTERNAL = {} MSVC_PLATFORM_EXTERNAL = {} for vc_platform, is_uwp in [ ('Desktop', False), ('UWP', True), ]: vc_platform_def = MSVC_PLATFORM_DEFINITION( vc_platform = vc_platform, is_uwp = is_uwp, ) MSVC_PLATFORM_DEFINITION_LIST.append(vc_platform_def) MSVC_PLATFORM_INTERNAL[vc_platform] = vc_platform_def for symbol in [vc_platform, vc_platform.lower(), vc_platform.upper()]: MSVC_PLATFORM_EXTERNAL[symbol] = vc_platform_def MSVC_RUNTIME_DEFINITION = namedtuple('MSVCRuntime', [ 'vc_runtime', 'vc_runtime_numeric', 'vc_runtime_alias_list', 'vc_runtime_vsdef_list', ]) MSVC_RUNTIME_DEFINITION_LIST = [] MSVC_RUNTIME_INTERNAL = {} MSVC_RUNTIME_EXTERNAL = {} for vc_runtime, vc_runtime_numeric, vc_runtime_alias_list in [ ('140', 140, ['ucrt']), ('120', 120, ['msvcr120']), ('110', 110, ['msvcr110']), ('100', 100, ['msvcr100']), ('90', 90, ['msvcr90']), ('80', 80, ['msvcr80']), ('71', 71, ['msvcr71']), ('70', 70, ['msvcr70']), ('60', 60, ['msvcrt']), ]: vc_runtime_def = MSVC_RUNTIME_DEFINITION( vc_runtime = vc_runtime, vc_runtime_numeric = vc_runtime_numeric, vc_runtime_alias_list = vc_runtime_alias_list, vc_runtime_vsdef_list = [], ) MSVC_RUNTIME_DEFINITION_LIST.append(vc_runtime_def) MSVC_RUNTIME_INTERNAL[vc_runtime] = vc_runtime_def MSVC_RUNTIME_EXTERNAL[vc_runtime] = vc_runtime_def for vc_runtime_alias in vc_runtime_alias_list: MSVC_RUNTIME_EXTERNAL[vc_runtime_alias] = vc_runtime_def MSVC_BUILDTOOLS_DEFINITION = namedtuple('MSVCBuildtools', [ 'vc_buildtools', 'vc_buildtools_numeric', 'vc_version', 'vc_version_numeric', 'cl_version', 'cl_version_numeric', 'vc_runtime_def', 'vc_istoolset', ]) MSVC_BUILDTOOLS_DEFINITION_LIST = [] MSVC_BUILDTOOLS_INTERNAL = {} MSVC_BUILDTOOLS_EXTERNAL = {} VC_VERSION_MAP = {} for vc_buildtools, vc_version, cl_version, vc_runtime, vc_istoolset in [ ('v143', '14.3', '19.3', '140', True), ('v142', '14.2', '19.2', '140', True), ('v141', '14.1', '19.1', '140', True), ('v140', '14.0', '19.0', '140', True), ('v120', '12.0', '18.0', '120', False), ('v110', '11.0', '17.0', '110', False), ('v100', '10.0', '16.0', '100', False), ('v90', '9.0', '15.0', '90', False), ('v80', '8.0', '14.0', '80', False), ('v71', '7.1', '13.1', '71', False), ('v70', '7.0', '13.0', '70', False), ('v60', '6.0', '12.0', '60', False), ]: vc_runtime_def = MSVC_RUNTIME_INTERNAL[vc_runtime] vc_buildtools_def = MSVC_BUILDTOOLS_DEFINITION( vc_buildtools = vc_buildtools, vc_buildtools_numeric = int(vc_buildtools[1:]), vc_version = vc_version, vc_version_numeric = float(vc_version), cl_version = cl_version, cl_version_numeric = float(cl_version), vc_runtime_def = vc_runtime_def, vc_istoolset = vc_istoolset, ) MSVC_BUILDTOOLS_DEFINITION_LIST.append(vc_buildtools_def) MSVC_BUILDTOOLS_INTERNAL[vc_buildtools] = vc_buildtools_def MSVC_BUILDTOOLS_EXTERNAL[vc_buildtools] = vc_buildtools_def MSVC_BUILDTOOLS_EXTERNAL[vc_version] = vc_buildtools_def VC_VERSION_MAP[vc_version] = vc_buildtools_def MSVS_VERSION_INTERNAL = {} MSVS_VERSION_EXTERNAL = {} MSVC_VERSION_INTERNAL = {} MSVC_VERSION_EXTERNAL = {} MSVC_VERSION_SUFFIX = {} MSVS_VERSION_MAJOR_MAP = {} CL_VERSION_MAP = {} MSVC_SDK_VERSIONS = set() VISUALSTUDIO_DEFINITION = namedtuple('VisualStudioDefinition', [ 'vs_product', 'vs_product_alias_list', 'vs_version', 'vs_version_major', 'vs_envvar', 'vs_express', 'vs_lookup', 'vc_sdk_versions', 'vc_ucrt_versions', 'vc_uwp', 'vc_buildtools_def', 'vc_buildtools_all', ]) VISUALSTUDIO_DEFINITION_LIST = [] VS_PRODUCT_ALIAS = { '1998': ['6'] } # vs_envvar: VisualStudioVersion defined in environment for MSVS 2012 and later # MSVS 2010 and earlier cl_version -> vs_def is a 1:1 mapping # SDK attached to product or buildtools? for vs_product, vs_version, vs_envvar, vs_express, vs_lookup, vc_sdk, vc_ucrt, vc_uwp, vc_buildtools_all in [ ('2022', '17.0', True, False, 'vswhere' , ['10.0', '8.1'], ['10'], 'uwp', ['v143', 'v142', 'v141', 'v140']), ('2019', '16.0', True, False, 'vswhere' , ['10.0', '8.1'], ['10'], 'uwp', ['v142', 'v141', 'v140']), ('2017', '15.0', True, True, 'vswhere' , ['10.0', '8.1'], ['10'], 'uwp', ['v141', 'v140']), ('2015', '14.0', True, True, 'registry', ['10.0', '8.1'], ['10'], 'store', ['v140']), ('2013', '12.0', True, True, 'registry', None, None, None, ['v120']), ('2012', '11.0', True, True, 'registry', None, None, None, ['v110']), ('2010', '10.0', False, True, 'registry', None, None, None, ['v100']), ('2008', '9.0', False, True, 'registry', None, None, None, ['v90']), ('2005', '8.0', False, True, 'registry', None, None, None, ['v80']), ('2003', '7.1', False, False, 'registry', None, None, None, ['v71']), ('2002', '7.0', False, False, 'registry', None, None, None, ['v70']), ('1998', '6.0', False, False, 'registry', None, None, None, ['v60']), ]: vs_version_major = vs_version.split('.')[0] vc_buildtools_def = MSVC_BUILDTOOLS_INTERNAL[vc_buildtools_all[0]] vs_def = VISUALSTUDIO_DEFINITION( vs_product = vs_product, vs_product_alias_list = [], vs_version = vs_version, vs_version_major = vs_version_major, vs_envvar = vs_envvar, vs_express = vs_express, vs_lookup = vs_lookup, vc_sdk_versions = vc_sdk, vc_ucrt_versions = vc_ucrt, vc_uwp = vc_uwp, vc_buildtools_def = vc_buildtools_def, vc_buildtools_all = vc_buildtools_all, ) VISUALSTUDIO_DEFINITION_LIST.append(vs_def) vc_buildtools_def.vc_runtime_def.vc_runtime_vsdef_list.append(vs_def) vc_version = vc_buildtools_def.vc_version MSVS_VERSION_INTERNAL[vs_product] = vs_def MSVS_VERSION_EXTERNAL[vs_product] = vs_def MSVS_VERSION_EXTERNAL[vs_version] = vs_def MSVC_VERSION_INTERNAL[vc_version] = vs_def MSVC_VERSION_EXTERNAL[vs_product] = vs_def MSVC_VERSION_EXTERNAL[vc_version] = vs_def MSVC_VERSION_EXTERNAL[vc_buildtools_def.vc_buildtools] = vs_def if vs_product in VS_PRODUCT_ALIAS: for vs_product_alias in VS_PRODUCT_ALIAS[vs_product]: vs_def.vs_product_alias_list.append(vs_product_alias) MSVS_VERSION_EXTERNAL[vs_product_alias] = vs_def MSVC_VERSION_EXTERNAL[vs_product_alias] = vs_def MSVC_VERSION_SUFFIX[vc_version] = vs_def if vs_express: MSVC_VERSION_SUFFIX[vc_version + 'Exp'] = vs_def MSVS_VERSION_MAJOR_MAP[vs_version_major] = vs_def CL_VERSION_MAP[vc_buildtools_def.cl_version] = vs_def if vc_sdk: MSVC_SDK_VERSIONS.update(vc_sdk) # EXPERIMENTAL: msvc version/toolset search lists # # VS2017 example: # # defaults['14.1'] = ['14.1', '14.1Exp'] # defaults['14.1Exp'] = ['14.1Exp'] # # search['14.1'] = ['14.3', '14.2', '14.1', '14.1Exp'] # search['14.1Exp'] = ['14.1Exp'] MSVC_VERSION_TOOLSET_DEFAULTS_MAP = {} MSVC_VERSION_TOOLSET_SEARCH_MAP = {} # Pass 1: Build defaults lists and setup express versions for vs_def in VISUALSTUDIO_DEFINITION_LIST: if not vs_def.vc_buildtools_def.vc_istoolset: continue version_key = vs_def.vc_buildtools_def.vc_version MSVC_VERSION_TOOLSET_DEFAULTS_MAP[version_key] = [version_key] MSVC_VERSION_TOOLSET_SEARCH_MAP[version_key] = [] if vs_def.vs_express: express_key = version_key + 'Exp' MSVC_VERSION_TOOLSET_DEFAULTS_MAP[version_key].append(express_key) MSVC_VERSION_TOOLSET_DEFAULTS_MAP[express_key] = [express_key] MSVC_VERSION_TOOLSET_SEARCH_MAP[express_key] = [express_key] # Pass 2: Extend search lists (decreasing version order) for vs_def in VISUALSTUDIO_DEFINITION_LIST: if not vs_def.vc_buildtools_def.vc_istoolset: continue version_key = vs_def.vc_buildtools_def.vc_version for vc_buildtools in vs_def.vc_buildtools_all: toolset_buildtools_def = MSVC_BUILDTOOLS_INTERNAL[vc_buildtools] toolset_vs_def = MSVC_VERSION_INTERNAL[toolset_buildtools_def.vc_version] buildtools_key = toolset_buildtools_def.vc_version MSVC_VERSION_TOOLSET_SEARCH_MAP[buildtools_key].extend(MSVC_VERSION_TOOLSET_DEFAULTS_MAP[version_key]) # convert string version set to string version list ranked in descending order MSVC_SDK_VERSIONS = [str(f) for f in sorted([float(s) for s in MSVC_SDK_VERSIONS], reverse=True)] def verify(): from .. import vc for msvc_version in vc._VCVER: if msvc_version not in MSVC_VERSION_SUFFIX: err_msg = 'msvc_version {} not in MSVC_VERSION_SUFFIX'.format(repr(msvc_version)) raise MSVCInternalError(err_msg) vc_version = Util.get_msvc_version_prefix(msvc_version) if vc_version not in MSVC_VERSION_INTERNAL: err_msg = 'vc_version {} not in MSVC_VERSION_INTERNAL'.format(repr(vc_version)) raise MSVCInternalError(err_msg)