You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

573 lines
22 KiB

6 years ago
  1. #
  2. # Copyright (c) 2001 - 2017 The SCons Foundation
  3. #
  4. # Permission is hereby granted, free of charge, to any person obtaining
  5. # a copy of this software and associated documentation files (the
  6. # "Software"), to deal in the Software without restriction, including
  7. # without limitation the rights to use, copy, modify, merge, publish,
  8. # distribute, sublicense, and/or sell copies of the Software, and to
  9. # permit persons to whom the Software is furnished to do so, subject to
  10. # the following conditions:
  11. #
  12. # The above copyright notice and this permission notice shall be included
  13. # in all copies or substantial portions of the Software.
  14. #
  15. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
  16. # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  17. # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  18. # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  19. # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  20. # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  21. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22. #
  23. # TODO:
  24. # * supported arch for versions: for old versions of batch file without
  25. # argument, giving bogus argument cannot be detected, so we have to hardcode
  26. # this here
  27. # * print warning when msvc version specified but not found
  28. # * find out why warning do not print
  29. # * test on 64 bits XP + VS 2005 (and VS 6 if possible)
  30. # * SDK
  31. # * Assembly
  32. __revision__ = "src/engine/SCons/Tool/MSCommon/vc.py rel_3.0.0:4395:8972f6a2f699 2017/09/18 12:59:24 bdbaddog"
  33. __doc__ = """Module for Visual C/C++ detection and configuration.
  34. """
  35. import SCons.compat
  36. import SCons.Util
  37. import subprocess
  38. import os
  39. import platform
  40. from string import digits as string_digits
  41. import SCons.Warnings
  42. from . import common
  43. debug = common.debug
  44. from . import sdk
  45. get_installed_sdks = sdk.get_installed_sdks
  46. class VisualCException(Exception):
  47. pass
  48. class UnsupportedVersion(VisualCException):
  49. pass
  50. class UnsupportedArch(VisualCException):
  51. pass
  52. class MissingConfiguration(VisualCException):
  53. pass
  54. class NoVersionFound(VisualCException):
  55. pass
  56. class BatchFileExecutionError(VisualCException):
  57. pass
  58. # Dict to 'canonalize' the arch
  59. _ARCH_TO_CANONICAL = {
  60. "amd64" : "amd64",
  61. "emt64" : "amd64",
  62. "i386" : "x86",
  63. "i486" : "x86",
  64. "i586" : "x86",
  65. "i686" : "x86",
  66. "ia64" : "ia64",
  67. "itanium" : "ia64",
  68. "x86" : "x86",
  69. "x86_64" : "amd64",
  70. "x86_amd64" : "x86_amd64", # Cross compile to 64 bit from 32bits
  71. }
  72. # Given a (host, target) tuple, return the argument for the bat file. Both host
  73. # and targets should be canonalized.
  74. _HOST_TARGET_ARCH_TO_BAT_ARCH = {
  75. ("x86", "x86"): "x86",
  76. ("x86", "amd64"): "x86_amd64",
  77. ("x86", "x86_amd64"): "x86_amd64",
  78. ("amd64", "x86_amd64"): "x86_amd64", # This is present in (at least) VS2012 express
  79. ("amd64", "amd64"): "amd64",
  80. ("amd64", "x86"): "x86",
  81. ("x86", "ia64"): "x86_ia64"
  82. }
  83. def get_host_target(env):
  84. debug('vc.py:get_host_target()')
  85. host_platform = env.get('HOST_ARCH')
  86. if not host_platform:
  87. host_platform = platform.machine()
  88. # TODO(2.5): the native Python platform.machine() function returns
  89. # '' on all Python versions before 2.6, after which it also uses
  90. # PROCESSOR_ARCHITECTURE.
  91. if not host_platform:
  92. host_platform = os.environ.get('PROCESSOR_ARCHITECTURE', '')
  93. # Retain user requested TARGET_ARCH
  94. req_target_platform = env.get('TARGET_ARCH')
  95. debug('vc.py:get_host_target() req_target_platform:%s'%req_target_platform)
  96. if req_target_platform:
  97. # If user requested a specific platform then only try that one.
  98. target_platform = req_target_platform
  99. else:
  100. target_platform = host_platform
  101. try:
  102. host = _ARCH_TO_CANONICAL[host_platform.lower()]
  103. except KeyError as e:
  104. msg = "Unrecognized host architecture %s"
  105. raise ValueError(msg % repr(host_platform))
  106. try:
  107. target = _ARCH_TO_CANONICAL[target_platform.lower()]
  108. except KeyError as e:
  109. all_archs = str(list(_ARCH_TO_CANONICAL.keys()))
  110. raise ValueError("Unrecognized target architecture %s\n\tValid architectures: %s" % (target_platform, all_archs))
  111. return (host, target,req_target_platform)
  112. # If you update this, update SupportedVSList in Tool/MSCommon/vs.py, and the
  113. # MSVC_VERSION documentation in Tool/msvc.xml.
  114. _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"]
  115. _VCVER_TO_PRODUCT_DIR = {
  116. '14.1' : [
  117. (SCons.Util.HKEY_LOCAL_MACHINE, r'')], # Visual Studio 2017 doesn't set this registry key anymore
  118. '14.0' : [
  119. (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VisualStudio\14.0\Setup\VC\ProductDir')],
  120. '14.0Exp' : [
  121. (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VCExpress\14.0\Setup\VC\ProductDir')],
  122. '12.0' : [
  123. (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VisualStudio\12.0\Setup\VC\ProductDir'),
  124. ],
  125. '12.0Exp' : [
  126. (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VCExpress\12.0\Setup\VC\ProductDir'),
  127. ],
  128. '11.0': [
  129. (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VisualStudio\11.0\Setup\VC\ProductDir'),
  130. ],
  131. '11.0Exp' : [
  132. (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VCExpress\11.0\Setup\VC\ProductDir'),
  133. ],
  134. '10.0': [
  135. (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VisualStudio\10.0\Setup\VC\ProductDir'),
  136. ],
  137. '10.0Exp' : [
  138. (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VCExpress\10.0\Setup\VC\ProductDir'),
  139. ],
  140. '9.0': [
  141. (SCons.Util.HKEY_CURRENT_USER, r'Microsoft\DevDiv\VCForPython\9.0\installdir',),
  142. (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VisualStudio\9.0\Setup\VC\ProductDir',),
  143. ],
  144. '9.0Exp' : [
  145. (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VCExpress\9.0\Setup\VC\ProductDir'),
  146. ],
  147. '8.0': [
  148. (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VisualStudio\8.0\Setup\VC\ProductDir'),
  149. ],
  150. '8.0Exp': [
  151. (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VCExpress\8.0\Setup\VC\ProductDir'),
  152. ],
  153. '7.1': [
  154. (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VisualStudio\7.1\Setup\VC\ProductDir'),
  155. ],
  156. '7.0': [
  157. (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VisualStudio\7.0\Setup\VC\ProductDir'),
  158. ],
  159. '6.0': [
  160. (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VisualStudio\6.0\Setup\Microsoft Visual C++\ProductDir'),
  161. ]
  162. }
  163. def msvc_version_to_maj_min(msvc_version):
  164. msvc_version_numeric = ''.join([x for x in msvc_version if x in string_digits + '.'])
  165. t = msvc_version_numeric.split(".")
  166. if not len(t) == 2:
  167. raise ValueError("Unrecognized version %s (%s)" % (msvc_version,msvc_version_numeric))
  168. try:
  169. maj = int(t[0])
  170. min = int(t[1])
  171. return maj, min
  172. except ValueError as e:
  173. raise ValueError("Unrecognized version %s (%s)" % (msvc_version,msvc_version_numeric))
  174. def is_host_target_supported(host_target, msvc_version):
  175. """Return True if the given (host, target) tuple is supported given the
  176. msvc version.
  177. Parameters
  178. ----------
  179. host_target: tuple
  180. tuple of (canonalized) host-target, e.g. ("x86", "amd64") for cross
  181. compilation from 32 bits windows to 64 bits.
  182. msvc_version: str
  183. msvc version (major.minor, e.g. 10.0)
  184. Note
  185. ----
  186. This only check whether a given version *may* support the given (host,
  187. target), not that the toolchain is actually present on the machine.
  188. """
  189. # We assume that any Visual Studio version supports x86 as a target
  190. if host_target[1] != "x86":
  191. maj, min = msvc_version_to_maj_min(msvc_version)
  192. if maj < 8:
  193. return False
  194. return True
  195. def find_vc_pdir_vswhere(msvc_version):
  196. """
  197. Find the MSVC product directory using vswhere.exe .
  198. Run it asking for specified version and get MSVS install location
  199. :param msvc_version:
  200. :return: MSVC install dir
  201. """
  202. vswhere_path = os.path.join(
  203. 'C:\\',
  204. 'Program Files (x86)',
  205. 'Microsoft Visual Studio',
  206. 'Installer',
  207. 'vswhere.exe'
  208. )
  209. vswhere_cmd = [vswhere_path, '-version', msvc_version, '-property', 'installationPath']
  210. if os.path.exists(vswhere_path):
  211. sp = subprocess.Popen(vswhere_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  212. vsdir, err = sp.communicate()
  213. vsdir = vsdir.decode("mbcs")
  214. vsdir = vsdir.rstrip()
  215. vc_pdir = os.path.join(vsdir, 'VC')
  216. return vc_pdir
  217. else:
  218. # No vswhere on system, no install info available
  219. return None
  220. def find_vc_pdir(msvc_version):
  221. """Try to find the product directory for the given
  222. version.
  223. Note
  224. ----
  225. If for some reason the requested version could not be found, an
  226. exception which inherits from VisualCException will be raised."""
  227. root = 'Software\\'
  228. try:
  229. hkeys = _VCVER_TO_PRODUCT_DIR[msvc_version]
  230. except KeyError:
  231. debug("Unknown version of MSVC: %s" % msvc_version)
  232. raise UnsupportedVersion("Unknown version %s" % msvc_version)
  233. for hkroot, key in hkeys:
  234. try:
  235. comps = None
  236. if not key:
  237. comps = find_vc_pdir_vswhere(msvc_version)
  238. if not comps:
  239. debug('find_vc_dir(): no VC found via vswhere for version {}'.format(repr(key)))
  240. raise SCons.Util.WinError
  241. else:
  242. if common.is_win64():
  243. try:
  244. # ordinally at win64, try Wow6432Node first.
  245. comps = common.read_reg(root + 'Wow6432Node\\' + key, hkroot)
  246. except SCons.Util.WinError as e:
  247. # at Microsoft Visual Studio for Python 2.7, value is not in Wow6432Node
  248. pass
  249. if not comps:
  250. # not Win64, or Microsoft Visual Studio for Python 2.7
  251. comps = common.read_reg(root + key, hkroot)
  252. except SCons.Util.WinError as e:
  253. debug('find_vc_dir(): no VC registry key {}'.format(repr(key)))
  254. else:
  255. debug('find_vc_dir(): found VC in registry: {}'.format(comps))
  256. if os.path.exists(comps):
  257. return comps
  258. else:
  259. debug('find_vc_dir(): reg says dir is {}, but it does not exist. (ignoring)'.format(comps))
  260. raise MissingConfiguration("registry dir {} not found on the filesystem".format(comps))
  261. return None
  262. def find_batch_file(env,msvc_version,host_arch,target_arch):
  263. """
  264. Find the location of the batch script which should set up the compiler
  265. for any TARGET_ARCH whose compilers were installed by Visual Studio/VCExpress
  266. """
  267. pdir = find_vc_pdir(msvc_version)
  268. if pdir is None:
  269. raise NoVersionFound("No version of Visual Studio found")
  270. debug('vc.py: find_batch_file() pdir:{}'.format(pdir))
  271. # filter out e.g. "Exp" from the version name
  272. msvc_ver_numeric = ''.join([x for x in msvc_version if x in string_digits + "."])
  273. vernum = float(msvc_ver_numeric)
  274. if 7 <= vernum < 8:
  275. pdir = os.path.join(pdir, os.pardir, "Common7", "Tools")
  276. batfilename = os.path.join(pdir, "vsvars32.bat")
  277. elif vernum < 7:
  278. pdir = os.path.join(pdir, "Bin")
  279. batfilename = os.path.join(pdir, "vcvars32.bat")
  280. elif 8 <= vernum <= 14:
  281. batfilename = os.path.join(pdir, "vcvarsall.bat")
  282. else: # vernum >= 14.1 VS2017 and above
  283. batfilename = os.path.join(pdir, "Auxiliary", "Build", "vcvarsall.bat")
  284. if not os.path.exists(batfilename):
  285. debug("Not found: %s" % batfilename)
  286. batfilename = None
  287. installed_sdks=get_installed_sdks()
  288. for _sdk in installed_sdks:
  289. sdk_bat_file = _sdk.get_sdk_vc_script(host_arch,target_arch)
  290. if not sdk_bat_file:
  291. debug("vc.py:find_batch_file() not found:%s"%_sdk)
  292. else:
  293. sdk_bat_file_path = os.path.join(pdir,sdk_bat_file)
  294. if os.path.exists(sdk_bat_file_path):
  295. debug('vc.py:find_batch_file() sdk_bat_file_path:%s'%sdk_bat_file_path)
  296. return (batfilename,sdk_bat_file_path)
  297. return (batfilename,None)
  298. __INSTALLED_VCS_RUN = None
  299. def cached_get_installed_vcs():
  300. global __INSTALLED_VCS_RUN
  301. if __INSTALLED_VCS_RUN is None:
  302. ret = get_installed_vcs()
  303. __INSTALLED_VCS_RUN = ret
  304. return __INSTALLED_VCS_RUN
  305. def get_installed_vcs():
  306. installed_versions = []
  307. for ver in _VCVER:
  308. debug('trying to find VC %s' % ver)
  309. try:
  310. if find_vc_pdir(ver):
  311. debug('found VC %s' % ver)
  312. installed_versions.append(ver)
  313. else:
  314. debug('find_vc_pdir return None for ver %s' % ver)
  315. except VisualCException as e:
  316. debug('did not find VC %s: caught exception %s' % (ver, str(e)))
  317. return installed_versions
  318. def reset_installed_vcs():
  319. """Make it try again to find VC. This is just for the tests."""
  320. __INSTALLED_VCS_RUN = None
  321. # Running these batch files isn't cheap: most of the time spent in
  322. # msvs.generate() is due to vcvars*.bat. In a build that uses "tools='msvs'"
  323. # in multiple environments, for example:
  324. # env1 = Environment(tools='msvs')
  325. # env2 = Environment(tools='msvs')
  326. # we can greatly improve the speed of the second and subsequent Environment
  327. # (or Clone) calls by memoizing the environment variables set by vcvars*.bat.
  328. script_env_stdout_cache = {}
  329. def script_env(script, args=None):
  330. cache_key = (script, args)
  331. stdout = script_env_stdout_cache.get(cache_key, None)
  332. if stdout is None:
  333. stdout = common.get_output(script, args)
  334. script_env_stdout_cache[cache_key] = stdout
  335. # Stupid batch files do not set return code: we take a look at the
  336. # beginning of the output for an error message instead
  337. olines = stdout.splitlines()
  338. if olines[0].startswith("The specified configuration type is missing"):
  339. raise BatchFileExecutionError("\n".join(olines[:2]))
  340. return common.parse_output(stdout)
  341. def get_default_version(env):
  342. debug('get_default_version()')
  343. msvc_version = env.get('MSVC_VERSION')
  344. msvs_version = env.get('MSVS_VERSION')
  345. debug('get_default_version(): msvc_version:%s msvs_version:%s'%(msvc_version,msvs_version))
  346. if msvs_version and not msvc_version:
  347. SCons.Warnings.warn(
  348. SCons.Warnings.DeprecatedWarning,
  349. "MSVS_VERSION is deprecated: please use MSVC_VERSION instead ")
  350. return msvs_version
  351. elif msvc_version and msvs_version:
  352. if not msvc_version == msvs_version:
  353. SCons.Warnings.warn(
  354. SCons.Warnings.VisualVersionMismatch,
  355. "Requested msvc version (%s) and msvs version (%s) do " \
  356. "not match: please use MSVC_VERSION only to request a " \
  357. "visual studio version, MSVS_VERSION is deprecated" \
  358. % (msvc_version, msvs_version))
  359. return msvs_version
  360. if not msvc_version:
  361. installed_vcs = cached_get_installed_vcs()
  362. debug('installed_vcs:%s' % installed_vcs)
  363. if not installed_vcs:
  364. #msg = 'No installed VCs'
  365. #debug('msv %s\n' % repr(msg))
  366. #SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, msg)
  367. debug('msvc_setup_env: No installed VCs')
  368. return None
  369. msvc_version = installed_vcs[0]
  370. debug('msvc_setup_env: using default installed MSVC version %s\n' % repr(msvc_version))
  371. return msvc_version
  372. def msvc_setup_env_once(env):
  373. try:
  374. has_run = env["MSVC_SETUP_RUN"]
  375. except KeyError:
  376. has_run = False
  377. if not has_run:
  378. msvc_setup_env(env)
  379. env["MSVC_SETUP_RUN"] = True
  380. def msvc_find_valid_batch_script(env,version):
  381. debug('vc.py:msvc_find_valid_batch_script()')
  382. # Find the host platform, target platform, and if present the requested
  383. # target platform
  384. (host_platform, target_platform,req_target_platform) = get_host_target(env)
  385. try_target_archs = [target_platform]
  386. debug("msvs_find_valid_batch_script(): req_target_platform %s target_platform:%s"%(req_target_platform,target_platform))
  387. # VS2012 has a "cross compile" environment to build 64 bit
  388. # with x86_amd64 as the argument to the batch setup script
  389. if req_target_platform in ('amd64','x86_64'):
  390. try_target_archs.append('x86_amd64')
  391. elif not req_target_platform and target_platform in ['amd64','x86_64']:
  392. # There may not be "native" amd64, but maybe "cross" x86_amd64 tools
  393. try_target_archs.append('x86_amd64')
  394. # If the user hasn't specifically requested a TARGET_ARCH, and
  395. # The TARGET_ARCH is amd64 then also try 32 bits if there are no viable
  396. # 64 bit tools installed
  397. try_target_archs.append('x86')
  398. debug("msvs_find_valid_batch_script(): host_platform: %s try_target_archs:%s"%(host_platform, try_target_archs))
  399. d = None
  400. for tp in try_target_archs:
  401. # Set to current arch.
  402. env['TARGET_ARCH']=tp
  403. debug("vc.py:msvc_find_valid_batch_script() trying target_platform:%s"%tp)
  404. host_target = (host_platform, tp)
  405. if not is_host_target_supported(host_target, version):
  406. warn_msg = "host, target = %s not supported for MSVC version %s" % \
  407. (host_target, version)
  408. SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, warn_msg)
  409. arg = _HOST_TARGET_ARCH_TO_BAT_ARCH[host_target]
  410. # Get just version numbers
  411. maj, min = msvc_version_to_maj_min(version)
  412. # VS2015+
  413. if maj >= 14:
  414. if env.get('MSVC_UWP_APP') == '1':
  415. # Initialize environment variables with store/universal paths
  416. arg += ' store'
  417. # Try to locate a batch file for this host/target platform combo
  418. try:
  419. (vc_script,sdk_script) = find_batch_file(env,version,host_platform,tp)
  420. debug('vc.py:msvc_find_valid_batch_script() vc_script:%s sdk_script:%s'%(vc_script,sdk_script))
  421. except VisualCException as e:
  422. msg = str(e)
  423. debug('Caught exception while looking for batch file (%s)' % msg)
  424. warn_msg = "VC version %s not installed. " + \
  425. "C/C++ compilers are most likely not set correctly.\n" + \
  426. " Installed versions are: %s"
  427. warn_msg = warn_msg % (version, cached_get_installed_vcs())
  428. SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, warn_msg)
  429. continue
  430. # Try to use the located batch file for this host/target platform combo
  431. debug('vc.py:msvc_find_valid_batch_script() use_script 2 %s, args:%s\n' % (repr(vc_script), arg))
  432. if vc_script:
  433. try:
  434. d = script_env(vc_script, args=arg)
  435. except BatchFileExecutionError as e:
  436. debug('vc.py:msvc_find_valid_batch_script() use_script 3: failed running VC script %s: %s: Error:%s'%(repr(vc_script),arg,e))
  437. vc_script=None
  438. continue
  439. if not vc_script and sdk_script:
  440. debug('vc.py:msvc_find_valid_batch_script() use_script 4: trying sdk script: %s'%(sdk_script))
  441. try:
  442. d = script_env(sdk_script)
  443. except BatchFileExecutionError as e:
  444. debug('vc.py:msvc_find_valid_batch_script() use_script 5: failed running SDK script %s: Error:%s'%(repr(sdk_script),e))
  445. continue
  446. elif not vc_script and not sdk_script:
  447. debug('vc.py:msvc_find_valid_batch_script() use_script 6: Neither VC script nor SDK script found')
  448. continue
  449. debug("vc.py:msvc_find_valid_batch_script() Found a working script/target: %s %s"%(repr(sdk_script),arg))
  450. break # We've found a working target_platform, so stop looking
  451. # If we cannot find a viable installed compiler, reset the TARGET_ARCH
  452. # To it's initial value
  453. if not d:
  454. env['TARGET_ARCH']=req_target_platform
  455. return d
  456. def msvc_setup_env(env):
  457. debug('msvc_setup_env()')
  458. version = get_default_version(env)
  459. if version is None:
  460. warn_msg = "No version of Visual Studio compiler found - C/C++ " \
  461. "compilers most likely not set correctly"
  462. SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, warn_msg)
  463. return None
  464. debug('msvc_setup_env: using specified MSVC version %s\n' % repr(version))
  465. # XXX: we set-up both MSVS version for backward
  466. # compatibility with the msvs tool
  467. env['MSVC_VERSION'] = version
  468. env['MSVS_VERSION'] = version
  469. env['MSVS'] = {}
  470. use_script = env.get('MSVC_USE_SCRIPT', True)
  471. if SCons.Util.is_String(use_script):
  472. debug('vc.py:msvc_setup_env() use_script 1 %s\n' % repr(use_script))
  473. d = script_env(use_script)
  474. elif use_script:
  475. d = msvc_find_valid_batch_script(env,version)
  476. debug('vc.py:msvc_setup_env() use_script 2 %s\n' % d)
  477. if not d:
  478. return d
  479. else:
  480. debug('MSVC_USE_SCRIPT set to False')
  481. warn_msg = "MSVC_USE_SCRIPT set to False, assuming environment " \
  482. "set correctly."
  483. SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, warn_msg)
  484. return None
  485. for k, v in d.items():
  486. debug('vc.py:msvc_setup_env() env:%s -> %s'%(k,v))
  487. env.PrependENVPath(k, v, delete_existing=True)
  488. def msvc_exists(version=None):
  489. vcs = cached_get_installed_vcs()
  490. if version is None:
  491. return len(vcs) > 0
  492. return version in vcs