http://scons.tigris.org/issues/show_bug.cgi?id=2345
[scons.git] / src / engine / SCons / Tool / msvc.py
index 89768528614b5b0730c7efa492f062db26e72598..41e793aade6a7c5c807140c39bb95cedfa692f9e 100644 (file)
@@ -35,7 +35,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os.path
 import re
-import string
 import sys
 
 import SCons.Action
@@ -48,18 +47,18 @@ import SCons.Util
 import SCons.Warnings
 import SCons.Scanner.RC
 
-from MSCommon import msvc_exists, msvc_setup_env
+from MSCommon import msvc_exists, msvc_setup_env_once
 
 CSuffixes = ['.c', '.C']
 CXXSuffixes = ['.cc', '.cpp', '.cxx', '.c++', '.C++']
 
 def validate_vars(env):
     """Validate the PCH and PCHSTOP construction variables."""
-    if env.has_key('PCH') and env['PCH']:
-        if not env.has_key('PCHSTOP'):
-            raise SCons.Errors.UserError, "The PCHSTOP construction must be defined if PCH is defined."
+    if 'PCH' in env and env['PCH']:
+        if 'PCHSTOP' not in env:
+            raise SCons.Errors.UserError("The PCHSTOP construction must be defined if PCH is defined.")
         if not SCons.Util.is_String(env['PCHSTOP']):
-            raise SCons.Errors.UserError, "The PCHSTOP construction variable must be a string: %r"%env['PCHSTOP']
+            raise SCons.Errors.UserError("The PCHSTOP construction variable must be a string: %r"%env['PCHSTOP'])
 
 def pch_emitter(target, source, env):
     """Adds the object file target."""
@@ -89,8 +88,20 @@ def object_emitter(target, source, env, parent_emitter):
 
     parent_emitter(target, source, env)
 
-    if env.has_key('PCH') and env['PCH']:
-        env.Depends(target, env['PCH'])
+    # Add a dependency, but only if the target (e.g. 'Source1.obj')
+    # doesn't correspond to the pre-compiled header ('Source1.pch').
+    # If the basenames match, then this was most likely caused by
+    # someone adding the source file to both the env.PCH() and the
+    # env.Program() calls, and adding the explicit dependency would
+    # cause a cycle on the .pch file itself.
+    #
+    # See issue #2505 for a discussion of what to do if it turns
+    # out this assumption causes trouble in the wild:
+    # http://scons.tigris.org/issues/show_bug.cgi?id=2505
+    if 'PCH' in env:
+        pch = env['PCH']
+        if str(target[0]) != SCons.Util.splitext(str(pch))[0] + '.obj':
+            env.Depends(target, pch)
 
     return (target, source)
 
@@ -232,11 +243,8 @@ def generate(env):
     env['SHOBJPREFIX']    = '$OBJPREFIX'
     env['SHOBJSUFFIX']    = '$OBJSUFFIX'
 
-    # Set-up ms tools paths for default version
-    msvc_setup_env(env)
-
-    import mssdk
-    mssdk.generate(env)
+    # Set-up ms tools paths
+    msvc_setup_env_once(env)
 
     env['CFILESUFFIX'] = '.c'
     env['CXXFILESUFFIX'] = '.cc'
@@ -245,13 +253,13 @@ def generate(env):
     env['PCHCOM'] = '$CXX /Fo${TARGETS[1]} $CXXFLAGS $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c $SOURCES /Yc$PCHSTOP /Fp${TARGETS[0]} $CCPDBFLAGS $PCHPDBFLAGS'
     env['BUILDERS']['PCH'] = pch_builder
 
-    if not env.has_key('ENV'):
+    if 'ENV' not in env:
         env['ENV'] = {}
-    if not env['ENV'].has_key('SystemRoot'):    # required for dlls in the winsxs folders
+    if 'SystemRoot' not in env['ENV']:    # required for dlls in the winsxs folders
         env['ENV']['SystemRoot'] = SCons.Platform.win32.get_system_root()
 
 def exists(env):
-    return msvc_exists('cl')
+    return msvc_exists()
 
 # Local Variables:
 # tab-width:4