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"
141 # XXX This code assumes anything that isn't EXPRESS uses the default
142 # registry key string. Is this really true for all VS suites?
143 if suite == 'EXPRESS':
146 s = '\\VisualStudio\\'
150 (settings_path, t) = SCons.Util.RegGetValue(SCons.Util.HKEY_CURRENT_USER,
151 r'Software\Microsoft' + s + version +\
152 r'\Profile\AutoSaveFile')
153 settings_path = settings_path.upper()
154 except SCons.Util.RegError:
155 raise SCons.Errors.InternalError, \
156 "The VS8 settings file location was not found in the registry."
158 # Look for potential environment variables in the settings path
159 if settings_path.find('%VSSPV_VISUALSTUDIO_DIR%') >= 0:
160 # First replace a special variable named %vsspv_visualstudio_dir%
161 # that is not found in the OSs environment variables...
163 (value, t) = SCons.Util.RegGetValue(SCons.Util.HKEY_CURRENT_USER,
164 r'Software\Microsoft' + s + version +\
165 r'\VisualStudioLocation')
166 settings_path = settings_path.replace('%VSSPV_VISUALSTUDIO_DIR%', value)
167 except SCons.Util.RegError:
168 raise SCons.Errors.InternalError, "The VS8 settings file location was not found in the registry."
170 if settings_path.find('%') >= 0:
171 # Collect global environment variables
174 # Read all the global environment variables of the current user
175 k = SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_CURRENT_USER, r'Environment')
179 (key,val,t) = SCons.Util.RegEnumValue(k,i)
180 env_vars[key.upper()] = val.upper()
182 except SCons.Util.RegError:
185 # And some more variables that are not found in the registry
186 env_vars['USERPROFILE'] = os.getenv('USERPROFILE')
187 env_vars['SystemDrive'] = os.getenv('SystemDrive')
192 for env_var in env_vars:
193 if settings_path.find(r'%' + env_var + r'%') >= 0:
194 settings_path = settings_path.replace(r'%' + env_var + r'%', env_vars[env_var])
199 if os.path.exists(settings_path):
200 # now we parse the directories from this file, if it exists.
201 import xml.dom.minidom
202 doc = xml.dom.minidom.parse(settings_path)
203 user_settings = doc.getElementsByTagName('UserSettings')[0]
204 tool_options = user_settings.getElementsByTagName('ToolsOptions')[0]
205 tool_options_categories = tool_options.getElementsByTagName('ToolsOptionsCategory')
206 environment_var_map = {
207 'IncludeDirectories' : 'INCLUDE',
208 'LibraryDirectories' : 'LIBRARY',
209 'ExecutableDirectories' : 'PATH',
211 for category in tool_options_categories:
212 category_name = category.attributes.get('name')
213 if category_name is not None and category_name.value == 'Projects':
214 subcategories = category.getElementsByTagName('ToolsOptionsSubCategory')
215 for subcategory in subcategories:
216 subcategory_name = subcategory.attributes.get('name')
217 if subcategory_name is not None and subcategory_name.value == 'VCDirectories':
218 properties = subcategory.getElementsByTagName('PropertyValue')
219 for property in properties:
220 property_name = property.attributes.get('name')
221 if property_name is None:
223 var_name = environment_var_map.get(property_name)
225 data = property.childNodes[0].data
226 value_list = string.split(data, '|')
227 if len(value_list) == 1:
228 dirs[var_name] = value_list[0]
231 dest, value = value_list[:2]
233 # ToDo: Support for destinations
236 dirs[var_name] = value
239 # There are no default directories in the registry for VS8 Express :(
240 raise SCons.Errors.InternalError, "Unable to find MSVC paths in the registry."
243 def _get_msvc7_path(path, version, platform):
245 Get Visual Studio directories from version 7 (MSVS .NET)
246 (it has a different registry structure than versions before it)
248 # first, look for a customization of the default values in the
249 # registry: These are sometimes stored in the Local Settings area
250 # for Visual Studio, in a file, so we have to parse it.
251 dirs = _parse_msvc7_overrides(version,platform)
253 if dirs.has_key(path):
256 raise SCons.Errors.InternalError, \
257 "Unable to retrieve the %s path from MS VC++."%path
259 # collect some useful information for later expansions...
260 paths = SCons.Tool.msvs.get_msvs_install_dirs(version)
262 # expand the directory path variables that we support. If there
263 # is a variable we don't support, then replace that entry with
264 # "---Unknown Location VSInstallDir---" or something similar, to clue
265 # people in that we didn't find something, and so env expansion doesn't
266 # do weird things with the $(xxx)'s
267 s = re.compile('\$\(([a-zA-Z0-9_]+?)\)')
269 def repl(match, paths=paths):
270 key = string.upper(match.group(1))
271 if paths.has_key(key):
274 # Now look in the global environment variables
275 envresult = os.getenv(key)
276 if not envresult is None:
277 return envresult + '\\'
279 return '---Unknown Location %s---' % match.group()
282 for entry in p.split(os.pathsep):
283 entry = s.sub(repl,entry).rstrip('\n\r')
286 return string.join(rv,os.pathsep)
288 def _get_msvc8_path(path, version, platform, suite):
290 Get Visual Studio directories from version 8 (MSVS 2005)
291 (it has a different registry structure than versions before it)
293 # first, look for a customization of the default values in the
294 # registry: These are sometimes stored in the Local Settings area
295 # for Visual Studio, in a file, so we have to parse it.
296 dirs = _parse_msvc8_overrides(version, platform, suite)
298 if dirs.has_key(path):
301 raise SCons.Errors.InternalError, \
302 "Unable to retrieve the %s path from MS VC++."%path
304 # collect some useful information for later expansions...
305 paths = SCons.Tool.msvs.get_msvs_install_dirs(version, suite)
307 # expand the directory path variables that we support. If there
308 # is a variable we don't support, then replace that entry with
309 # "---Unknown Location VSInstallDir---" or something similar, to clue
310 # people in that we didn't find something, and so env expansion doesn't
311 # do weird things with the $(xxx)'s
312 s = re.compile('\$\(([a-zA-Z0-9_]+?)\)')
314 def repl(match, paths=paths):
315 key = string.upper(match.group(1))
316 if paths.has_key(key):
319 return '---Unknown Location %s---' % match.group()
322 for entry in p.split(os.pathsep):
323 entry = s.sub(repl,entry).rstrip('\n\r')
326 return string.join(rv,os.pathsep)
328 def get_msvc_path(env, path, version):
330 Get a list of visualstudio directories (include, lib or path).
331 Return a string delimited by the os.pathsep separator (';'). An
332 exception will be raised if unable to access the registry or
333 appropriate registry keys not found.
336 if not SCons.Util.can_read_reg:
337 raise SCons.Errors.InternalError, "No Windows registry module was found"
339 # normalize the case for comparisons (since the registry is case
341 path = string.upper(path)
346 version_num, suite = SCons.Tool.msvs.msvs_parse_version(version)
347 if version_num >= 8.0:
348 platform = env.get('MSVS8_PLATFORM', 'x86')
349 suite = SCons.Tool.msvs.get_default_visualstudio8_suite(env)
353 if version_num >= 8.0:
354 return _get_msvc8_path(path, str(version_num), platform, suite)
355 elif version_num >= 7.0:
356 return _get_msvc7_path(path, str(version_num), platform)
358 path = string.upper(path + ' Dirs')
359 K = ('Software\\Microsoft\\Devstudio\\%s\\' +
360 'Build System\\Components\\Platforms\\Win32 (x86)\\Directories') % \
362 for base in (SCons.Util.HKEY_CURRENT_USER,
363 SCons.Util.HKEY_LOCAL_MACHINE):
365 k = SCons.Util.RegOpenKeyEx(base,K)
369 (p,v,t) = SCons.Util.RegEnumValue(k,i)
370 if string.upper(p) == path:
373 except SCons.Util.RegError:
375 except SCons.Util.RegError:
378 # if we got here, then we didn't find the registry entries:
379 raise SCons.Errors.InternalError, "The %s path was not found in the registry."%path
381 def _get_msvc6_default_paths(version, use_mfc_dirs):
382 """Return a 3-tuple of (INCLUDE, LIB, PATH) as the values of those
383 three environment variables that should be set in order to execute
384 the MSVC 6.0 tools properly, if the information wasn't available
385 from the registry."""
392 paths = SCons.Tool.msvs.get_msvs_install_dirs(version)
393 MVSdir = paths['VSINSTALLDIR']
394 except (SCons.Util.RegError, SCons.Errors.InternalError, KeyError):
395 if os.environ.has_key('MSDEVDIR'):
396 MVSdir = os.path.normpath(os.path.join(os.environ['MSDEVDIR'],'..','..'))
398 MVSdir = r'C:\Program Files\Microsoft Visual Studio'
400 if SCons.Util.can_read_reg and paths.has_key('VCINSTALLDIR'):
401 MVSVCdir = paths['VCINSTALLDIR']
403 MVSVCdir = os.path.join(MVSdir,'VC98')
405 MVSCommondir = r'%s\Common' % MVSdir
407 mfc_include_ = r'%s\ATL\include;%s\MFC\include;' % (MVSVCdir, MVSVCdir)
408 mfc_lib_ = r'%s\MFC\lib;' % MVSVCdir
412 include_path = r'%s%s\include' % (mfc_include_, MVSVCdir)
413 lib_path = r'%s%s\lib' % (mfc_lib_, MVSVCdir)
415 if os.environ.has_key('OS') and os.environ['OS'] == "Windows_NT":
420 exe_path = r'%s\tools\%s;%s\MSDev98\bin;%s\tools;%s\bin' % (MVSCommondir, osdir, MVSCommondir, MVSCommondir, MVSVCdir)
421 return (include_path, lib_path, exe_path)
423 def _get_msvc7_default_paths(env, version, use_mfc_dirs):
424 """Return a 3-tuple of (INCLUDE, LIB, PATH) as the values of those
425 three environment variables that should be set in order to execute
426 the MSVC .NET tools properly, if the information wasn't available
427 from the registry."""
435 paths = SCons.Tool.msvs.get_msvs_install_dirs(version)
436 MVSdir = paths['VSINSTALLDIR']
437 except (KeyError, SCons.Util.RegError, SCons.Errors.InternalError):
438 if os.environ.has_key('VSCOMNTOOLS'):
439 MVSdir = os.path.normpath(os.path.join(os.environ['VSCOMNTOOLS'],'..','..'))
441 # last resort -- default install location
442 MVSdir = r'C:\Program Files\Microsoft Visual Studio .NET'
445 if SCons.Util.can_read_reg and paths.has_key('VCINSTALLDIR'):
446 MVSVCdir = paths['VCINSTALLDIR']
448 MVSVCdir = os.path.join(MVSdir,'Vc7')
450 MVSCommondir = r'%s\Common7' % MVSdir
452 mfc_include_ = r'%s\atlmfc\include;' % MVSVCdir
453 mfc_lib_ = r'%s\atlmfc\lib;' % MVSVCdir
457 include_path = r'%s%s\include;%s\PlatformSDK\include' % (mfc_include_, MVSVCdir, MVSVCdir)
458 lib_path = r'%s%s\lib;%s\PlatformSDK\lib' % (mfc_lib_, MVSVCdir, MVSVCdir)
459 exe_path = r'%s\IDE;%s\bin;%s\Tools;%s\Tools\bin' % (MVSCommondir,MVSVCdir, MVSCommondir, MVSCommondir )
461 if SCons.Util.can_read_reg and paths.has_key('FRAMEWORKSDKDIR'):
462 include_path = include_path + r';%s\include'%paths['FRAMEWORKSDKDIR']
463 lib_path = lib_path + r';%s\lib'%paths['FRAMEWORKSDKDIR']
464 exe_path = exe_path + r';%s\bin'%paths['FRAMEWORKSDKDIR']
466 if SCons.Util.can_read_reg and paths.has_key('FRAMEWORKDIR') and paths.has_key('FRAMEWORKVERSION'):
467 exe_path = exe_path + r';%s\%s'%(paths['FRAMEWORKDIR'],paths['FRAMEWORKVERSION'])
469 return (include_path, lib_path, exe_path)
471 def _get_msvc8_default_paths(env, version, suite, use_mfc_dirs):
472 """Return a 3-tuple of (INCLUDE, LIB, PATH) as the values of those
473 three environment variables that should be set in order to execute
474 the MSVC 8 tools properly, if the information wasn't available
475 from the registry."""
483 paths = SCons.Tool.msvs.get_msvs_install_dirs(version, suite)
484 MVSdir = paths['VSINSTALLDIR']
485 except (KeyError, SCons.Util.RegError, SCons.Errors.InternalError):
486 if os.environ.has_key('VSCOMNTOOLS'):
487 MVSdir = os.path.normpath(os.path.join(os.environ['VSCOMNTOOLS'],'..','..'))
489 # last resort -- default install location
490 MVSdir = os.getenv('ProgramFiles') + r'\Microsoft Visual Studio 8'
493 if SCons.Util.can_read_reg and paths.has_key('VCINSTALLDIR'):
494 MVSVCdir = paths['VCINSTALLDIR']
496 MVSVCdir = os.path.join(MVSdir,'VC')
498 MVSCommondir = os.path.join(MVSdir, 'Common7')
499 include_paths.append( os.path.join(MVSVCdir, 'include') )
500 lib_paths.append( os.path.join(MVSVCdir, 'lib') )
501 for base, subdir in [(MVSCommondir,'IDE'), (MVSVCdir,'bin'),
502 (MVSCommondir,'Tools'), (MVSCommondir,r'Tools\bin')]:
503 exe_paths.append( os.path.join( base, subdir) )
505 if paths.has_key('PLATFORMSDKDIR'):
506 PlatformSdkDir = paths['PLATFORMSDKDIR']
508 PlatformSdkDir = os.path.join(MVSVCdir,'PlatformSDK')
509 platform_include_path = os.path.join( PlatformSdkDir, 'Include' )
510 include_paths.append( platform_include_path )
511 lib_paths.append( os.path.join( PlatformSdkDir, 'Lib' ) )
513 if paths.has_key('PLATFORMSDKDIR'):
514 include_paths.append( os.path.join( platform_include_path, 'mfc' ) )
515 include_paths.append( os.path.join( platform_include_path, 'atl' ) )
517 atlmfc_path = os.path.join( MVSVCdir, 'atlmfc' )
518 include_paths.append( os.path.join( atlmfc_path, 'include' ) )
519 lib_paths.append( os.path.join( atlmfc_path, 'lib' ) )
521 if SCons.Util.can_read_reg and paths.has_key('FRAMEWORKSDKDIR'):
522 fwdir = paths['FRAMEWORKSDKDIR']
523 include_paths.append( os.path.join( fwdir, 'include' ) )
524 lib_paths.append( os.path.join( fwdir, 'lib' ) )
525 exe_paths.append( os.path.join( fwdir, 'bin' ) )
527 if SCons.Util.can_read_reg and paths.has_key('FRAMEWORKDIR') and paths.has_key('FRAMEWORKVERSION'):
528 exe_paths.append( os.path.join( paths['FRAMEWORKDIR'], paths['FRAMEWORKVERSION'] ) )
530 include_path = string.join( include_paths, os.pathsep )
531 lib_path = string.join(lib_paths, os.pathsep )
532 exe_path = string.join(exe_paths, os.pathsep )
533 return (include_path, lib_path, exe_path)
535 def get_msvc_paths(env, version=None, use_mfc_dirs=0):
536 """Return a 3-tuple of (INCLUDE, LIB, PATH) as the values
537 of those three environment variables that should be set
538 in order to execute the MSVC tools properly."""
544 versions = SCons.Tool.msvs.get_visualstudio_versions()
546 version = versions[0] #use highest version by default
550 # Some of the configured directories only
551 # appear if the user changes them from the default.
552 # Therefore, we'll see if we can get the path to the MSDev
553 # base installation from the registry and deduce the default
555 version_num, suite = SCons.Tool.msvs.msvs_parse_version(version)
556 if version_num >= 8.0:
557 suite = SCons.Tool.msvs.get_default_visualstudio8_suite(env)
558 defpaths = _get_msvc8_default_paths(env, version, suite, use_mfc_dirs)
559 elif version_num >= 7.0:
560 defpaths = _get_msvc7_default_paths(env, version, use_mfc_dirs)
562 defpaths = _get_msvc6_default_paths(version, use_mfc_dirs)
565 include_path = get_msvc_path(env, "include", version)
566 except (SCons.Util.RegError, SCons.Errors.InternalError):
567 include_path = defpaths[0]
570 lib_path = get_msvc_path(env, "lib", version)
571 except (SCons.Util.RegError, SCons.Errors.InternalError):
572 lib_path = defpaths[1]
575 exe_path = get_msvc_path(env, "path", version)
576 except (SCons.Util.RegError, SCons.Errors.InternalError):
577 exe_path = defpaths[2]
579 return (include_path, lib_path, exe_path)
581 def get_msvc_default_paths(env, version=None, use_mfc_dirs=0):
582 """Return a 3-tuple of (INCLUDE, LIB, PATH) as the values of those
583 three environment variables that should be set in order to execute
584 the MSVC tools properly. This will only return the default
585 locations for the tools, not the values used by MSVS in their
586 directory setup area. This can help avoid problems with different
587 developers having different settings, and should allow the tools
588 to run in most cases."""
590 if not version and not SCons.Util.can_read_reg:
595 version = SCons.Tool.msvs.get_visualstudio_versions()[0] #use highest version
596 except KeyboardInterrupt:
601 version_num, suite = SCons.Tool.msvs.msvs_parse_version(version)
602 if version_num >= 8.0:
603 suite = SCons.Tool.msvs.get_default_visualstudio8_suite(env)
604 return _get_msvc8_default_paths(env, version, suite, use_mfc_dirs)
605 elif version_num >= 7.0:
606 return _get_msvc7_default_paths(env, version, use_mfc_dirs)
608 return _get_msvc6_default_paths(version, use_mfc_dirs)
610 def validate_vars(env):
611 """Validate the PCH and PCHSTOP construction variables."""
612 if env.has_key('PCH') and env['PCH']:
613 if not env.has_key('PCHSTOP'):
614 raise SCons.Errors.UserError, "The PCHSTOP construction must be defined if PCH is defined."
615 if not SCons.Util.is_String(env['PCHSTOP']):
616 raise SCons.Errors.UserError, "The PCHSTOP construction variable must be a string: %r"%env['PCHSTOP']
618 def pch_emitter(target, source, env):
619 """Adds the object file target."""
627 if SCons.Util.splitext(str(t))[1] == '.pch':
629 if SCons.Util.splitext(str(t))[1] == '.obj':
633 obj = SCons.Util.splitext(str(pch))[0]+'.obj'
635 target = [pch, obj] # pch must be first, and obj second for the PCHCOM to work
637 return (target, source)
639 def object_emitter(target, source, env, parent_emitter):
640 """Sets up the PCH dependencies for an object file."""
644 parent_emitter(target, source, env)
646 if env.has_key('PCH') and env['PCH']:
647 env.Depends(target, env['PCH'])
649 return (target, source)
651 def static_object_emitter(target, source, env):
652 return object_emitter(target, source, env,
653 SCons.Defaults.StaticObjectEmitter)
655 def shared_object_emitter(target, source, env):
656 return object_emitter(target, source, env,
657 SCons.Defaults.SharedObjectEmitter)
659 pch_action = SCons.Action.Action('$PCHCOM', '$PCHCOMSTR')
660 pch_builder = SCons.Builder.Builder(action=pch_action, suffix='.pch',
662 source_scanner=SCons.Tool.SourceFileScanner)
663 res_action = SCons.Action.Action('$RCCOM', '$RCCOMSTR')
664 res_builder = SCons.Builder.Builder(action=res_action,
668 source_scanner=SCons.Tool.SourceFileScanner)
669 SCons.Tool.SourceFileScanner.add_scanner('.rc', SCons.Defaults.CScan)
672 """Add Builders and construction variables for MSVC++ to an Environment."""
673 static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
675 for suffix in CSuffixes:
676 static_obj.add_action(suffix, SCons.Defaults.CAction)
677 shared_obj.add_action(suffix, SCons.Defaults.ShCAction)
678 static_obj.add_emitter(suffix, static_object_emitter)
679 shared_obj.add_emitter(suffix, shared_object_emitter)
681 for suffix in CXXSuffixes:
682 static_obj.add_action(suffix, SCons.Defaults.CXXAction)
683 shared_obj.add_action(suffix, SCons.Defaults.ShCXXAction)
684 static_obj.add_emitter(suffix, static_object_emitter)
685 shared_obj.add_emitter(suffix, shared_object_emitter)
687 env['CCPDBFLAGS'] = SCons.Util.CLVar(['${(PDB and "/Z7") or ""}'])
688 env['CCPCHFLAGS'] = SCons.Util.CLVar(['${(PCH and "/Yu%s /Fp%s"%(PCHSTOP or "",File(PCH))) or ""}'])
689 env['_CCCOMCOM'] = '$CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS $CCPCHFLAGS $CCPDBFLAGS'
691 env['CCFLAGS'] = SCons.Util.CLVar('/nologo')
692 env['CFLAGS'] = SCons.Util.CLVar('')
693 env['CCCOM'] = '$CC /Fo$TARGET /c $SOURCES $CFLAGS $CCFLAGS $_CCCOMCOM'
695 env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS')
696 env['SHCFLAGS'] = SCons.Util.CLVar('$CFLAGS')
697 env['SHCCCOM'] = '$SHCC /Fo$TARGET /c $SOURCES $SHCFLAGS $SHCCFLAGS $_CCCOMCOM'
699 env['CXXFLAGS'] = SCons.Util.CLVar('$CCFLAGS $( /TP $)')
700 env['CXXCOM'] = '$CXX /Fo:$TARGET /c $SOURCES $CXXFLAGS $CCFLAGS $_CCCOMCOM'
701 env['SHCXX'] = '$CXX'
702 env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS')
703 env['SHCXXCOM'] = '$SHCXX /Fo:$TARGET /c $SOURCES $SHCXXFLAGS $SHCCFLAGS $_CCCOMCOM'
704 env['CPPDEFPREFIX'] = '/D'
705 env['CPPDEFSUFFIX'] = ''
706 env['INCPREFIX'] = '/I'
707 env['INCSUFFIX'] = ''
708 # env.Append(OBJEMITTER = [static_object_emitter])
709 # env.Append(SHOBJEMITTER = [shared_object_emitter])
710 env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1
713 env['RCFLAGS'] = SCons.Util.CLVar('')
714 env['RCCOM'] = '$RC $_CPPDEFFLAGS $_CPPINCFLAGS $RCFLAGS /fo$TARGET $SOURCES'
715 env['BUILDERS']['RES'] = res_builder
716 env['OBJPREFIX'] = ''
717 env['OBJSUFFIX'] = '.obj'
718 env['SHOBJPREFIX'] = '$OBJPREFIX'
719 env['SHOBJSUFFIX'] = '$OBJSUFFIX'
722 version = SCons.Tool.msvs.get_default_visualstudio_version(env)
723 version_num, suite = SCons.Tool.msvs.msvs_parse_version(version)
724 if version_num == 8.0:
725 suite = SCons.Tool.msvs.get_default_visualstudio8_suite(env)
727 use_mfc_dirs = env.get('MSVS_USE_MFC_DIRS', 0)
728 if env.get('MSVS_IGNORE_IDE_PATHS', 0):
729 _get_paths = get_msvc_default_paths
731 _get_paths = get_msvc_paths
732 include_path, lib_path, exe_path = _get_paths(env, version, use_mfc_dirs)
734 # since other tools can set these, we just make sure that the
735 # relevant stuff from MSVS is in there somewhere.
736 env.PrependENVPath('INCLUDE', include_path)
737 env.PrependENVPath('LIB', lib_path)
738 env.PrependENVPath('PATH', exe_path)
739 except (SCons.Util.RegError, SCons.Errors.InternalError):
742 env['CFILESUFFIX'] = '.c'
743 env['CXXFILESUFFIX'] = '.cc'
745 env['PCHPDBFLAGS'] = SCons.Util.CLVar(['${(PDB and "/Yd") or ""}'])
746 env['PCHCOM'] = '$CXX $CXXFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c $SOURCES /Fo${TARGETS[1]} /Yc$PCHSTOP /Fp${TARGETS[0]} $CCPDBFLAGS $PCHPDBFLAGS'
747 env['BUILDERS']['PCH'] = pch_builder
749 if not env.has_key('ENV'):
751 if not env['ENV'].has_key('SystemRoot'): # required for dlls in the winsxs folders
752 env['ENV']['SystemRoot'] = SCons.Platform.win32.get_system_root()
755 if SCons.Tool.msvs.is_msvs_installed():
756 # there's at least one version of MSVS installed.
759 return env.Detect('cl')