1 """engine.SCons.Tool.msvc
3 Tool-specific initialization for Microsoft Visual C/C++.
5 There normally shouldn't be any need to import this module directly.
6 It will usually be imported through the generic SCons.Tool.Tool()
14 # Permission is hereby granted, free of charge, to any person obtaining
15 # a copy of this software and associated documentation files (the
16 # "Software"), to deal in the Software without restriction, including
17 # without limitation the rights to use, copy, modify, merge, publish,
18 # distribute, sublicense, and/or sell copies of the Software, and to
19 # permit persons to whom the Software is furnished to do so, subject to
20 # the following conditions:
22 # The above copyright notice and this permission notice shall be included
23 # in all copies or substantial portions of the Software.
25 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
26 # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
27 # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
43 import SCons.Platform.win32
45 import SCons.Tool.msvs
49 CSuffixes = ['.c', '.C']
50 CXXSuffixes = ['.cc', '.cpp', '.cxx', '.c++', '.C++']
52 def _parse_msvc7_overrides(version,platform):
53 """ Parse any overridden defaults for MSVS directory locations
56 # First, we get the shell folder for this user:
57 if not SCons.Util.can_read_reg:
58 raise SCons.Errors.InternalError, "No Windows registry module was found"
62 (comps, t) = SCons.Util.RegGetValue(SCons.Util.HKEY_CURRENT_USER,
63 r'Software\Microsoft\Windows\CurrentVersion' +\
64 r'\Explorer\Shell Folders\Local AppData')
65 except SCons.Util.RegError:
66 raise SCons.Errors.InternalError, \
67 "The Local AppData directory was not found in the registry."
69 comps = comps + '\\Microsoft\\VisualStudio\\' + version + '\\VCComponents.dat'
72 if os.path.exists(comps):
73 # now we parse the directories from this file, if it exists.
74 # We only look for entries after:
75 # [VC\VC_OBJECTS_PLATFORM_INFO\Win32\Directories],
76 # since this file could contain a number of things...
84 f = codecs.open(comps, 'r', 'utf16')
85 encoder = codecs.getencoder('ascii')
86 lines = map(lambda l, e=encoder: e(l)[0], f.readlines())
87 except (LookupError, UnicodeError):
88 lines = codecs.open(comps, 'r', 'utf8').readlines()
90 lines = open(comps, 'r').readlines()
91 if 'x86' == platform: platform = 'Win32'
96 if line.find(r'[VC\VC_OBJECTS_PLATFORM_INFO\%s\Directories]'%platform) >= 0:
98 elif line == '' or line[:1] == '[':
101 kv = line.split('=', 1)
104 key = key.replace(' Dirs','')
105 dirs[key.upper()] = val
108 # since the file didn't exist, we have only the defaults in
109 # the registry to work with.
111 if 'x86' == platform: platform = 'Win32'
114 K = 'SOFTWARE\\Microsoft\\VisualStudio\\' + version
115 K = K + r'\VC\VC_OBJECTS_PLATFORM_INFO\%s\Directories'%platform
116 k = SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE,K)
120 (key,val,t) = SCons.Util.RegEnumValue(k,i)
121 key = key.replace(' Dirs','')
122 dirs[key.upper()] = val
124 except SCons.Util.RegError:
126 except SCons.Util.RegError:
127 # if we got here, then we didn't find the registry entries:
128 raise SCons.Errors.InternalError, "Unable to find MSVC paths in the registry."
131 def _parse_msvc8_overrides(version,platform,suite):
132 """ Parse any overridden defaults for MSVC directory locations
135 # In VS8 the user can change the location of the settings file that
136 # contains the include, lib and binary paths. Try to get the location
138 if not SCons.Util.can_read_reg:
139 raise SCons.Errors.InternalError, "No Windows registry module was found"
142 if suite == 'EXPRESS':
145 # ToDo: add registry key strings for the other versions of visual
149 (settings_path, t) = SCons.Util.RegGetValue(SCons.Util.HKEY_CURRENT_USER,
150 r'Software\Microsoft' + s + version +\
151 r'\Profile\AutoSaveFile')
152 settings_path = settings_path.upper()
153 except SCons.Util.RegError:
154 raise SCons.Errors.InternalError, \
155 "The VS8 settings file location was not found in the registry."
157 # Look for potential environment variables in the settings path
158 if settings_path.find('%VSSPV_VISUALSTUDIO_DIR%') >= 0:
159 # First replace a special variable named %vsspv_visualstudio_dir%
160 # that is not found in the OSs environment variables...
162 (value, t) = SCons.Util.RegGetValue(SCons.Util.HKEY_CURRENT_USER,
163 r'Software\Microsoft' + s + version +\
164 r'\VisualStudioLocation')
165 settings_path = settings_path.replace('%VSSPV_VISUALSTUDIO_DIR%', value)
166 except SCons.Util.RegError:
167 raise SCons.Errors.InternalError, "The VS8 settings file location was not found in the registry."
169 if settings_path.find('%') >= 0:
170 # Collect global environment variables
173 # Read all the global environment variables of the current user
174 k = SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_CURRENT_USER, r'Environment')
178 (key,val,t) = SCons.Util.RegEnumValue(k,i)
179 env_vars[key.upper()] = val.upper()
181 except SCons.Util.RegError:
184 # And some more variables that are not found in the registry
185 env_vars['USERPROFILE'] = os.getenv('USERPROFILE')
186 env_vars['SystemDrive'] = os.getenv('SystemDrive')
191 for env_var in env_vars:
192 if settings_path.find(r'%' + env_var + r'%') >= 0:
193 settings_path = settings_path.replace(r'%' + env_var + r'%', env_vars[env_var])
198 if os.path.exists(settings_path):
199 # now we parse the directories from this file, if it exists.
200 import xml.dom.minidom
201 doc = xml.dom.minidom.parse(settings_path)
202 user_settings = doc.getElementsByTagName('UserSettings')[0]
203 tool_options = user_settings.getElementsByTagName('ToolsOptions')[0]
204 tool_options_categories = tool_options.getElementsByTagName('ToolsOptionsCategory')
205 for category in tool_options_categories:
206 category_name = category.attributes.get('name')
207 if category_name is not None and category_name.value == 'Projects':
208 subcategories = category.getElementsByTagName('ToolsOptionsSubCategory')
209 for subcategory in subcategories:
210 subcategory_name = subcategory.attributes.get('name')
211 if subcategory_name is not None and subcategory_name.value == 'VCDirectories':
212 properties = subcategory.getElementsByTagName('PropertyValue')
213 for property in properties:
214 property_name = property.attributes.get('name')
215 if property_name is None:
217 elif property_name.value == 'IncludeDirectories':
218 include_dirs = property.childNodes[0].data
219 # ToDo: Support for other destinations than Win32
220 include_dirs = include_dirs.replace('Win32|', '')
221 dirs['INCLUDE'] = include_dirs
222 elif property_name.value == 'LibraryDirectories':
223 lib_dirs = property.childNodes[0].data.replace('Win32|', '')
224 # ToDo: Support for other destinations than Win32
225 lib_dirs = lib_dirs.replace('Win32|', '')
226 dirs['LIBRARY'] = lib_dirs
227 elif property_name.value == 'ExecutableDirectories':
228 path_dirs = property.childNodes[0].data.replace('Win32|', '')
229 # ToDo: Support for other destinations than Win32
230 path_dirs = path_dirs.replace('Win32|', '')
231 dirs['PATH'] = path_dirs
233 dirs['VCINSTALLDIR'] = os.getenv('VCInstallDir')
234 dirs['VSINSTALLDIR'] = os.getenv('VSInstallDir')
236 # There are no default directories in the registry for VS8 Express :(
237 raise SCons.Errors.InternalError, "Unable to find MSVC paths in the registry."
240 def _get_msvc7_path(path, version, platform):
242 Get Visual Studio directories from version 7 (MSVS .NET)
243 (it has a different registry structure than versions before it)
245 # first, look for a customization of the default values in the
246 # registry: These are sometimes stored in the Local Settings area
247 # for Visual Studio, in a file, so we have to parse it.
248 dirs = _parse_msvc7_overrides(version,platform)
250 if dirs.has_key(path):
253 raise SCons.Errors.InternalError, \
254 "Unable to retrieve the %s path from MS VC++."%path
256 # collect some useful information for later expansions...
257 paths = SCons.Tool.msvs.get_msvs_install_dirs(version)
259 # expand the directory path variables that we support. If there
260 # is a variable we don't support, then replace that entry with
261 # "---Unknown Location VSInstallDir---" or something similar, to clue
262 # people in that we didn't find something, and so env expansion doesn't
263 # do weird things with the $(xxx)'s
264 s = re.compile('\$\(([a-zA-Z0-9_]+?)\)')
266 def repl(match, paths=paths):
267 key = string.upper(match.group(1))
268 if paths.has_key(key):
271 return '---Unknown Location %s---' % match.group()
274 for entry in p.split(os.pathsep):
275 entry = s.sub(repl,entry).rstrip('\n\r')
278 return string.join(rv,os.pathsep)
280 def _get_msvc8_path(path, version, platform, suite):
282 Get Visual Studio directories from version 8 (MSVS 2005)
283 (it has a different registry structure than versions before it)
285 # first, look for a customization of the default values in the
286 # registry: These are sometimes stored in the Local Settings area
287 # for Visual Studio, in a file, so we have to parse it.
288 dirs = _parse_msvc8_overrides(version, platform, suite)
290 if dirs.has_key(path):
293 raise SCons.Errors.InternalError, \
294 "Unable to retrieve the %s path from MS VC++."%path
296 # collect some useful information for later expansions...
297 paths = SCons.Tool.msvs.get_msvs_install_dirs(version)
299 # expand the directory path variables that we support. If there
300 # is a variable we don't support, then replace that entry with
301 # "---Unknown Location VSInstallDir---" or something similar, to clue
302 # people in that we didn't find something, and so env expansion doesn't
303 # do weird things with the $(xxx)'s
304 s = re.compile('\$\(([a-zA-Z0-9_]+?)\)')
306 def repl(match, paths=paths):
307 key = string.upper(match.group(1))
308 if paths.has_key(key):
311 return '---Unknown Location %s---' % match.group()
314 for entry in p.split(os.pathsep):
315 entry = s.sub(repl,entry).rstrip('\n\r')
318 return string.join(rv,os.pathsep)
320 def get_msvc_path(env, path, version):
322 Get a list of visualstudio directories (include, lib or path).
323 Return a string delimited by the os.pathsep separator (';'). An
324 exception will be raised if unable to access the registry or
325 appropriate registry keys not found.
328 if not SCons.Util.can_read_reg:
329 raise SCons.Errors.InternalError, "No Windows registry module was found"
331 # normalize the case for comparisons (since the registry is case
333 path = string.upper(path)
338 version_num, suite = SCons.Tool.msvs.msvs_parse_version(version)
339 if version_num >= 8.0:
340 platform = env.get('MSVS8_PLATFORM', 'x86')
341 suite = SCons.Tool.msvs.get_default_visualstudio8_suite(env)
345 if version_num >= 8.0:
346 return _get_msvc8_path(path, version, platform, suite)
347 elif version_num >= 7.0:
348 return _get_msvc7_path(path, version, platform)
350 path = string.upper(path + ' Dirs')
351 K = ('Software\\Microsoft\\Devstudio\\%s\\' +
352 'Build System\\Components\\Platforms\\Win32 (x86)\\Directories') % \
354 for base in (SCons.Util.HKEY_CURRENT_USER,
355 SCons.Util.HKEY_LOCAL_MACHINE):
357 k = SCons.Util.RegOpenKeyEx(base,K)
361 (p,v,t) = SCons.Util.RegEnumValue(k,i)
362 if string.upper(p) == path:
365 except SCons.Util.RegError:
367 except SCons.Util.RegError:
370 # if we got here, then we didn't find the registry entries:
371 raise SCons.Errors.InternalError, "The %s path was not found in the registry."%path
373 def _get_msvc6_default_paths(version, use_mfc_dirs):
374 """Return a 3-tuple of (INCLUDE, LIB, PATH) as the values of those
375 three environment variables that should be set in order to execute
376 the MSVC 6.0 tools properly, if the information wasn't available
377 from the registry."""
384 paths = SCons.Tool.msvs.get_msvs_install_dirs(version)
385 MVSdir = paths['VSINSTALLDIR']
386 except (SCons.Util.RegError, SCons.Errors.InternalError, KeyError):
387 if os.environ.has_key('MSDEVDIR'):
388 MVSdir = os.path.normpath(os.path.join(os.environ['MSDEVDIR'],'..','..'))
390 MVSdir = r'C:\Program Files\Microsoft Visual Studio'
392 if SCons.Util.can_read_reg and paths.has_key('VCINSTALLDIR'):
393 MVSVCdir = paths['VCINSTALLDIR']
395 MVSVCdir = os.path.join(MVSdir,'VC98')
397 MVSCommondir = r'%s\Common' % MVSdir
399 mfc_include_ = r'%s\ATL\include;%s\MFC\include;' % (MVSVCdir, MVSVCdir)
400 mfc_lib_ = r'%s\MFC\lib;' % MVSVCdir
404 include_path = r'%s%s\include' % (mfc_include_, MVSVCdir)
405 lib_path = r'%s%s\lib' % (mfc_lib_, MVSVCdir)
407 if os.environ.has_key('OS') and os.environ['OS'] == "Windows_NT":
412 exe_path = r'%s\tools\%s;%s\MSDev98\bin;%s\tools;%s\bin' % (MVSCommondir, osdir, MVSCommondir, MVSCommondir, MVSVCdir)
413 return (include_path, lib_path, exe_path)
415 def _get_msvc7_default_paths(env, version, use_mfc_dirs):
416 """Return a 3-tuple of (INCLUDE, LIB, PATH) as the values of those
417 three environment variables that should be set in order to execute
418 the MSVC .NET tools properly, if the information wasn't available
419 from the registry."""
427 paths = SCons.Tool.msvs.get_msvs_install_dirs(version)
428 MVSdir = paths['VSINSTALLDIR']
429 except (KeyError, SCons.Util.RegError, SCons.Errors.InternalError):
430 if os.environ.has_key('VSCOMNTOOLS'):
431 MVSdir = os.path.normpath(os.path.join(os.environ['VSCOMNTOOLS'],'..','..'))
433 # last resort -- default install location
434 MVSdir = r'C:\Program Files\Microsoft Visual Studio .NET'
437 if SCons.Util.can_read_reg and paths.has_key('VCINSTALLDIR'):
438 MVSVCdir = paths['VCINSTALLDIR']
440 MVSVCdir = os.path.join(MVSdir,'Vc7')
442 MVSCommondir = r'%s\Common7' % MVSdir
444 mfc_include_ = r'%s\atlmfc\include;' % MVSVCdir
445 mfc_lib_ = r'%s\atlmfc\lib;' % MVSVCdir
449 include_path = r'%s%s\include;%s\PlatformSDK\include' % (mfc_include_, MVSVCdir, MVSVCdir)
450 lib_path = r'%s%s\lib;%s\PlatformSDK\lib' % (mfc_lib_, MVSVCdir, MVSVCdir)
451 exe_path = r'%s\IDE;%s\bin;%s\Tools;%s\Tools\bin' % (MVSCommondir,MVSVCdir, MVSCommondir, MVSCommondir )
453 if SCons.Util.can_read_reg and paths.has_key('FRAMEWORKSDKDIR'):
454 include_path = include_path + r';%s\include'%paths['FRAMEWORKSDKDIR']
455 lib_path = lib_path + r';%s\lib'%paths['FRAMEWORKSDKDIR']
456 exe_path = exe_path + r';%s\bin'%paths['FRAMEWORKSDKDIR']
458 if SCons.Util.can_read_reg and paths.has_key('FRAMEWORKDIR') and paths.has_key('FRAMEWORKVERSION'):
459 exe_path = exe_path + r';%s\%s'%(paths['FRAMEWORKDIR'],paths['FRAMEWORKVERSION'])
461 return (include_path, lib_path, exe_path)
463 def _get_msvc8_default_paths(env, version, suite, use_mfc_dirs):
464 """Return a 3-tuple of (INCLUDE, LIB, PATH) as the values of those
465 three environment variables that should be set in order to execute
466 the MSVC 8 tools properly, if the information wasn't available
467 from the registry."""
475 paths = SCons.Tool.msvs.get_msvs_install_dirs(version)
476 MVSdir = paths['VSINSTALLDIR']
477 except (KeyError, SCons.Util.RegError, SCons.Errors.InternalError):
478 if os.environ.has_key('VSCOMNTOOLS'):
479 MVSdir = os.path.normpath(os.path.join(os.environ['VSCOMNTOOLS'],'..','..'))
481 # last resort -- default install location
482 MVSdir = os.getenv('ProgramFiles') + r'\Microsoft Visual Studio 8'
485 if SCons.Util.can_read_reg and paths.has_key('VCINSTALLDIR'):
486 MVSVCdir = paths['VCINSTALLDIR']
488 MVSVCdir = os.path.join(MVSdir,'VC')
490 MVSCommondir = os.path.join(MVSdir, 'Common7')
491 include_paths.append( os.path.join(MVSVCdir, 'include') )
492 lib_paths.append( os.path.join(MVSVCdir, 'lib') )
493 for base, subdir in [(MVSCommondir,'IDE'), (MVSVCdir,'bin'),
494 (MVSCommondir,'Tools'), (MVSCommondir,r'Tools\bin')]:
495 exe_paths.append( os.path.join( base, subdir) )
497 if paths.has_key('PLATFORMSDKDIR'):
498 PlatformSdkDir = paths['PLATFORMSDKDIR']
500 PlatformSdkDir = os.path.join(MVSVCdir,'PlatformSDK')
501 platform_include_path = os.path.join( PlatformSdkDir, 'Include' )
502 include_paths.append( platform_include_path )
503 lib_paths.append( os.path.join( PlatformSdkDir, 'Lib' ) )
505 if paths.has_key('PLATFORMSDKDIR'):
506 include_paths.append( os.path.join( platform_include_path, 'mfc' ) )
507 include_paths.append( os.path.join( platform_include_path, 'atl' ) )
509 atlmfc_path = os.path.join( MVSVCdir, 'atlmfc' )
510 include_paths.append( os.path.join( atlmfc_path, 'include' ) )
511 lib_paths.append( os.path.join( atlmfc_path, 'lib' ) )
513 env_include_path = SCons.Util.get_environment_var('INCLUDE')
515 include_paths.append( env_include_path )
517 if SCons.Util.can_read_reg and paths.has_key('FRAMEWORKSDKDIR'):
518 include_paths.append( os.path.join( paths['FRAMEWORKSDKDIR'], 'include' ) )
519 lib_paths.append( os.path.join( paths['FRAMEWORKSDKDIR'], 'lib' ) )
520 exe_paths.append( paths['FRAMEWORKSDKDIR'], 'bin' )
522 if SCons.Util.can_read_reg and paths.has_key('FRAMEWORKDIR') and paths.has_key('FRAMEWORKVERSION'):
523 exe_paths.append( os.path.join( paths['FRAMEWORKDIR'], paths['FRAMEWORKVERSION'] ) )
525 include_path = string.join( include_paths, os.pathsep )
526 lib_path = string.join(lib_paths, os.pathsep )
527 exe_path = string.join(exe_paths, os.pathsep )
528 return (include_path, lib_path, exe_path)
530 def get_msvc_paths(env, version=None, use_mfc_dirs=0):
531 """Return a 3-tuple of (INCLUDE, LIB, PATH) as the values
532 of those three environment variables that should be set
533 in order to execute the MSVC tools properly."""
539 versions = SCons.Tool.msvs.get_visualstudio_versions()
541 version = versions[0] #use highest version by default
545 # Some of the configured directories only
546 # appear if the user changes them from the default.
547 # Therefore, we'll see if we can get the path to the MSDev
548 # base installation from the registry and deduce the default
550 version_num, suite = SCons.Tool.msvs.msvs_parse_version(version)
551 if version_num >= 8.0:
552 suite = SCons.Tool.msvs.get_default_visualstudio8_suite(env)
553 defpaths = _get_msvc8_default_paths(env, version, suite, use_mfc_dirs)
554 elif version_num >= 7.0:
555 defpaths = _get_msvc7_default_paths(env, version, use_mfc_dirs)
557 defpaths = _get_msvc6_default_paths(version, use_mfc_dirs)
560 include_path = get_msvc_path(env, "include", version)
561 except (SCons.Util.RegError, SCons.Errors.InternalError):
562 include_path = defpaths[0]
565 lib_path = get_msvc_path(env, "lib", version)
566 except (SCons.Util.RegError, SCons.Errors.InternalError):
567 lib_path = defpaths[1]
570 exe_path = get_msvc_path(env, "path", version)
571 except (SCons.Util.RegError, SCons.Errors.InternalError):
572 exe_path = defpaths[2]
574 return (include_path, lib_path, exe_path)
576 def get_msvc_default_paths(env, version=None, use_mfc_dirs=0):
577 """Return a 3-tuple of (INCLUDE, LIB, PATH) as the values of those
578 three environment variables that should be set in order to execute
579 the MSVC tools properly. This will only return the default
580 locations for the tools, not the values used by MSVS in their
581 directory setup area. This can help avoid problems with different
582 developers having different settings, and should allow the tools
583 to run in most cases."""
585 if not version and not SCons.Util.can_read_reg:
590 version = SCons.Tool.msvs.get_visualstudio_versions()[0] #use highest version
591 except KeyboardInterrupt:
596 version_num, suite = SCons.Tool.msvs.msvs_parse_version(version)
597 if version_num >= 8.0:
598 suite = SCons.Tool.msvs.get_default_visualstudio8_suite(env)
599 defpaths = _get_msvc8_default_paths(env, version, suite, use_mfc_dirs)
600 elif version_num >= 7.0:
601 return _get_msvc7_default_paths(env, version, use_mfc_dirs)
603 return _get_msvc6_default_paths(version, use_mfc_dirs)
605 def validate_vars(env):
606 """Validate the PCH and PCHSTOP construction variables."""
607 if env.has_key('PCH') and env['PCH']:
608 if not env.has_key('PCHSTOP'):
609 raise SCons.Errors.UserError, "The PCHSTOP construction must be defined if PCH is defined."
610 if not SCons.Util.is_String(env['PCHSTOP']):
611 raise SCons.Errors.UserError, "The PCHSTOP construction variable must be a string: %r"%env['PCHSTOP']
613 def pch_emitter(target, source, env):
614 """Adds the object file target."""
622 if SCons.Util.splitext(str(t))[1] == '.pch':
624 if SCons.Util.splitext(str(t))[1] == '.obj':
628 obj = SCons.Util.splitext(str(pch))[0]+'.obj'
630 target = [pch, obj] # pch must be first, and obj second for the PCHCOM to work
632 return (target, source)
634 def object_emitter(target, source, env, parent_emitter):
635 """Sets up the PCH dependencies for an object file."""
639 parent_emitter(target, source, env)
641 if env.has_key('PCH') and env['PCH']:
642 env.Depends(target, env['PCH'])
644 return (target, source)
646 def static_object_emitter(target, source, env):
647 return object_emitter(target, source, env,
648 SCons.Defaults.StaticObjectEmitter)
650 def shared_object_emitter(target, source, env):
651 return object_emitter(target, source, env,
652 SCons.Defaults.SharedObjectEmitter)
654 pch_action = SCons.Action.Action('$PCHCOM', '$PCHCOMSTR')
655 pch_builder = SCons.Builder.Builder(action=pch_action, suffix='.pch',
657 source_scanner=SCons.Tool.SourceFileScanner)
658 res_action = SCons.Action.Action('$RCCOM', '$RCCOMSTR')
659 res_builder = SCons.Builder.Builder(action=res_action, suffix='.res',
660 source_scanner=SCons.Tool.SourceFileScanner)
661 SCons.Tool.SourceFileScanner.add_scanner('.rc', SCons.Defaults.CScan)
664 """Add Builders and construction variables for MSVC++ to an Environment."""
665 static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
667 for suffix in CSuffixes:
668 static_obj.add_action(suffix, SCons.Defaults.CAction)
669 shared_obj.add_action(suffix, SCons.Defaults.ShCAction)
670 static_obj.add_emitter(suffix, static_object_emitter)
671 shared_obj.add_emitter(suffix, shared_object_emitter)
673 for suffix in CXXSuffixes:
674 static_obj.add_action(suffix, SCons.Defaults.CXXAction)
675 shared_obj.add_action(suffix, SCons.Defaults.ShCXXAction)
676 static_obj.add_emitter(suffix, static_object_emitter)
677 shared_obj.add_emitter(suffix, shared_object_emitter)
679 env['CCPDBFLAGS'] = SCons.Util.CLVar(['${(PDB and "/Z7") or ""}'])
680 env['CCPCHFLAGS'] = SCons.Util.CLVar(['${(PCH and "/Yu%s /Fp%s"%(PCHSTOP or "",File(PCH))) or ""}'])
681 env['CCCOMFLAGS'] = '$CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c $SOURCES /Fo$TARGET $CCPCHFLAGS $CCPDBFLAGS'
683 env['CCFLAGS'] = SCons.Util.CLVar('/nologo')
684 env['CCCOM'] = '$CC $CCFLAGS $CCCOMFLAGS'
686 env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS')
687 env['SHCCCOM'] = '$SHCC $SHCCFLAGS $CCCOMFLAGS'
689 env['CXXFLAGS'] = SCons.Util.CLVar('$CCFLAGS $( /TP $)')
690 env['CXXCOM'] = '$CXX $CXXFLAGS $CCCOMFLAGS'
691 env['SHCXX'] = '$CXX'
692 env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS')
693 env['SHCXXCOM'] = '$SHCXX $SHCXXFLAGS $CCCOMFLAGS'
694 env['CPPDEFPREFIX'] = '/D'
695 env['CPPDEFSUFFIX'] = ''
696 env['INCPREFIX'] = '/I'
697 env['INCSUFFIX'] = ''
698 # env.Append(OBJEMITTER = [static_object_emitter])
699 # env.Append(SHOBJEMITTER = [shared_object_emitter])
700 env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1
703 env['RCFLAGS'] = SCons.Util.CLVar('')
704 env['RCCOM'] = '$RC $_CPPDEFFLAGS $_CPPINCFLAGS $RCFLAGS /fo$TARGET $SOURCES'
705 env['BUILDERS']['RES'] = res_builder
706 env['OBJPREFIX'] = ''
707 env['OBJSUFFIX'] = '.obj'
708 env['SHOBJPREFIX'] = '$OBJPREFIX'
709 env['SHOBJSUFFIX'] = '$OBJSUFFIX'
712 version = SCons.Tool.msvs.get_default_visualstudio_version(env)
713 version_num, suite = SCons.Tool.msvs.msvs_parse_version(version)
714 if version_num == 8.0:
715 suite = SCons.Tool.msvs.get_default_visualstudio8_suite(env)
717 use_mfc_dirs = env.get('MSVS_USE_MFC_DIRS', 0)
718 if env.get('MSVS_IGNORE_IDE_PATHS', 0):
719 _get_paths = get_msvc_default_paths
721 _get_paths = get_msvc_paths
722 include_path, lib_path, exe_path = _get_paths(env, version, use_mfc_dirs)
724 # since other tools can set these, we just make sure that the
725 # relevant stuff from MSVS is in there somewhere.
726 env.PrependENVPath('INCLUDE', include_path)
727 env.PrependENVPath('LIB', lib_path)
728 env.PrependENVPath('PATH', exe_path)
729 except (SCons.Util.RegError, SCons.Errors.InternalError):
732 env['CFILESUFFIX'] = '.c'
733 env['CXXFILESUFFIX'] = '.cc'
735 env['PCHPDBFLAGS'] = SCons.Util.CLVar(['${(PDB and "/Yd") or ""}'])
736 env['PCHCOM'] = '$CXX $CXXFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c $SOURCES /Fo${TARGETS[1]} /Yc$PCHSTOP /Fp${TARGETS[0]} $CCPDBFLAGS $PCHPDBFLAGS'
737 env['BUILDERS']['PCH'] = pch_builder
739 if not env.has_key('ENV'):
741 if not env['ENV'].has_key('SystemRoot'): # required for dlls in the winsxs folders
742 env['ENV']['SystemRoot'] = SCons.Platform.win32.get_system_root()
745 if SCons.Tool.msvs.is_msvs_installed():
746 # there's at least one version of MSVS installed.
749 return env.Detect('cl')