PageRenderTime 80ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/couchjs/scons/scons-local-2.0.1/SCons/Tool/MSCommon/vs.py

http://github.com/cloudant/bigcouch
Python | 499 lines | 475 code | 2 blank | 22 comment | 0 complexity | 006bf46883a7a0e6ebaaca0aa7b26719 MD5 | raw file
Possible License(s): Apache-2.0
  1. #
  2. # Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 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. __revision__ = "src/engine/SCons/Tool/MSCommon/vs.py 5134 2010/08/16 23:02:40 bdeegan"
  24. __doc__ = """Module to detect Visual Studio and/or Visual C/C++
  25. """
  26. import os
  27. import SCons.Errors
  28. import SCons.Util
  29. from common import debug, \
  30. get_output, \
  31. is_win64, \
  32. normalize_env, \
  33. parse_output, \
  34. read_reg
  35. import SCons.Tool.MSCommon.vc
  36. class VisualStudio(object):
  37. """
  38. An abstract base class for trying to find installed versions of
  39. Visual Studio.
  40. """
  41. def __init__(self, version, **kw):
  42. self.version = version
  43. kw['vc_version'] = kw.get('vc_version', version)
  44. kw['sdk_version'] = kw.get('sdk_version', version)
  45. self.__dict__.update(kw)
  46. self._cache = {}
  47. #
  48. def find_batch_file(self):
  49. vs_dir = self.get_vs_dir()
  50. if not vs_dir:
  51. debug('find_executable(): no vs_dir')
  52. return None
  53. batch_file = os.path.join(vs_dir, self.batch_file_path)
  54. batch_file = os.path.normpath(batch_file)
  55. if not os.path.isfile(batch_file):
  56. debug('find_batch_file(): %s not on file system' % batch_file)
  57. return None
  58. return batch_file
  59. def find_vs_dir_by_vc(self):
  60. SCons.Tool.MSCommon.vc.get_installed_vcs()
  61. dir = SCons.Tool.MSCommon.vc.find_vc_pdir(self.vc_version)
  62. if not dir:
  63. debug('find_vs_dir(): no installed VC %s' % self.vc_version)
  64. return None
  65. return dir
  66. def find_vs_dir_by_reg(self):
  67. root = 'Software\\'
  68. if is_win64():
  69. root = root + 'Wow6432Node\\'
  70. for key in self.hkeys:
  71. if key=='use_dir':
  72. return self.find_vs_dir_by_vc()
  73. key = root + key
  74. try:
  75. comps = read_reg(key)
  76. except WindowsError, e:
  77. debug('find_vs_dir_by_reg(): no VS registry key %s' % repr(key))
  78. else:
  79. debug('find_vs_dir_by_reg(): found VS in registry: %s' % comps)
  80. return comps
  81. return None
  82. def find_vs_dir(self):
  83. """ Can use registry or location of VC to find vs dir
  84. First try to find by registry, and if that fails find via VC dir
  85. """
  86. if True:
  87. vs_dir=self.find_vs_dir_by_reg()
  88. return vs_dir
  89. else:
  90. return self.find_vs_dir_by_vc()
  91. def find_executable(self):
  92. vs_dir = self.get_vs_dir()
  93. if not vs_dir:
  94. debug('find_executable(): no vs_dir (%s)'%vs_dir)
  95. return None
  96. executable = os.path.join(vs_dir, self.executable_path)
  97. executable = os.path.normpath(executable)
  98. if not os.path.isfile(executable):
  99. debug('find_executable(): %s not on file system' % executable)
  100. return None
  101. return executable
  102. #
  103. def get_batch_file(self):
  104. try:
  105. return self._cache['batch_file']
  106. except KeyError:
  107. batch_file = self.find_batch_file()
  108. self._cache['batch_file'] = batch_file
  109. return batch_file
  110. def get_executable(self):
  111. try:
  112. debug('get_executable using cache:%s'%self._cache['executable'])
  113. return self._cache['executable']
  114. except KeyError:
  115. executable = self.find_executable()
  116. self._cache['executable'] = executable
  117. debug('get_executable not in cache:%s'%executable)
  118. return executable
  119. def get_vs_dir(self):
  120. try:
  121. return self._cache['vs_dir']
  122. except KeyError:
  123. vs_dir = self.find_vs_dir()
  124. self._cache['vs_dir'] = vs_dir
  125. return vs_dir
  126. def get_supported_arch(self):
  127. try:
  128. return self._cache['supported_arch']
  129. except KeyError:
  130. # RDEVE: for the time being use hardcoded lists
  131. # supported_arch = self.find_supported_arch()
  132. self._cache['supported_arch'] = self.supported_arch
  133. return self.supported_arch
  134. def reset(self):
  135. self._cache = {}
  136. # The list of supported Visual Studio versions we know how to detect.
  137. #
  138. # How to look for .bat file ?
  139. # - VS 2008 Express (x86):
  140. # * from registry key productdir, gives the full path to vsvarsall.bat. In
  141. # HKEY_LOCAL_MACHINE):
  142. # Software\Microsoft\VCEpress\9.0\Setup\VC\productdir
  143. # * from environmnent variable VS90COMNTOOLS: the path is then ..\..\VC
  144. # relatively to the path given by the variable.
  145. #
  146. # - VS 2008 Express (WoW6432: 32 bits on windows x64):
  147. # Software\Wow6432Node\Microsoft\VCEpress\9.0\Setup\VC\productdir
  148. #
  149. # - VS 2005 Express (x86):
  150. # * from registry key productdir, gives the full path to vsvarsall.bat. In
  151. # HKEY_LOCAL_MACHINE):
  152. # Software\Microsoft\VCEpress\8.0\Setup\VC\productdir
  153. # * from environmnent variable VS80COMNTOOLS: the path is then ..\..\VC
  154. # relatively to the path given by the variable.
  155. #
  156. # - VS 2005 Express (WoW6432: 32 bits on windows x64): does not seem to have a
  157. # productdir ?
  158. #
  159. # - VS 2003 .Net (pro edition ? x86):
  160. # * from registry key productdir. The path is then ..\Common7\Tools\
  161. # relatively to the key. The key is in HKEY_LOCAL_MACHINE):
  162. # Software\Microsoft\VisualStudio\7.1\Setup\VC\productdir
  163. # * from environmnent variable VS71COMNTOOLS: the path is the full path to
  164. # vsvars32.bat
  165. #
  166. # - VS 98 (VS 6):
  167. # * from registry key productdir. The path is then Bin
  168. # relatively to the key. The key is in HKEY_LOCAL_MACHINE):
  169. # Software\Microsoft\VisualStudio\6.0\Setup\VC98\productdir
  170. #
  171. # The first version found in the list is the one used by default if
  172. # there are multiple versions installed. Barring good reasons to
  173. # the contrary, this means we should list versions from most recent
  174. # to oldest. Pro versions get listed before Express versions on the
  175. # assumption that, by default, you'd rather use the version you paid
  176. # good money for in preference to whatever Microsoft makes available
  177. # for free.
  178. #
  179. # If you update this list, update the documentation in Tool/msvs.xml.
  180. SupportedVSList = [
  181. # Visual Studio 2010
  182. # TODO: find the settings, perhaps from someone with a CTP copy?
  183. #VisualStudio('TBD',
  184. # hkey_root=r'TBD',
  185. # common_tools_var='TBD',
  186. # executable_path=r'TBD',
  187. # default_dirname='TBD',
  188. #),
  189. # Visual Studio 2008
  190. # The batch file we look for is in the VC directory,
  191. # so the devenv.com executable is up in ..\..\Common7\IDE.
  192. VisualStudio('9.0',
  193. sdk_version='6.1',
  194. hkeys=[r'Microsoft\VisualStudio\9.0\Setup\VS\ProductDir'],
  195. common_tools_var='VS90COMNTOOLS',
  196. executable_path=r'Common7\IDE\devenv.com',
  197. batch_file_path=r'Common7\Tools\vsvars32.bat',
  198. default_dirname='Microsoft Visual Studio 9',
  199. supported_arch=['x86', 'amd64'],
  200. ),
  201. # Visual C++ 2008 Express Edition
  202. # The batch file we look for is in the VC directory,
  203. # so the VCExpress.exe executable is up in ..\..\Common7\IDE.
  204. VisualStudio('9.0Exp',
  205. vc_version='9.0',
  206. sdk_version='6.1',
  207. hkeys=[r'Microsoft\VCExpress\9.0\Setup\VS\ProductDir'],
  208. common_tools_var='VS90COMNTOOLS',
  209. executable_path=r'Common7\IDE\VCExpress.exe',
  210. batch_file_path=r'Common7\Tools\vsvars32.bat',
  211. default_dirname='Microsoft Visual Studio 9',
  212. supported_arch=['x86'],
  213. ),
  214. # Visual Studio 2005
  215. # The batch file we look for is in the VC directory,
  216. # so the devenv.com executable is up in ..\..\Common7\IDE.
  217. VisualStudio('8.0',
  218. sdk_version='6.0A',
  219. hkeys=[r'Microsoft\VisualStudio\8.0\Setup\VS\ProductDir'],
  220. common_tools_var='VS80COMNTOOLS',
  221. executable_path=r'Common7\IDE\devenv.com',
  222. batch_file_path=r'Common7\Tools\vsvars32.bat',
  223. default_dirname='Microsoft Visual Studio 8',
  224. supported_arch=['x86', 'amd64'],
  225. ),
  226. # Visual C++ 2005 Express Edition
  227. # The batch file we look for is in the VC directory,
  228. # so the VCExpress.exe executable is up in ..\..\Common7\IDE.
  229. VisualStudio('8.0Exp',
  230. vc_version='8.0Exp',
  231. sdk_version='6.0A',
  232. hkeys=[r'Microsoft\VCExpress\8.0\Setup\VS\ProductDir'],
  233. common_tools_var='VS80COMNTOOLS',
  234. executable_path=r'Common7\IDE\VCExpress.exe',
  235. batch_file_path=r'Common7\Tools\vsvars32.bat',
  236. default_dirname='Microsoft Visual Studio 8',
  237. supported_arch=['x86'],
  238. ),
  239. # Visual Studio .NET 2003
  240. # The batch file we look for is in the Common7\Tools directory,
  241. # so the devenv.com executable is next door in ..\IDE.
  242. VisualStudio('7.1',
  243. sdk_version='6.0',
  244. hkeys=[r'Microsoft\VisualStudio\7.1\Setup\VS\ProductDir'],
  245. common_tools_var='VS71COMNTOOLS',
  246. executable_path=r'Common7\IDE\devenv.com',
  247. batch_file_path=r'Common7\Tools\vsvars32.bat',
  248. default_dirname='Microsoft Visual Studio .NET 2003',
  249. supported_arch=['x86'],
  250. ),
  251. # Visual Studio .NET
  252. # The batch file we look for is in the Common7\Tools directory,
  253. # so the devenv.com executable is next door in ..\IDE.
  254. VisualStudio('7.0',
  255. sdk_version='2003R2',
  256. hkeys=[r'Microsoft\VisualStudio\7.0\Setup\VS\ProductDir'],
  257. common_tools_var='VS70COMNTOOLS',
  258. executable_path=r'IDE\devenv.com',
  259. batch_file_path=r'Common7\Tools\vsvars32.bat',
  260. default_dirname='Microsoft Visual Studio .NET',
  261. supported_arch=['x86'],
  262. ),
  263. # Visual Studio 6.0
  264. VisualStudio('6.0',
  265. sdk_version='2003R1',
  266. hkeys=[r'Microsoft\VisualStudio\6.0\Setup\Microsoft Visual Studio\ProductDir',
  267. 'use_dir'],
  268. common_tools_var='VS60COMNTOOLS',
  269. executable_path=r'Common\MSDev98\Bin\MSDEV.COM',
  270. batch_file_path=r'Common7\Tools\vsvars32.bat',
  271. default_dirname='Microsoft Visual Studio',
  272. supported_arch=['x86'],
  273. ),
  274. ]
  275. SupportedVSMap = {}
  276. for vs in SupportedVSList:
  277. SupportedVSMap[vs.version] = vs
  278. # Finding installed versions of Visual Studio isn't cheap, because it
  279. # goes not only to the registry but also to the disk to sanity-check
  280. # that there is, in fact, a Visual Studio directory there and that the
  281. # registry entry isn't just stale. Find this information once, when
  282. # requested, and cache it.
  283. InstalledVSList = None
  284. InstalledVSMap = None
  285. def get_installed_visual_studios():
  286. global InstalledVSList
  287. global InstalledVSMap
  288. if InstalledVSList is None:
  289. InstalledVSList = []
  290. InstalledVSMap = {}
  291. for vs in SupportedVSList:
  292. debug('trying to find VS %s' % vs.version)
  293. if vs.get_executable():
  294. debug('found VS %s' % vs.version)
  295. InstalledVSList.append(vs)
  296. InstalledVSMap[vs.version] = vs
  297. return InstalledVSList
  298. def reset_installed_visual_studios():
  299. global InstalledVSList
  300. global InstalledVSMap
  301. InstalledVSList = None
  302. InstalledVSMap = None
  303. for vs in SupportedVSList:
  304. vs.reset()
  305. # Need to clear installed VC's as well as they are used in finding
  306. # installed VS's
  307. SCons.Tool.MSCommon.vc.reset_installed_vcs()
  308. # We may be asked to update multiple construction environments with
  309. # SDK information. When doing this, we check on-disk for whether
  310. # the SDK has 'mfc' and 'atl' subdirectories. Since going to disk
  311. # is expensive, cache results by directory.
  312. #SDKEnvironmentUpdates = {}
  313. #
  314. #def set_sdk_by_directory(env, sdk_dir):
  315. # global SDKEnvironmentUpdates
  316. # try:
  317. # env_tuple_list = SDKEnvironmentUpdates[sdk_dir]
  318. # except KeyError:
  319. # env_tuple_list = []
  320. # SDKEnvironmentUpdates[sdk_dir] = env_tuple_list
  321. #
  322. # include_path = os.path.join(sdk_dir, 'include')
  323. # mfc_path = os.path.join(include_path, 'mfc')
  324. # atl_path = os.path.join(include_path, 'atl')
  325. #
  326. # if os.path.exists(mfc_path):
  327. # env_tuple_list.append(('INCLUDE', mfc_path))
  328. # if os.path.exists(atl_path):
  329. # env_tuple_list.append(('INCLUDE', atl_path))
  330. # env_tuple_list.append(('INCLUDE', include_path))
  331. #
  332. # env_tuple_list.append(('LIB', os.path.join(sdk_dir, 'lib')))
  333. # env_tuple_list.append(('LIBPATH', os.path.join(sdk_dir, 'lib')))
  334. # env_tuple_list.append(('PATH', os.path.join(sdk_dir, 'bin')))
  335. #
  336. # for variable, directory in env_tuple_list:
  337. # env.PrependENVPath(variable, directory)
  338. def msvs_exists():
  339. return (len(get_installed_visual_studios()) > 0)
  340. def get_vs_by_version(msvs):
  341. global InstalledVSMap
  342. global SupportedVSMap
  343. debug('vs.py:get_vs_by_version()')
  344. if msvs not in SupportedVSMap:
  345. msg = "Visual Studio version %s is not supported" % repr(msvs)
  346. raise SCons.Errors.UserError(msg)
  347. get_installed_visual_studios()
  348. vs = InstalledVSMap.get(msvs)
  349. debug('InstalledVSMap:%s'%InstalledVSMap)
  350. debug('vs.py:get_vs_by_version: found vs:%s'%vs)
  351. # Some check like this would let us provide a useful error message
  352. # if they try to set a Visual Studio version that's not installed.
  353. # However, we also want to be able to run tests (like the unit
  354. # tests) on systems that don't, or won't ever, have it installed.
  355. # It might be worth resurrecting this, with some configurable
  356. # setting that the tests can use to bypass the check.
  357. #if not vs:
  358. # msg = "Visual Studio version %s is not installed" % repr(msvs)
  359. # raise SCons.Errors.UserError, msg
  360. return vs
  361. def get_default_version(env):
  362. """Returns the default version string to use for MSVS.
  363. If no version was requested by the user through the MSVS environment
  364. variable, query all the available the visual studios through
  365. query_versions, and take the highest one.
  366. Return
  367. ------
  368. version: str
  369. the default version.
  370. """
  371. if 'MSVS' not in env or not SCons.Util.is_Dict(env['MSVS']):
  372. versions = [vs.version for vs in get_installed_visual_studios()]
  373. env['MSVS'] = {'VERSIONS' : versions}
  374. else:
  375. versions = env['MSVS'].get('VERSIONS', [])
  376. if 'MSVS_VERSION' not in env:
  377. if versions:
  378. env['MSVS_VERSION'] = versions[0] #use highest version by default
  379. else:
  380. env['MSVS_VERSION'] = SupportedVSList[0].version
  381. env['MSVS']['VERSION'] = env['MSVS_VERSION']
  382. return env['MSVS_VERSION']
  383. def get_default_arch(env):
  384. """Return the default arch to use for MSVS
  385. if no version was requested by the user through the MSVS_ARCH environment
  386. variable, select x86
  387. Return
  388. ------
  389. arch: str
  390. """
  391. arch = env.get('MSVS_ARCH', 'x86')
  392. msvs = InstalledVSMap.get(env['MSVS_VERSION'])
  393. if not msvs:
  394. arch = 'x86'
  395. elif not arch in msvs.get_supported_arch():
  396. fmt = "Visual Studio version %s does not support architecture %s"
  397. raise SCons.Errors.UserError(fmt % (env['MSVS_VERSION'], arch))
  398. return arch
  399. def merge_default_version(env):
  400. version = get_default_version(env)
  401. arch = get_default_arch(env)
  402. def msvs_setup_env(env):
  403. batfilename = msvs.get_batch_file()
  404. msvs = get_vs_by_version(version)
  405. if msvs is None:
  406. return
  407. # XXX: I think this is broken. This will silently set a bogus tool instead
  408. # of failing, but there is no other way with the current scons tool
  409. # framework
  410. if batfilename is not None:
  411. vars = ('LIB', 'LIBPATH', 'PATH', 'INCLUDE')
  412. msvs_list = get_installed_visual_studios()
  413. vscommonvarnames = [vs.common_tools_var for vs in msvs_list]
  414. save_ENV = env['ENV']
  415. nenv = normalize_env(env['ENV'],
  416. ['COMSPEC'] + vscommonvarnames,
  417. force=True)
  418. try:
  419. output = get_output(batfilename, arch, env=nenv)
  420. finally:
  421. env['ENV'] = save_ENV
  422. vars = parse_output(output, vars)
  423. for k, v in vars.items():
  424. env.PrependENVPath(k, v, delete_existing=1)
  425. def query_versions():
  426. """Query the system to get available versions of VS. A version is
  427. considered when a batfile is found."""
  428. msvs_list = get_installed_visual_studios()
  429. versions = [msvs.version for msvs in msvs_list]
  430. return versions
  431. # Local Variables:
  432. # tab-width:4
  433. # indent-tabs-mode:nil
  434. # End:
  435. # vim: set expandtab tabstop=4 shiftwidth=4: