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()
12 # Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
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__ = "src/engine/SCons/Tool/msvc.py 3842 2008/12/20 22:59:52 scons"
43 import SCons.Platform.win32
45 import SCons.Tool.msvs
48 import SCons.Scanner.RC
50 CSuffixes = ['.c', '.C']
51 CXXSuffixes = ['.cc', '.cpp', '.cxx', '.c++', '.C++']
53 def _parse_msvc7_overrides(version,platform):
54 """ Parse any overridden defaults for MSVS directory locations
57 # First, we get the shell folder for this user:
58 if not SCons.Util.can_read_reg:
59 raise SCons.Errors.InternalError, "No Windows registry module was found"
63 (comps, t) = SCons.Util.RegGetValue(SCons.Util.HKEY_CURRENT_USER,
64 r'Software\Microsoft\Windows\CurrentVersion' +\
65 r'\Explorer\Shell Folders\Local AppData')
66 except SCons.Util.RegError:
67 raise SCons.Errors.InternalError, \
68 "The Local AppData directory was not found in the registry."
70 comps = comps + '\\Microsoft\\VisualStudio\\' + version + '\\VCComponents.dat'
73 if os.path.exists(comps):
74 # now we parse the directories from this file, if it exists.
75 # We only look for entries after:
76 # [VC\VC_OBJECTS_PLATFORM_INFO\Win32\Directories],
77 # since this file could contain a number of things...
85 f = codecs.open(comps, 'r', 'utf16')
86 encoder = codecs.getencoder('ascii')
87 lines = map(lambda l, e=encoder: e(l)[0], f.readlines())
88 except (LookupError, UnicodeError):
89 lines = codecs.open(comps, 'r', 'utf8').readlines()
91 lines = open(comps, 'r').readlines()
92 if 'x86' == platform: platform = 'Win32'
97 if line.find(r'[VC\VC_OBJECTS_PLATFORM_INFO\%s\Directories]'%platform) >= 0:
99 elif line == '' or line[:1] == '[':
102 kv = line.split('=', 1)
105 key = key.replace(' Dirs','')
106 dirs[key.upper()] = val
109 # since the file didn't exist, we have only the defaults in
110 # the registry to work with.
112 if 'x86' == platform: platform = 'Win32'
115 K = 'SOFTWARE\\Microsoft\\VisualStudio\\' + version
116 K = K + r'\VC\VC_OBJECTS_PLATFORM_INFO\%s\Directories'%platform
117 k = SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE,K)
121 (key,val,t) = SCons.Util.RegEnumValue(k,i)
122 key = key.replace(' Dirs','')
123 dirs[key.upper()] = val
125 except SCons.Util.RegError:
127 except SCons.Util.RegError:
128 # if we got here, then we didn't find the registry entries:
129 raise SCons.Errors.InternalError, "Unable to find MSVC paths in the registry."
132 def _parse_msvc8_overrides(version,platform,suite):
133 """ Parse any overridden defaults for MSVC directory locations
136 # In VS8 the user can change the location of the settings file that
137 # contains the include, lib and binary paths. Try to get the location
139 if not SCons.Util.can_read_reg:
140 raise SCons.Errors.InternalError, "No Windows registry module was found"
142 # XXX This code assumes anything that isn't EXPRESS uses the default
143 # registry key string. Is this really true for all VS suites?
144 if suite == 'EXPRESS':
147 s = '\\VisualStudio\\'
151 (settings_path, t) = SCons.Util.RegGetValue(SCons.Util.HKEY_CURRENT_USER,
152 r'Software\Microsoft' + s + version +\
153 r'\Profile\AutoSaveFile')
154 settings_path = settings_path.upper()
155 except SCons.Util.RegError:
156 raise SCons.Errors.InternalError, \
157 "The VS8 settings file location was not found in the registry."
159 # Look for potential environment variables in the settings path
160 if settings_path.find('%VSSPV_VISUALSTUDIO_DIR%') >= 0:
161 # First replace a special variable named %vsspv_visualstudio_dir%
162 # that is not found in the OSs environment variables...
164 (value, t) = SCons.Util.RegGetValue(SCons.Util.HKEY_CURRENT_USER,
165 r'Software\Microsoft' + s + version +\
166 r'\VisualStudioLocation')
167 settings_path = settings_path.replace('%VSSPV_VISUALSTUDIO_DIR%', value)
168 except SCons.Util.RegError:
169 raise SCons.Errors.InternalError, "The VS8 settings file location was not found in the registry."
171 if settings_path.find('%') >= 0:
172 # Collect global environment variables
175 # Read all the global environment variables of the current user
176 k = SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_CURRENT_USER, r'Environment')
180 (key,val,t) = SCons.Util.RegEnumValue(k,i)
181 env_vars[key.upper()] = val.upper()
183 except SCons.Util.RegError:
186 # And some more variables that are not found in the registry
187 env_vars['USERPROFILE'] = os.getenv('USERPROFILE')
188 env_vars['SystemDrive'] = os.getenv('SystemDrive')
193 for env_var in env_vars:
194 if settings_path.find(r'%' + env_var + r'%') >= 0:
195 settings_path = settings_path.replace(r'%' + env_var + r'%', env_vars[env_var])
200 if os.path.exists(settings_path):
201 # now we parse the directories from this file, if it exists.
202 import xml.dom.minidom
203 doc = xml.dom.minidom.parse(settings_path)
204 user_settings = doc.getElementsByTagName('UserSettings')[0]
205 tool_options = user_settings.getElementsByTagName('ToolsOptions')[0]
206 tool_options_categories = tool_options.getElementsByTagName('ToolsOptionsCategory')
207 environment_var_map = {
208 'IncludeDirectories' : 'INCLUDE',
209 'LibraryDirectories' : 'LIBRARY',
210 'ExecutableDirectories' : 'PATH',
212 for category in tool_options_categories:
213 category_name = category.attributes.get('name')
214 if category_name is not None and category_name.value == 'Projects':
215 subcategories = category.getElementsByTagName('ToolsOptionsSubCategory')
216 for subcategory in subcategories:
217 subcategory_name = subcategory.attributes.get('name')
218 if subcategory_name is not None and subcategory_name.value == 'VCDirectories':
219 properties = subcategory.getElementsByTagName('PropertyValue')
220 for property in properties:
221 property_name = property.attributes.get('name')
222 if property_name is None:
224 var_name = environment_var_map.get(property_name)
226 data = property.childNodes[0].data
227 value_list = string.split(data, '|')
228 if len(value_list) == 1:
229 dirs[var_name] = value_list[0]
232 dest, value = value_list[:2]
234 # ToDo: Support for destinations
237 dirs[var_name] = value
240 # There are no default directories in the registry for VS8 Express :(
241 raise SCons.Errors.InternalError, "Unable to find MSVC paths in the registry."
244 def _get_msvc7_path(path, version, platform):
246 Get Visual Studio directories from version 7 (MSVS .NET)
247 (it has a different registry structure than versions before it)
249 # first, look for a customization of the default values in the
250 # registry: These are sometimes stored in the Local Settings area
251 # for Visual Studio, in a file, so we have to parse it.
252 dirs = _parse_msvc7_overrides(version,platform)
254 if dirs.has_key(path):
257 raise SCons.Errors.InternalError, \
258 "Unable to retrieve the %s path from MS VC++."%path
260 # collect some useful information for later expansions...
261 paths = SCons.Tool.msvs.get_msvs_install_dirs(version)
263 # expand the directory path variables that we support. If there
264 # is a variable we don't support, then replace that entry with
265 # "---Unknown Location VSInstallDir---" or something similar, to clue
266 # people in that we didn't find something, and so env expansion doesn't
267 # do weird things with the $(xxx)'s
268 s = re.compile('\$\(([a-zA-Z0-9_]+?)\)')
270 def repl(match, paths=paths):
271 key = string.upper(match.group(1))
272 if paths.has_key(key):
275 # Now look in the global environment variables
276 envresult = os.getenv(key)
277 if not envresult is None:
278 return envresult + '\\'
280 return '---Unknown Location %s---' % match.group()
283 for entry in p.split(os.pathsep):
284 entry = s.sub(repl,entry).rstrip('\n\r')
287 return string.join(rv,os.pathsep)
289 def _get_msvc8_path(path, version, platform, suite):
291 Get Visual Studio directories from version 8 (MSVS 2005)
292 (it has a different registry structure than versions before it)
294 # first, look for a customization of the default values in the
295 # registry: These are sometimes stored in the Local Settings area
296 # for Visual Studio, in a file, so we have to parse it.
297 dirs = _parse_msvc8_overrides(version, platform, suite)
299 if dirs.has_key(path):
302 raise SCons.Errors.InternalError, \
303 "Unable to retrieve the %s path from MS VC++."%path
305 # collect some useful information for later expansions...
306 paths = SCons.Tool.msvs.get_msvs_install_dirs(version, suite)
308 # expand the directory path variables that we support. If there
309 # is a variable we don't support, then replace that entry with
310 # "---Unknown Location VSInstallDir---" or something similar, to clue
311 # people in that we didn't find something, and so env expansion doesn't
312 # do weird things with the $(xxx)'s
313 s = re.compile('\$\(([a-zA-Z0-9_]+?)\)')
315 def repl(match, paths=paths):
316 key = string.upper(match.group(1))
317 if paths.has_key(key):
320 return '---Unknown Location %s---' % match.group()
323 for entry in p.split(os.pathsep):
324 entry = s.sub(repl,entry).rstrip('\n\r')
327 return string.join(rv,os.pathsep)
329 def get_msvc_path(env, path, version):
331 Get a list of visualstudio directories (include, lib or path).
332 Return a string delimited by the os.pathsep separator (';'). An
333 exception will be raised if unable to access the registry or
334 appropriate registry keys not found.
337 if not SCons.Util.can_read_reg:
338 raise SCons.Errors.InternalError, "No Windows registry module was found"
340 # normalize the case for comparisons (since the registry is case
342 path = string.upper(path)
347 version_num, suite = SCons.Tool.msvs.msvs_parse_version(version)
348 if version_num >= 8.0:
349 platform = env.get('MSVS8_PLATFORM', 'x86')
350 suite = SCons.Tool.msvs.get_default_visualstudio8_suite(env)
354 if version_num >= 8.0:
355 return _get_msvc8_path(path, str(version_num), platform, suite)
356 elif version_num >= 7.0:
357 return _get_msvc7_path(path, str(version_num), platform)
359 path = string.upper(path + ' Dirs')
360 K = ('Software\\Microsoft\\Devstudio\\%s\\' +
361 'Build System\\Components\\Platforms\\Win32 (x86)\\Directories') % \
363 for base in (SCons.Util.HKEY_CURRENT_USER,
364 SCons.Util.HKEY_LOCAL_MACHINE):
366 k = SCons.Util.RegOpenKeyEx(base,K)
370 (p,v,t) = SCons.Util.RegEnumValue(k,i)
371 if string.upper(p) == path:
374 except SCons.Util.RegError:
376 except SCons.Util.RegError:
379 # if we got here, then we didn't find the registry entries:
380 raise SCons.Errors.InternalError, "The %s path was not found in the registry."%path
382 def _get_msvc6_default_paths(version, use_mfc_dirs):
383 """Return a 3-tuple of (INCLUDE, LIB, PATH) as the values of those
384 three environment variables that should be set in order to execute
385 the MSVC 6.0 tools properly, if the information wasn't available
386 from the registry."""
393 paths = SCons.Tool.msvs.get_msvs_install_dirs(version)
394 MVSdir = paths['VSINSTALLDIR']
395 except (SCons.Util.RegError, SCons.Errors.InternalError, KeyError):
396 if os.environ.has_key('MSDEVDIR'):
397 MVSdir = os.path.normpath(os.path.join(os.environ['MSDEVDIR'],'..','..'))
399 MVSdir = r'C:\Program Files\Microsoft Visual Studio'
401 if SCons.Util.can_read_reg and paths.has_key('VCINSTALLDIR'):
402 MVSVCdir = paths['VCINSTALLDIR']
404 MVSVCdir = os.path.join(MVSdir,'VC98')
406 MVSCommondir = r'%s\Common' % MVSdir
408 mfc_include_ = r'%s\ATL\include;%s\MFC\include;' % (MVSVCdir, MVSVCdir)
409 mfc_lib_ = r'%s\MFC\lib;' % MVSVCdir
413 include_path = r'%s%s\include' % (mfc_include_, MVSVCdir)
414 lib_path = r'%s%s\lib' % (mfc_lib_, MVSVCdir)
416 if os.environ.has_key('OS') and os.environ['OS'] == "Windows_NT":
421 exe_path = r'%s\tools\%s;%s\MSDev98\bin;%s\tools;%s\bin' % (MVSCommondir, osdir, MVSCommondir, MVSCommondir, MVSVCdir)
422 return (include_path, lib_path, exe_path)
424 def _get_msvc7_default_paths(env, version, use_mfc_dirs):
425 """Return a 3-tuple of (INCLUDE, LIB, PATH) as the values of those
426 three environment variables that should be set in order to execute
427 the MSVC .NET tools properly, if the information wasn't available
428 from the registry."""
436 paths = SCons.Tool.msvs.get_msvs_install_dirs(version)
437 MVSdir = paths['VSINSTALLDIR']
438 except (KeyError, SCons.Util.RegError, SCons.Errors.InternalError):
439 if os.environ.has_key('VSCOMNTOOLS'):
440 MVSdir = os.path.normpath(os.path.join(os.environ['VSCOMNTOOLS'],'..','..'))
442 # last resort -- default install location
443 MVSdir = r'C:\Program Files\Microsoft Visual Studio .NET'
446 if SCons.Util.can_read_reg and paths.has_key('VCINSTALLDIR'):
447 MVSVCdir = paths['VCINSTALLDIR']
449 MVSVCdir = os.path.join(MVSdir,'Vc7')
451 MVSCommondir = r'%s\Common7' % MVSdir
453 mfc_include_ = r'%s\atlmfc\include;' % MVSVCdir
454 mfc_lib_ = r'%s\atlmfc\lib;' % MVSVCdir
458 include_path = r'%s%s\include;%s\PlatformSDK\include' % (mfc_include_, MVSVCdir, MVSVCdir)
459 lib_path = r'%s%s\lib;%s\PlatformSDK\lib' % (mfc_lib_, MVSVCdir, MVSVCdir)
460 exe_path = r'%s\IDE;%s\bin;%s\Tools;%s\Tools\bin' % (MVSCommondir,MVSVCdir, MVSCommondir, MVSCommondir )
462 if SCons.Util.can_read_reg and paths.has_key('FRAMEWORKSDKDIR'):
463 include_path = include_path + r';%s\include'%paths['FRAMEWORKSDKDIR']
464 lib_path = lib_path + r';%s\lib'%paths['FRAMEWORKSDKDIR']
465 exe_path = exe_path + r';%s\bin'%paths['FRAMEWORKSDKDIR']
467 if SCons.Util.can_read_reg and paths.has_key('FRAMEWORKDIR') and paths.has_key('FRAMEWORKVERSION'):
468 exe_path = exe_path + r';%s\%s'%(paths['FRAMEWORKDIR'],paths['FRAMEWORKVERSION'])
470 return (include_path, lib_path, exe_path)
472 def _get_msvc8_default_paths(env, version, suite, use_mfc_dirs):
473 """Return a 3-tuple of (INCLUDE, LIB, PATH) as the values of those
474 three environment variables that should be set in order to execute
475 the MSVC 8 tools properly, if the information wasn't available
476 from the registry."""
484 paths = SCons.Tool.msvs.get_msvs_install_dirs(version, suite)
485 MVSdir = paths['VSINSTALLDIR']
486 except (KeyError, SCons.Util.RegError, SCons.Errors.InternalError):
487 if os.environ.has_key('VSCOMNTOOLS'):
488 MVSdir = os.path.normpath(os.path.join(os.environ['VSCOMNTOOLS'],'..','..'))
490 # last resort -- default install location
491 MVSdir = os.getenv('ProgramFiles') + r'\Microsoft Visual Studio 8'
494 if SCons.Util.can_read_reg and paths.has_key('VCINSTALLDIR'):
495 MVSVCdir = paths['VCINSTALLDIR']
497 MVSVCdir = os.path.join(MVSdir,'VC')
499 MVSCommondir = os.path.join(MVSdir, 'Common7')
500 include_paths.append( os.path.join(MVSVCdir, 'include') )
501 lib_paths.append( os.path.join(MVSVCdir, 'lib') )
502 for base, subdir in [(MVSCommondir,'IDE'), (MVSVCdir,'bin'),
503 (MVSCommondir,'Tools'), (MVSCommondir,r'Tools\bin')]:
504 exe_paths.append( os.path.join( base, subdir) )
506 if paths.has_key('PLATFORMSDKDIR'):
507 PlatformSdkDir = paths['PLATFORMSDKDIR']
509 PlatformSdkDir = os.path.join(MVSVCdir,'PlatformSDK')
510 platform_include_path = os.path.join( PlatformSdkDir, 'Include' )
511 include_paths.append( platform_include_path )
512 lib_paths.append( os.path.join( PlatformSdkDir, 'Lib' ) )
514 if paths.has_key('PLATFORMSDKDIR'):
515 include_paths.append( os.path.join( platform_include_path, 'mfc' ) )
516 include_paths.append( os.path.join( platform_include_path, 'atl' ) )
518 atlmfc_path = os.path.join( MVSVCdir, 'atlmfc' )
519 include_paths.append( os.path.join( atlmfc_path, 'include' ) )
520 lib_paths.append( os.path.join( atlmfc_path, 'lib' ) )
522 if SCons.Util.can_read_reg and paths.has_key('FRAMEWORKSDKDIR'):
523 fwdir = paths['FRAMEWORKSDKDIR']
524 include_paths.append( os.path.join( fwdir, 'include' ) )
525 lib_paths.append( os.path.join( fwdir, 'lib' ) )
526 exe_paths.append( os.path.join( fwdir, 'bin' ) )
528 if SCons.Util.can_read_reg and paths.has_key('FRAMEWORKDIR') and paths.has_key('FRAMEWORKVERSION'):
529 exe_paths.append( os.path.join( paths['FRAMEWORKDIR'], paths['FRAMEWORKVERSION'] ) )
531 include_path = string.join( include_paths, os.pathsep )
532 lib_path = string.join(lib_paths, os.pathsep )
533 exe_path = string.join(exe_paths, os.pathsep )
534 return (include_path, lib_path, exe_path)
536 def get_msvc_paths(env, version=None, use_mfc_dirs=0):
537 """Return a 3-tuple of (INCLUDE, LIB, PATH) as the values
538 of those three environment variables that should be set
539 in order to execute the MSVC tools properly."""
545 versions = SCons.Tool.msvs.get_visualstudio_versions()
547 version = versions[0] #use highest version by default
551 # Some of the configured directories only
552 # appear if the user changes them from the default.
553 # Therefore, we'll see if we can get the path to the MSDev
554 # base installation from the registry and deduce the default
556 version_num, suite = SCons.Tool.msvs.msvs_parse_version(version)
557 if version_num >= 8.0:
558 suite = SCons.Tool.msvs.get_default_visualstudio8_suite(env)
559 defpaths = _get_msvc8_default_paths(env, version, suite, use_mfc_dirs)
560 elif version_num >= 7.0:
561 defpaths = _get_msvc7_default_paths(env, version, use_mfc_dirs)
563 defpaths = _get_msvc6_default_paths(version, use_mfc_dirs)
566 include_path = get_msvc_path(env, "include", version)
567 except (SCons.Util.RegError, SCons.Errors.InternalError):
568 include_path = defpaths[0]
571 lib_path = get_msvc_path(env, "lib", version)
572 except (SCons.Util.RegError, SCons.Errors.InternalError):
573 lib_path = defpaths[1]
576 exe_path = get_msvc_path(env, "path", version)
577 except (SCons.Util.RegError, SCons.Errors.InternalError):
578 exe_path = defpaths[2]
580 return (include_path, lib_path, exe_path)
582 def get_msvc_default_paths(env, version=None, use_mfc_dirs=0):
583 """Return a 3-tuple of (INCLUDE, LIB, PATH) as the values of those
584 three environment variables that should be set in order to execute
585 the MSVC tools properly. This will only return the default
586 locations for the tools, not the values used by MSVS in their
587 directory setup area. This can help avoid problems with different
588 developers having different settings, and should allow the tools
589 to run in most cases."""
591 if not version and not SCons.Util.can_read_reg:
596 version = SCons.Tool.msvs.get_visualstudio_versions()[0] #use highest version
597 except KeyboardInterrupt:
602 version_num, suite = SCons.Tool.msvs.msvs_parse_version(version)
603 if version_num >= 8.0:
604 suite = SCons.Tool.msvs.get_default_visualstudio8_suite(env)
605 return _get_msvc8_default_paths(env, version, suite, use_mfc_dirs)
606 elif version_num >= 7.0:
607 return _get_msvc7_default_paths(env, version, use_mfc_dirs)
609 return _get_msvc6_default_paths(version, use_mfc_dirs)
611 def validate_vars(env):
612 """Validate the PCH and PCHSTOP construction variables."""
613 if env.has_key('PCH') and env['PCH']:
614 if not env.has_key('PCHSTOP'):
615 raise SCons.Errors.UserError, "The PCHSTOP construction must be defined if PCH is defined."
616 if not SCons.Util.is_String(env['PCHSTOP']):
617 raise SCons.Errors.UserError, "The PCHSTOP construction variable must be a string: %r"%env['PCHSTOP']
619 def pch_emitter(target, source, env):
620 """Adds the object file target."""
628 if SCons.Util.splitext(str(t))[1] == '.pch':
630 if SCons.Util.splitext(str(t))[1] == '.obj':
634 obj = SCons.Util.splitext(str(pch))[0]+'.obj'
636 target = [pch, obj] # pch must be first, and obj second for the PCHCOM to work
638 return (target, source)
640 def object_emitter(target, source, env, parent_emitter):
641 """Sets up the PCH dependencies for an object file."""
645 parent_emitter(target, source, env)
647 if env.has_key('PCH') and env['PCH']:
648 env.Depends(target, env['PCH'])
650 return (target, source)
652 def static_object_emitter(target, source, env):
653 return object_emitter(target, source, env,
654 SCons.Defaults.StaticObjectEmitter)
656 def shared_object_emitter(target, source, env):
657 return object_emitter(target, source, env,
658 SCons.Defaults.SharedObjectEmitter)
660 pch_action = SCons.Action.Action('$PCHCOM', '$PCHCOMSTR')
661 pch_builder = SCons.Builder.Builder(action=pch_action, suffix='.pch',
663 source_scanner=SCons.Tool.SourceFileScanner)
666 # Logic to build .rc files into .res files (resource files)
667 res_scanner = SCons.Scanner.RC.RCScan()
668 res_action = SCons.Action.Action('$RCCOM', '$RCCOMSTR')
669 res_builder = SCons.Builder.Builder(action=res_action,
673 source_scanner=res_scanner)
677 """Add Builders and construction variables for MSVC++ to an Environment."""
678 static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
680 for suffix in CSuffixes:
681 static_obj.add_action(suffix, SCons.Defaults.CAction)
682 shared_obj.add_action(suffix, SCons.Defaults.ShCAction)
683 static_obj.add_emitter(suffix, static_object_emitter)
684 shared_obj.add_emitter(suffix, shared_object_emitter)
686 for suffix in CXXSuffixes:
687 static_obj.add_action(suffix, SCons.Defaults.CXXAction)
688 shared_obj.add_action(suffix, SCons.Defaults.ShCXXAction)
689 static_obj.add_emitter(suffix, static_object_emitter)
690 shared_obj.add_emitter(suffix, shared_object_emitter)
692 env['CCPDBFLAGS'] = SCons.Util.CLVar(['${(PDB and "/Z7") or ""}'])
693 env['CCPCHFLAGS'] = SCons.Util.CLVar(['${(PCH and "/Yu%s /Fp%s"%(PCHSTOP or "",File(PCH))) or ""}'])
694 env['_CCCOMCOM'] = '$CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS $CCPCHFLAGS $CCPDBFLAGS'
696 env['CCFLAGS'] = SCons.Util.CLVar('/nologo')
697 env['CFLAGS'] = SCons.Util.CLVar('')
698 env['CCCOM'] = '$CC /Fo$TARGET /c $SOURCES $CFLAGS $CCFLAGS $_CCCOMCOM'
700 env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS')
701 env['SHCFLAGS'] = SCons.Util.CLVar('$CFLAGS')
702 env['SHCCCOM'] = '$SHCC /Fo$TARGET /c $SOURCES $SHCFLAGS $SHCCFLAGS $_CCCOMCOM'
704 env['CXXFLAGS'] = SCons.Util.CLVar('$CCFLAGS $( /TP $)')
705 env['CXXCOM'] = '$CXX /Fo$TARGET /c $SOURCES $CXXFLAGS $CCFLAGS $_CCCOMCOM'
706 env['SHCXX'] = '$CXX'
707 env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS')
708 env['SHCXXCOM'] = '$SHCXX /Fo$TARGET /c $SOURCES $SHCXXFLAGS $SHCCFLAGS $_CCCOMCOM'
709 env['CPPDEFPREFIX'] = '/D'
710 env['CPPDEFSUFFIX'] = ''
711 env['INCPREFIX'] = '/I'
712 env['INCSUFFIX'] = ''
713 # env.Append(OBJEMITTER = [static_object_emitter])
714 # env.Append(SHOBJEMITTER = [shared_object_emitter])
715 env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1
718 env['RCFLAGS'] = SCons.Util.CLVar('')
719 env['RCSUFFIXES']=['.rc','.rc2']
720 env['RCCOM'] = '$RC $_CPPDEFFLAGS $_CPPINCFLAGS $RCFLAGS /fo$TARGET $SOURCES'
721 env['BUILDERS']['RES'] = res_builder
722 env['OBJPREFIX'] = ''
723 env['OBJSUFFIX'] = '.obj'
724 env['SHOBJPREFIX'] = '$OBJPREFIX'
725 env['SHOBJSUFFIX'] = '$OBJSUFFIX'
728 version = SCons.Tool.msvs.get_default_visualstudio_version(env)
729 version_num, suite = SCons.Tool.msvs.msvs_parse_version(version)
730 if version_num == 8.0:
731 suite = SCons.Tool.msvs.get_default_visualstudio8_suite(env)
733 use_mfc_dirs = env.get('MSVS_USE_MFC_DIRS', 0)
734 if env.get('MSVS_IGNORE_IDE_PATHS', 0):
735 _get_paths = get_msvc_default_paths
737 _get_paths = get_msvc_paths
738 include_path, lib_path, exe_path = _get_paths(env, version, use_mfc_dirs)
740 # since other tools can set these, we just make sure that the
741 # relevant stuff from MSVS is in there somewhere.
742 env.PrependENVPath('INCLUDE', include_path)
743 env.PrependENVPath('LIB', lib_path)
744 env.PrependENVPath('PATH', exe_path)
745 except (SCons.Util.RegError, SCons.Errors.InternalError):
748 env['CFILESUFFIX'] = '.c'
749 env['CXXFILESUFFIX'] = '.cc'
751 env['PCHPDBFLAGS'] = SCons.Util.CLVar(['${(PDB and "/Yd") or ""}'])
752 env['PCHCOM'] = '$CXX $CXXFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c $SOURCES /Fo${TARGETS[1]} /Yc$PCHSTOP /Fp${TARGETS[0]} $CCPDBFLAGS $PCHPDBFLAGS'
753 env['BUILDERS']['PCH'] = pch_builder
755 if not env.has_key('ENV'):
757 if not env['ENV'].has_key('SystemRoot'): # required for dlls in the winsxs folders
758 env['ENV']['SystemRoot'] = SCons.Platform.win32.get_system_root()
761 if SCons.Tool.msvs.is_msvs_installed():
762 # there's at least one version of MSVS installed.
765 return env.Detect('cl')