Index: third_party/scons/scons-local/SCons/Tool/msvc.py |
=================================================================== |
--- third_party/scons/scons-local/SCons/Tool/msvc.py (revision 9094) |
+++ third_party/scons/scons-local/SCons/Tool/msvc.py (working copy) |
@@ -9,7 +9,7 @@ |
""" |
# |
-# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation |
+# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation |
# |
# Permission is hereby granted, free of charge, to any person obtaining |
# a copy of this software and associated documentation files (the |
@@ -31,7 +31,7 @@ |
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
# |
-__revision__ = "src/engine/SCons/Tool/msvc.py 3842 2008/12/20 22:59:52 scons" |
+__revision__ = "src/engine/SCons/Tool/msvc.py 3897 2009/01/13 06:45:54 scons" |
import os.path |
import re |
@@ -672,40 +672,103 @@ |
src_builder=[], |
source_scanner=res_scanner) |
+def msvc_batch_key(action, env, target, source): |
+ """ |
+ Returns a key to identify unique batches of sources for compilation. |
+ If batching is enabled (via the $MSVC_BATCH setting), then all |
+ target+source pairs that use the same action, defined by the same |
+ environment, and have the same target and source directories, will |
+ be batched. |
+ |
+ Returning None specifies that the specified target+source should not |
+ be batched with other compilations. |
+ """ |
+ b = env.subst('$MSVC_BATCH') |
+ if b in (None, '', '0'): |
+ # We're not using batching; return no key. |
+ return None |
+ t = target[0] |
+ s = source[0] |
+ if os.path.splitext(t.name)[0] != os.path.splitext(s.name)[0]: |
+ # The base names are different, so this *must* be compiled |
+ # separately; return no key. |
+ return None |
+ return (id(action), id(env), t.dir, s.dir) |
+ |
+def msvc_output_flag(target, source, env, for_signature): |
+ """ |
+ Returns the correct /Fo flag for batching. |
+ |
+ If batching is disabled or there's only one source file, then we |
+ return an /Fo string that specifies the target explicitly. Otherwise, |
+ we return an /Fo string that just specifies the first target's |
+ directory (where the Visual C/C++ compiler will put the .obj files). |
+ """ |
+ b = env.subst('$MSVC_BATCH') |
+ if b in (None, '', '0') or len(source) == 1: |
+ return '/Fo$TARGET' |
+ else: |
+ # The Visual C/C++ compiler requires a \ at the end of the /Fo |
+ # option to indicate an output directory. We use os.sep here so |
+ # that the test(s) for this can be run on non-Windows systems |
+ # without having a hard-coded backslash mess up command-line |
+ # argument parsing. |
+ return '/Fo${TARGET.dir}' + os.sep |
+ |
+CAction = SCons.Action.Action("$CCCOM", "$CCCOMSTR", |
+ batch_key=msvc_batch_key, |
+ targets='$CHANGED_TARGETS') |
+ShCAction = SCons.Action.Action("$SHCCCOM", "$SHCCCOMSTR", |
+ batch_key=msvc_batch_key, |
+ targets='$CHANGED_TARGETS') |
+CXXAction = SCons.Action.Action("$CXXCOM", "$CXXCOMSTR", |
+ batch_key=msvc_batch_key, |
+ targets='$CHANGED_TARGETS') |
+ShCXXAction = SCons.Action.Action("$SHCXXCOM", "$SHCXXCOMSTR", |
+ batch_key=msvc_batch_key, |
+ targets='$CHANGED_TARGETS') |
+ |
def generate(env): |
"""Add Builders and construction variables for MSVC++ to an Environment.""" |
static_obj, shared_obj = SCons.Tool.createObjBuilders(env) |
+ # TODO(batch): shouldn't reach in to cmdgen this way; necessary |
+ # for now to bypass the checks in Builder.DictCmdGenerator.__call__() |
+ # and allow .cc and .cpp to be compiled in the same command line. |
+ static_obj.cmdgen.source_ext_match = False |
+ shared_obj.cmdgen.source_ext_match = False |
+ |
for suffix in CSuffixes: |
- static_obj.add_action(suffix, SCons.Defaults.CAction) |
- shared_obj.add_action(suffix, SCons.Defaults.ShCAction) |
+ static_obj.add_action(suffix, CAction) |
+ shared_obj.add_action(suffix, ShCAction) |
static_obj.add_emitter(suffix, static_object_emitter) |
shared_obj.add_emitter(suffix, shared_object_emitter) |
for suffix in CXXSuffixes: |
- static_obj.add_action(suffix, SCons.Defaults.CXXAction) |
- shared_obj.add_action(suffix, SCons.Defaults.ShCXXAction) |
+ static_obj.add_action(suffix, CXXAction) |
+ shared_obj.add_action(suffix, ShCXXAction) |
static_obj.add_emitter(suffix, static_object_emitter) |
shared_obj.add_emitter(suffix, shared_object_emitter) |
env['CCPDBFLAGS'] = SCons.Util.CLVar(['${(PDB and "/Z7") or ""}']) |
env['CCPCHFLAGS'] = SCons.Util.CLVar(['${(PCH and "/Yu%s /Fp%s"%(PCHSTOP or "",File(PCH))) or ""}']) |
+ env['_MSVC_OUTPUT_FLAG'] = msvc_output_flag |
env['_CCCOMCOM'] = '$CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS $CCPCHFLAGS $CCPDBFLAGS' |
env['CC'] = 'cl' |
env['CCFLAGS'] = SCons.Util.CLVar('/nologo') |
env['CFLAGS'] = SCons.Util.CLVar('') |
- env['CCCOM'] = '$CC /Fo$TARGET /c $SOURCES $CFLAGS $CCFLAGS $_CCCOMCOM' |
+ env['CCCOM'] = '$CC $_MSVC_OUTPUT_FLAG /c $CHANGED_SOURCES $CFLAGS $CCFLAGS $_CCCOMCOM' |
env['SHCC'] = '$CC' |
env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS') |
env['SHCFLAGS'] = SCons.Util.CLVar('$CFLAGS') |
- env['SHCCCOM'] = '$SHCC /Fo$TARGET /c $SOURCES $SHCFLAGS $SHCCFLAGS $_CCCOMCOM' |
+ env['SHCCCOM'] = '$SHCC $_MSVC_OUTPUT_FLAG /c $CHANGED_SOURCES $SHCFLAGS $SHCCFLAGS $_CCCOMCOM' |
env['CXX'] = '$CC' |
- env['CXXFLAGS'] = SCons.Util.CLVar('$CCFLAGS $( /TP $)') |
- env['CXXCOM'] = '$CXX /Fo$TARGET /c $SOURCES $CXXFLAGS $CCFLAGS $_CCCOMCOM' |
+ env['CXXFLAGS'] = SCons.Util.CLVar('$( /TP $)') |
+ env['CXXCOM'] = '$CXX $_MSVC_OUTPUT_FLAG /c $CHANGED_SOURCES $CXXFLAGS $CCFLAGS $_CCCOMCOM' |
env['SHCXX'] = '$CXX' |
env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS') |
- env['SHCXXCOM'] = '$SHCXX /Fo$TARGET /c $SOURCES $SHCXXFLAGS $SHCCFLAGS $_CCCOMCOM' |
+ env['SHCXXCOM'] = '$SHCXX $_MSVC_OUTPUT_FLAG /c $CHANGED_SOURCES $SHCXXFLAGS $SHCCFLAGS $_CCCOMCOM' |
env['CPPDEFPREFIX'] = '/D' |
env['CPPDEFSUFFIX'] = '' |
env['INCPREFIX'] = '/I' |