vs.py (SCons-4.3.0) | : | vs.py (SCons-4.4.0) | ||
---|---|---|---|---|
# MIT License | ||||
# | # | |||
# __COPYRIGHT__ | # Copyright The SCons Foundation | |||
# | # | |||
# Permission is hereby granted, free of charge, to any person obtaining | # Permission is hereby granted, free of charge, to any person obtaining | |||
# a copy of this software and associated documentation files (the | # a copy of this software and associated documentation files (the | |||
# "Software"), to deal in the Software without restriction, including | # "Software"), to deal in the Software without restriction, including | |||
# without limitation the rights to use, copy, modify, merge, publish, | # without limitation the rights to use, copy, modify, merge, publish, | |||
# distribute, sublicense, and/or sell copies of the Software, and to | # distribute, sublicense, and/or sell copies of the Software, and to | |||
# permit persons to whom the Software is furnished to do so, subject to | # permit persons to whom the Software is furnished to do so, subject to | |||
# the following conditions: | # the following conditions: | |||
# | # | |||
# The above copyright notice and this permission notice shall be included | # The above copyright notice and this permission notice shall be included | |||
# in all copies or substantial portions of the Software. | # in all copies or substantial portions of the Software. | |||
# | # | |||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY | |||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | |||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | |||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | |||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | |||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
# | ||||
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" | ||||
__doc__ = """Module to detect Visual Studio and/or Visual C/C++ | """ | |||
MS Compilers: detect Visual Studio and/or Visual C/C++ | ||||
""" | """ | |||
import os | import os | |||
import SCons.Errors | import SCons.Errors | |||
import SCons.Tool.MSCommon.vc | ||||
import SCons.Util | import SCons.Util | |||
from .common import debug, \ | from .common import ( | |||
get_output, \ | debug, | |||
is_win64, \ | get_output, | |||
normalize_env, \ | is_win64, | |||
parse_output, \ | normalize_env, | |||
read_reg | parse_output, | |||
read_reg, | ||||
import SCons.Tool.MSCommon.vc | ) | |||
class VisualStudio: | class VisualStudio: | |||
""" | """ | |||
An abstract base class for trying to find installed versions of | An abstract base class for trying to find installed versions of | |||
Visual Studio. | Visual Studio. | |||
""" | """ | |||
def __init__(self, version, **kw): | def __init__(self, version, **kw): | |||
self.version = version | self.version = version | |||
kw['vc_version'] = kw.get('vc_version', version) | kw['vc_version'] = kw.get('vc_version', version) | |||
kw['sdk_version'] = kw.get('sdk_version', version) | kw['sdk_version'] = kw.get('sdk_version', version) | |||
skipping to change at line 63 | skipping to change at line 63 | |||
self._cache = {} | self._cache = {} | |||
def find_batch_file(self): | def find_batch_file(self): | |||
vs_dir = self.get_vs_dir() | vs_dir = self.get_vs_dir() | |||
if not vs_dir: | if not vs_dir: | |||
debug('no vs_dir') | debug('no vs_dir') | |||
return None | return None | |||
batch_file = os.path.join(vs_dir, self.batch_file_path) | batch_file = os.path.join(vs_dir, self.batch_file_path) | |||
batch_file = os.path.normpath(batch_file) | batch_file = os.path.normpath(batch_file) | |||
if not os.path.isfile(batch_file): | if not os.path.isfile(batch_file): | |||
debug('%s not on file system' % batch_file) | debug('%s not on file system', batch_file) | |||
return None | return None | |||
return batch_file | return batch_file | |||
def find_vs_dir_by_vc(self, env): | def find_vs_dir_by_vc(self, env): | |||
dir = SCons.Tool.MSCommon.vc.find_vc_pdir(env, self.vc_version) | dir = SCons.Tool.MSCommon.vc.find_vc_pdir(env, self.vc_version) | |||
if not dir: | if not dir: | |||
debug('no installed VC %s' % self.vc_version) | debug('no installed VC %s', self.vc_version) | |||
return None | return None | |||
return os.path.abspath(os.path.join(dir, os.pardir)) | return os.path.abspath(os.path.join(dir, os.pardir)) | |||
def find_vs_dir_by_reg(self, env): | def find_vs_dir_by_reg(self, env): | |||
root = 'Software\\' | root = 'Software\\' | |||
if is_win64(): | if is_win64(): | |||
root = root + 'Wow6432Node\\' | root = root + 'Wow6432Node\\' | |||
for key in self.hkeys: | for key in self.hkeys: | |||
if key=='use_dir': | if key=='use_dir': | |||
return self.find_vs_dir_by_vc(env) | return self.find_vs_dir_by_vc(env) | |||
key = root + key | key = root + key | |||
try: | try: | |||
comps = read_reg(key) | comps = read_reg(key) | |||
except OSError: | except OSError: | |||
debug('no VS registry key {}'.format(repr(key))) | debug('no VS registry key %s', repr(key)) | |||
else: | else: | |||
debug('found VS in registry: {}'.format(comps)) | debug('found VS in registry: %s', comps) | |||
return comps | return comps | |||
return None | return None | |||
def find_vs_dir(self, env): | def find_vs_dir(self, env): | |||
""" Can use registry or location of VC to find vs dir | """ Can use registry or location of VC to find vs dir | |||
First try to find by registry, and if that fails find via VC dir | First try to find by registry, and if that fails find via VC dir | |||
""" | """ | |||
vs_dir=self.find_vs_dir_by_reg(env) | vs_dir = self.find_vs_dir_by_reg(env) | |||
if not vs_dir: | if not vs_dir: | |||
vs_dir = self.find_vs_dir_by_vc(env) | vs_dir = self.find_vs_dir_by_vc(env) | |||
debug('found VS in ' + str(vs_dir )) | debug('found VS in %s', str(vs_dir)) | |||
return vs_dir | return vs_dir | |||
def find_executable(self, env): | def find_executable(self, env): | |||
vs_dir = self.get_vs_dir(env) | vs_dir = self.get_vs_dir(env) | |||
if not vs_dir: | if not vs_dir: | |||
debug('no vs_dir ({})'.format(vs_dir)) | debug('no vs_dir (%s)', vs_dir) | |||
return None | return None | |||
executable = os.path.join(vs_dir, self.executable_path) | executable = os.path.join(vs_dir, self.executable_path) | |||
executable = os.path.normpath(executable) | executable = os.path.normpath(executable) | |||
if not os.path.isfile(executable): | if not os.path.isfile(executable): | |||
debug('{} not on file system'.format(executable)) | debug('%s not on file system', executable) | |||
return None | return None | |||
return executable | return executable | |||
def get_batch_file(self): | def get_batch_file(self): | |||
try: | try: | |||
return self._cache['batch_file'] | return self._cache['batch_file'] | |||
except KeyError: | except KeyError: | |||
batch_file = self.find_batch_file() | batch_file = self.find_batch_file() | |||
self._cache['batch_file'] = batch_file | self._cache['batch_file'] = batch_file | |||
return batch_file | return batch_file | |||
def get_executable(self, env=None): | def get_executable(self, env=None): | |||
try: | try: | |||
debug('using cache:%s'%self._cache['executable']) | debug('using cache:%s', self._cache['executable']) | |||
return self._cache['executable'] | return self._cache['executable'] | |||
except KeyError: | except KeyError: | |||
executable = self.find_executable(env) | executable = self.find_executable(env) | |||
self._cache['executable'] = executable | self._cache['executable'] = executable | |||
debug('not in cache:%s'%executable) | debug('not in cache:%s', executable) | |||
return executable | return executable | |||
def get_vs_dir(self, env): | def get_vs_dir(self, env=None): | |||
try: | try: | |||
return self._cache['vs_dir'] | return self._cache['vs_dir'] | |||
except KeyError: | except KeyError: | |||
vs_dir = self.find_vs_dir(env) | vs_dir = self.find_vs_dir(env) | |||
self._cache['vs_dir'] = vs_dir | self._cache['vs_dir'] = vs_dir | |||
return vs_dir | return vs_dir | |||
def get_supported_arch(self): | def get_supported_arch(self): | |||
try: | try: | |||
return self._cache['supported_arch'] | return self._cache['supported_arch'] | |||
skipping to change at line 393 | skipping to change at line 393 | |||
executable_path=r'Common7\IDE\devenv.com', | executable_path=r'Common7\IDE\devenv.com', | |||
batch_file_path=r'Common7\Tools\vsvars32.bat', | batch_file_path=r'Common7\Tools\vsvars32.bat', | |||
default_dirname='Microsoft Visual Studio .NET 2003', | default_dirname='Microsoft Visual Studio .NET 2003', | |||
supported_arch=['x86'], | supported_arch=['x86'], | |||
), | ), | |||
# Visual Studio .NET | # Visual Studio .NET | |||
VisualStudio('7.0', | VisualStudio('7.0', | |||
sdk_version='2003R2', | sdk_version='2003R2', | |||
hkeys=[r'Microsoft\VisualStudio\7.0\Setup\VS\ProductDir'], | hkeys=[r'Microsoft\VisualStudio\7.0\Setup\VS\ProductDir'], | |||
common_tools_var='VS70COMNTOOLS', | common_tools_var='VSCOMNTOOLS', | |||
executable_path=r'Common7\IDE\devenv.com', | executable_path=r'Common7\IDE\devenv.com', | |||
batch_file_path=r'Common7\Tools\vsvars32.bat', | batch_file_path=r'Common7\Tools\vsvars32.bat', | |||
default_dirname='Microsoft Visual Studio .NET', | default_dirname='Microsoft Visual Studio .NET', | |||
supported_arch=['x86'], | supported_arch=['x86'], | |||
), | ), | |||
# Visual Studio 6.0 | # Visual Studio 6.0 | |||
VisualStudio('6.0', | VisualStudio('6.0', | |||
sdk_version='2003R1', | sdk_version='2003R1', | |||
hkeys=[r'Microsoft\VisualStudio\6.0\Setup\Microsoft Visual Stud io\ProductDir', | hkeys=[r'Microsoft\VisualStudio\6.0\Setup\Microsoft Visual Stud io\ProductDir', | |||
'use_dir'], | 'use_dir'], | |||
common_tools_var='VS60COMNTOOLS', | common_tools_var='MSDevDir', | |||
executable_path=r'Common\MSDev98\Bin\MSDEV.COM', | executable_path=r'Common\MSDev98\Bin\MSDEV.COM', | |||
batch_file_path=r'Common7\Tools\vsvars32.bat', | batch_file_path=r'Common7\Tools\vsvars32.bat', | |||
default_dirname='Microsoft Visual Studio', | default_dirname='Microsoft Visual Studio', | |||
supported_arch=['x86'], | supported_arch=['x86'], | |||
), | ), | |||
] | ] | |||
SupportedVSMap = {} | SupportedVSMap = {} | |||
for vs in SupportedVSList: | for vs in SupportedVSList: | |||
SupportedVSMap[vs.version] = vs | SupportedVSMap[vs.version] = vs | |||
skipping to change at line 433 | skipping to change at line 433 | |||
InstalledVSList = None | InstalledVSList = None | |||
InstalledVSMap = None | InstalledVSMap = None | |||
def get_installed_visual_studios(env=None): | def get_installed_visual_studios(env=None): | |||
global InstalledVSList | global InstalledVSList | |||
global InstalledVSMap | global InstalledVSMap | |||
if InstalledVSList is None: | if InstalledVSList is None: | |||
InstalledVSList = [] | InstalledVSList = [] | |||
InstalledVSMap = {} | InstalledVSMap = {} | |||
for vs in SupportedVSList: | for vs in SupportedVSList: | |||
debug('trying to find VS %s' % vs.version) | debug('trying to find VS %s', vs.version) | |||
if vs.get_executable(env): | if vs.get_executable(env): | |||
debug('found VS %s' % vs.version) | debug('found VS %s', vs.version) | |||
InstalledVSList.append(vs) | InstalledVSList.append(vs) | |||
InstalledVSMap[vs.version] = vs | InstalledVSMap[vs.version] = vs | |||
return InstalledVSList | return InstalledVSList | |||
def reset_installed_visual_studios(): | def reset_installed_visual_studios(): | |||
global InstalledVSList | global InstalledVSList | |||
global InstalledVSMap | global InstalledVSMap | |||
InstalledVSList = None | InstalledVSList = None | |||
InstalledVSMap = None | InstalledVSMap = None | |||
for vs in SupportedVSList: | for vs in SupportedVSList: | |||
skipping to change at line 484 | skipping to change at line 484 | |||
# env_tuple_list.append(('INCLUDE', atl_path)) | # env_tuple_list.append(('INCLUDE', atl_path)) | |||
# env_tuple_list.append(('INCLUDE', include_path)) | # env_tuple_list.append(('INCLUDE', include_path)) | |||
# | # | |||
# env_tuple_list.append(('LIB', os.path.join(sdk_dir, 'lib'))) | # env_tuple_list.append(('LIB', os.path.join(sdk_dir, 'lib'))) | |||
# env_tuple_list.append(('LIBPATH', os.path.join(sdk_dir, 'lib'))) | # env_tuple_list.append(('LIBPATH', os.path.join(sdk_dir, 'lib'))) | |||
# env_tuple_list.append(('PATH', os.path.join(sdk_dir, 'bin'))) | # env_tuple_list.append(('PATH', os.path.join(sdk_dir, 'bin'))) | |||
# | # | |||
# for variable, directory in env_tuple_list: | # for variable, directory in env_tuple_list: | |||
# env.PrependENVPath(variable, directory) | # env.PrependENVPath(variable, directory) | |||
def msvs_exists(env=None): | def msvs_exists(env=None) -> bool: | |||
return (len(get_installed_visual_studios(env)) > 0) | return len(get_installed_visual_studios(env)) > 0 | |||
def get_vs_by_version(msvs): | def get_vs_by_version(msvs): | |||
global InstalledVSMap | global InstalledVSMap | |||
global SupportedVSMap | global SupportedVSMap | |||
debug('called') | debug('called') | |||
if msvs not in SupportedVSMap: | if msvs not in SupportedVSMap: | |||
msg = "Visual Studio version %s is not supported" % repr(msvs) | msg = "Visual Studio version %s is not supported" % repr(msvs) | |||
raise SCons.Errors.UserError(msg) | raise SCons.Errors.UserError(msg) | |||
get_installed_visual_studios() | get_installed_visual_studios() | |||
vs = InstalledVSMap.get(msvs) | vs = InstalledVSMap.get(msvs) | |||
debug('InstalledVSMap:%s' % InstalledVSMap) | debug('InstalledVSMap:%s', InstalledVSMap) | |||
debug('found vs:%s' % vs) | debug('found vs:%s', vs) | |||
# Some check like this would let us provide a useful error message | # Some check like this would let us provide a useful error message | |||
# if they try to set a Visual Studio version that's not installed. | # if they try to set a Visual Studio version that's not installed. | |||
# However, we also want to be able to run tests (like the unit | # However, we also want to be able to run tests (like the unit | |||
# tests) on systems that don't, or won't ever, have it installed. | # tests) on systems that don't, or won't ever, have it installed. | |||
# It might be worth resurrecting this, with some configurable | # It might be worth resurrecting this, with some configurable | |||
# setting that the tests can use to bypass the check. | # setting that the tests can use to bypass the check. | |||
#if not vs: | #if not vs: | |||
# msg = "Visual Studio version %s is not installed" % repr(msvs) | # msg = "Visual Studio version %s is not installed" % repr(msvs) | |||
# raise SCons.Errors.UserError, msg | # raise SCons.Errors.UserError, msg | |||
return vs | return vs | |||
skipping to change at line 534 | skipping to change at line 534 | |||
versions = [vs.version for vs in get_installed_visual_studios()] | versions = [vs.version for vs in get_installed_visual_studios()] | |||
env['MSVS'] = {'VERSIONS' : versions} | env['MSVS'] = {'VERSIONS' : versions} | |||
else: | else: | |||
versions = env['MSVS'].get('VERSIONS', []) | versions = env['MSVS'].get('VERSIONS', []) | |||
if 'MSVS_VERSION' not in env: | if 'MSVS_VERSION' not in env: | |||
if versions: | if versions: | |||
env['MSVS_VERSION'] = versions[0] #use highest version by default | env['MSVS_VERSION'] = versions[0] #use highest version by default | |||
else: | else: | |||
debug('WARNING: no installed versions found, ' | debug('WARNING: no installed versions found, ' | |||
'using first in SupportedVSList (%s)' % SupportedVSList[0].ver | 'using first in SupportedVSList (%s)', | |||
sion) | SupportedVSList[0].version) | |||
env['MSVS_VERSION'] = SupportedVSList[0].version | env['MSVS_VERSION'] = SupportedVSList[0].version | |||
env['MSVS']['VERSION'] = env['MSVS_VERSION'] | env['MSVS']['VERSION'] = env['MSVS_VERSION'] | |||
return env['MSVS_VERSION'] | return env['MSVS_VERSION'] | |||
def get_default_arch(env): | def get_default_arch(env): | |||
"""Return the default arch to use for MSVS | """Return the default arch to use for MSVS | |||
if no version was requested by the user through the MSVS_ARCH environment | if no version was requested by the user through the MSVS_ARCH environment | |||
skipping to change at line 567 | skipping to change at line 568 | |||
elif arch not in msvs.get_supported_arch(): | elif arch not in msvs.get_supported_arch(): | |||
fmt = "Visual Studio version %s does not support architecture %s" | fmt = "Visual Studio version %s does not support architecture %s" | |||
raise SCons.Errors.UserError(fmt % (env['MSVS_VERSION'], arch)) | raise SCons.Errors.UserError(fmt % (env['MSVS_VERSION'], arch)) | |||
return arch | return arch | |||
def merge_default_version(env): | def merge_default_version(env): | |||
version = get_default_version(env) | version = get_default_version(env) | |||
arch = get_default_arch(env) | arch = get_default_arch(env) | |||
# TODO: refers to versions and arch which aren't defined; called nowhere. Drop? | ||||
def msvs_setup_env(env): | def msvs_setup_env(env): | |||
batfilename = msvs.get_batch_file() | ||||
msvs = get_vs_by_version(version) | msvs = get_vs_by_version(version) | |||
if msvs is None: | if msvs is None: | |||
return | return | |||
batfilename = msvs.get_batch_file() | ||||
# XXX: I think this is broken. This will silently set a bogus tool instead | # XXX: I think this is broken. This will silently set a bogus tool instead | |||
# of failing, but there is no other way with the current scons tool | # of failing, but there is no other way with the current scons tool | |||
# framework | # framework | |||
if batfilename is not None: | if batfilename is not None: | |||
vars = ('LIB', 'LIBPATH', 'PATH', 'INCLUDE') | vars = ('LIB', 'LIBPATH', 'PATH', 'INCLUDE') | |||
msvs_list = get_installed_visual_studios() | msvs_list = get_installed_visual_studios() | |||
vscommonvarnames = [vs.common_tools_var for vs in msvs_list] | vscommonvarnames = [vs.common_tools_var for vs in msvs_list] | |||
End of changes. 27 change blocks. | ||||
35 lines changed or deleted | 36 lines changed or added |