# version 1 def _register_msvc_instances_in_vswhere_json(vswhere_output): msvc_instances = [] for instance in vswhere_output: productId = instance.get('productId','') if not productId: debug('productId not found in vswhere output') continue installationPath = instance.get('installationPath','') if not installationPath: debug('installationPath not found in vswhere output') continue installationVersion = instance.get('installationVersion','') if not installationVersion: debug('installationVersion not found in vswhere output') continue major = installationVersion.split('.')[0] try: msvc_vernum = _MSVC_CONFIG.MSVS_MAJORVERSION_TO_VCVER[major] except KeyError: debug("Unknown version of msvs: %s" % installationVersion) # TODO|JCB new exception type: MSVSProductUnknown? raise UnsupportedVersion("Unknown msvs version %s" % installationVersion) componentId = productId.split('.')[-1] if componentId not in _MSVC_PRODUCTVERSION_COMPONENTIDS[msvc_vernum]['Products']: debug('ignore componentId:%s' % componentId) continue component_rank = _MSVC_COMPONENTID_SELECTION_RANKING.get(componentId,0) if component_rank == 0: debug('unknown componentId:%s' % componentId) continue msvc_version = msvc_vernum msvc_product = msvc_version + _MSVC_COMPONENTID_VERSIONSUFFIX[componentId] if msvc_product in _VCVER: msvc_version = msvc_product if _MSVC_CONFIG.TESTING_IGNORE_INSTALLED_PRODUCT: if msvc_product in _MSVC_CONFIG.TESTING_IGNORE_INSTALLED_PRODUCTS: debug('ignoring product: ' + msvc_product) continue d = { 'msvc_version' : msvc_version, 'msvc_version_numeric' : msvc_vernum, 'msvc_product' : msvc_product, 'productId' : productId, 'installationPath': installationPath, 'componentId' : componentId, 'component_rank' : component_rank, } debug('found msvc instance:(%s,%s)' % (productId, msvc_version)) _MSVC_CONFIG.N_PRODUCTS += 1 _MSVC_CONFIG.MSVC_VSWHERE_INSTANCES_UNIQUE.setdefault(msvc_version,[]).append(d) _MSVC_CONFIG.MSVC_VSWHERE_INSTANCES.setdefault(msvc_version,[]).append(d) if msvc_product != msvc_version: # synthetic version number (e.g., 14.2Ent, 14.2Pro, 14.2Com, 14.2BT) needed when looking up vc_dir debug('found specific msvc instance:(%s,%s)' % (productId, msvc_product)) _MSVC_CONFIG.MSVC_VSWHERE_INSTANCES.setdefault(msvc_product,[]).append(d) else: # Known products (e.g., 14.1Exp) are not entered in the "bare" version number list # due to vc_dir lookup when walking _VCVER list. # Extended version support will use the "fully qualified" product type list. pass msvc_instances.append(d) for version, instances in _MSVC_CONFIG.MSVC_VSWHERE_INSTANCES_UNIQUE.items(): if len(instances): # sort multiple instances remaining based on productId priority: largest rank to smallest rank _MSVC_CONFIG.MSVC_VSWHERE_INSTANCES_UNIQUE[version] = sorted(instances, key = lambda x: x['component_rank'], reverse=True) for version, instances in _MSVC_CONFIG.MSVC_VSWHERE_INSTANCES.items(): if len(instances): # sort multiple instances remaining based on productId priority: largest rank to smallest rank _MSVC_CONFIG.MSVC_VSWHERE_INSTANCES[version] = sorted(instances, key = lambda x: x['component_rank'], reverse=True) return msvc_instances # version 2 including prerelease flag @classmethod def vs_process_json_output(cls, vs_rel, vswhere_output, vs_cfg): msvs_instances = [] for instance in vswhere_output: #print(json.dumps(instance, indent=4, sort_keys=True)) productId = instance.get('productId','') if not productId: debug('productId not found in vswhere output') continue installationPath = instance.get('installationPath','') if not installationPath: debug('installationPath not found in vswhere output') continue installationVersion = instance.get('installationVersion','') if not installationVersion: debug('installationVersion not found in vswhere output') continue major = installationVersion.split('.')[0] if major != vs_cfg.vs_major: raise InternalError('Internal error: msvs major version mis-match: %s, %s' % (major, vs_cfg.vs_major)) component_id = productId.split('.')[-1] if component_id not in vs_cfg.vs_products: debug('ignore component_id:%s' % component_id) continue component_rank = _VSDetectConst.MSVC_COMPONENTID_SELECTION_RANKING.get(component_id,0) if component_rank == 0: # JCB|TODO: exception and/or stderr? debug('unknown component_id:%s' % component_id) continue isPrerelease = 1 if instance.get('isPrerelease', False) else 0 isRelease = 0 if isPrerelease else 1 vs_root = _VSDetectUtil.process_path(installationPath) if vs_root in vs_rel.msvs_roots: continue vs_rel.msvs_roots.add(vs_root) msvs_base = MSVSBase._factory( title = vs_cfg.vs_title, root_dir = vs_root, root_version = installationVersion, vc_release = isRelease, vc_version = vs_cfg.vc_version, vc_runtime = vs_cfg.vc_runtime, vc_component_id = component_id, vc_component_rank = component_rank, ) msvs_instance = MSVSInstance._factory( msvs_base = msvs_base, vs_dir = vs_root, vs_version = installationVersion, vs_executable = _VSDetectUtil.vs_executable(vs_root, vs_cfg.vs_executable), vs_script = _VSDetectUtil.vs_batchfile(vs_root, [vs_cfg.vs_batchfile]), vs_script_errs = vs_cfg.vs_script_errs, vs_environ_vars = vs_cfg.vs_environ_vars, vs_preserve_vars = vs_cfg.vs_preserve_vars, ) msvs_instances.append(msvs_instance) msvs_instances = sorted(msvs_instances, key=cmp_to_key(MSVSInstance._default_order)) return msvs_instances