diff options
Diffstat (limited to 'scons')
| -rw-r--r-- | scons/custom.py | 167 | ||||
| -rw-r--r-- | scons/gallium.py | 156 | ||||
| -rw-r--r-- | scons/generic.py | 590 | ||||
| -rw-r--r-- | scons/llvm.py | 11 | ||||
| -rw-r--r-- | scons/mslib_sa.py | 8 | ||||
| -rw-r--r-- | scons/mslink_sa.py | 83 | ||||
| -rw-r--r-- | scons/msvc_sa.py | 103 | 
7 files changed, 359 insertions, 759 deletions
| diff --git a/scons/custom.py b/scons/custom.py new file mode 100644 index 0000000000..572b963388 --- /dev/null +++ b/scons/custom.py @@ -0,0 +1,167 @@ +"""custom + +Custom builders and methods. + +""" + +# +# Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. +# All Rights Reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sub license, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice (including the +# next paragraph) shall be included in all copies or substantial portions +# of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +# IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR +# ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + + +import os +import os.path +import re + +import SCons.Action +import SCons.Builder +import SCons.Scanner + +import fixes + + +def quietCommandLines(env): +    # Quiet command lines +    # See also http://www.scons.org/wiki/HidingCommandLinesInOutput +    env['ASCOMSTR'] = "  Assembling $SOURCE ..." +    env['ASPPCOMSTR'] = "  Assembling $SOURCE ..." +    env['CCCOMSTR'] = "  Compiling $SOURCE ..." +    env['SHCCCOMSTR'] = "  Compiling $SOURCE ..." +    env['CXXCOMSTR'] = "  Compiling $SOURCE ..." +    env['SHCXXCOMSTR'] = "  Compiling $SOURCE ..." +    env['ARCOMSTR'] = "  Archiving $TARGET ..." +    env['RANLIBCOMSTR'] = "  Indexing $TARGET ..." +    env['LINKCOMSTR'] = "  Linking $TARGET ..." +    env['SHLINKCOMSTR'] = "  Linking $TARGET ..." +    env['LDMODULECOMSTR'] = "  Linking $TARGET ..." +    env['SWIGCOMSTR'] = "  Generating $TARGET ..." + + +def createConvenienceLibBuilder(env): +    """This is a utility function that creates the ConvenienceLibrary +    Builder in an Environment if it is not there already. + +    If it is already there, we return the existing one. + +    Based on the stock StaticLibrary and SharedLibrary builders. +    """ + +    try: +        convenience_lib = env['BUILDERS']['ConvenienceLibrary'] +    except KeyError: +        action_list = [ SCons.Action.Action("$ARCOM", "$ARCOMSTR") ] +        if env.Detect('ranlib'): +            ranlib_action = SCons.Action.Action("$RANLIBCOM", "$RANLIBCOMSTR") +            action_list.append(ranlib_action) + +        convenience_lib = SCons.Builder.Builder(action = action_list, +                                  emitter = '$LIBEMITTER', +                                  prefix = '$LIBPREFIX', +                                  suffix = '$LIBSUFFIX', +                                  src_suffix = '$SHOBJSUFFIX', +                                  src_builder = 'SharedObject') +        env['BUILDERS']['ConvenienceLibrary'] = convenience_lib + +    return convenience_lib + + +# TODO: handle import statements with multiple modules +# TODO: handle from import statements +import_re = re.compile(r'^import\s+(\S+)$', re.M) + +def python_scan(node, env, path): +    # http://www.scons.org/doc/0.98.5/HTML/scons-user/c2781.html#AEN2789 +    contents = node.get_contents() +    source_dir = node.get_dir() +    imports = import_re.findall(contents) +    results = [] +    for imp in imports: +        for dir in path: +            file = os.path.join(str(dir), imp.replace('.', os.sep) + '.py') +            if os.path.exists(file): +                results.append(env.File(file)) +                break +            file = os.path.join(str(dir), imp.replace('.', os.sep), '__init__.py') +            if os.path.exists(file): +                results.append(env.File(file)) +                break +    return results + +python_scanner = SCons.Scanner.Scanner(function = python_scan, skeys = ['.py']) + + +def code_generate(env, script, target, source, command): +    """Method to simplify code generation via python scripts. + +    http://www.scons.org/wiki/UsingCodeGenerators +    http://www.scons.org/doc/0.98.5/HTML/scons-user/c2768.html +    """ + +    # We're generating code using Python scripts, so we have to be +    # careful with our scons elements.  This entry represents +    # the generator file *in the source directory*. +    script_src = env.File(script).srcnode() + +    # This command creates generated code *in the build directory*. +    command = command.replace('$SCRIPT', script_src.path) +    code = env.Command(target, source, command) + +    # Explicitly mark that the generated code depends on the generator, +    # and on implicitly imported python modules +    path = (script_src.get_dir(),) +    deps = [script_src] +    deps += script_src.get_implicit_deps(env, python_scanner, path) +    env.Depends(code, deps) + +    # Running the Python script causes .pyc files to be generated in the +    # source directory.  When we clean up, they should go too. So add side +    # effects for .pyc files +    for dep in deps: +        pyc = env.File(str(dep) + 'c') +        env.SideEffect(pyc, code) + +    return code + + +def createCodeGenerateMethod(env): +    env.Append(SCANNERS = python_scanner) +    env.AddMethod(code_generate, 'CodeGenerate') + + +def generate(env): +    """Common environment generation code""" + +    if env.get('quiet', True): +        quietCommandLines(env) + +    # Custom builders and methods +    createConvenienceLibBuilder(env) +    createCodeGenerateMethod(env) + +    # for debugging +    #print env.Dump() + + +def exists(env): +    return 1 diff --git a/scons/gallium.py b/scons/gallium.py index 2d963a5f9e..24f88e104b 100644 --- a/scons/gallium.py +++ b/scons/gallium.py @@ -38,116 +38,6 @@ import SCons.Action  import SCons.Builder  import SCons.Scanner -import fixes - - -def quietCommandLines(env): -    # Quiet command lines -    # See also http://www.scons.org/wiki/HidingCommandLinesInOutput -    env['ASCOMSTR'] = "  Assembling $SOURCE ..." -    env['ASPPCOMSTR'] = "  Assembling $SOURCE ..." -    env['CCCOMSTR'] = "  Compiling $SOURCE ..." -    env['SHCCCOMSTR'] = "  Compiling $SOURCE ..." -    env['CXXCOMSTR'] = "  Compiling $SOURCE ..." -    env['SHCXXCOMSTR'] = "  Compiling $SOURCE ..." -    env['ARCOMSTR'] = "  Archiving $TARGET ..." -    env['RANLIBCOMSTR'] = "  Indexing $TARGET ..." -    env['LINKCOMSTR'] = "  Linking $TARGET ..." -    env['SHLINKCOMSTR'] = "  Linking $TARGET ..." -    env['LDMODULECOMSTR'] = "  Linking $TARGET ..." -    env['SWIGCOMSTR'] = "  Generating $TARGET ..." - - -def createConvenienceLibBuilder(env): -    """This is a utility function that creates the ConvenienceLibrary -    Builder in an Environment if it is not there already. - -    If it is already there, we return the existing one. - -    Based on the stock StaticLibrary and SharedLibrary builders. -    """ - -    try: -        convenience_lib = env['BUILDERS']['ConvenienceLibrary'] -    except KeyError: -        action_list = [ SCons.Action.Action("$ARCOM", "$ARCOMSTR") ] -        if env.Detect('ranlib'): -            ranlib_action = SCons.Action.Action("$RANLIBCOM", "$RANLIBCOMSTR") -            action_list.append(ranlib_action) - -        convenience_lib = SCons.Builder.Builder(action = action_list, -                                  emitter = '$LIBEMITTER', -                                  prefix = '$LIBPREFIX', -                                  suffix = '$LIBSUFFIX', -                                  src_suffix = '$SHOBJSUFFIX', -                                  src_builder = 'SharedObject') -        env['BUILDERS']['ConvenienceLibrary'] = convenience_lib - -    return convenience_lib - - -# TODO: handle import statements with multiple modules -# TODO: handle from import statements -import_re = re.compile(r'^import\s+(\S+)$', re.M) - -def python_scan(node, env, path): -    # http://www.scons.org/doc/0.98.5/HTML/scons-user/c2781.html#AEN2789 -    contents = node.get_contents() -    source_dir = node.get_dir() -    imports = import_re.findall(contents) -    results = [] -    for imp in imports: -        for dir in path: -            file = os.path.join(str(dir), imp.replace('.', os.sep) + '.py') -            if os.path.exists(file): -                results.append(env.File(file)) -                break -            file = os.path.join(str(dir), imp.replace('.', os.sep), '__init__.py') -            if os.path.exists(file): -                results.append(env.File(file)) -                break -    return results - -python_scanner = SCons.Scanner.Scanner(function = python_scan, skeys = ['.py']) - - -def code_generate(env, script, target, source, command): -    """Method to simplify code generation via python scripts. - -    http://www.scons.org/wiki/UsingCodeGenerators -    http://www.scons.org/doc/0.98.5/HTML/scons-user/c2768.html -    """ - -    # We're generating code using Python scripts, so we have to be -    # careful with our scons elements.  This entry represents -    # the generator file *in the source directory*. -    script_src = env.File(script).srcnode() - -    # This command creates generated code *in the build directory*. -    command = command.replace('$SCRIPT', script_src.path) -    code = env.Command(target, source, command) - -    # Explicitly mark that the generated code depends on the generator, -    # and on implicitly imported python modules -    path = (script_src.get_dir(),) -    deps = [script_src] -    deps += script_src.get_implicit_deps(env, python_scanner, path) -    env.Depends(code, deps) - -    # Running the Python script causes .pyc files to be generated in the -    # source directory.  When we clean up, they should go too. So add side -    # effects for .pyc files -    for dep in deps: -        pyc = env.File(str(dep) + 'c') -        env.SideEffect(pyc, code) - -    return code - - -def createCodeGenerateMethod(env): -    env.Append(SCANNERS = python_scanner) -    env.AddMethod(code_generate, 'CodeGenerate') -  def symlink(target, source, env):      target = str(target[0]) @@ -156,19 +46,34 @@ def symlink(target, source, env):          os.remove(target)      os.symlink(os.path.basename(source), target) -def install_shared_library(env, source, version = ()): -    source = str(source[0]) +def install(env, source, subdir): +    target_dir = os.path.join(env.Dir('#.').srcnode().abspath, env['build'], subdir) +    env.Install(target_dir, source) + +def install_program(env, source): +    install(env, source, 'bin') + +def install_shared_library(env, sources, version = ()): +    install_dir = os.path.join(env.Dir('#.').srcnode().abspath, env['build'])      version = tuple(map(str, version)) -    target_dir =  os.path.join(env.Dir('#.').srcnode().abspath, env['build'], 'lib') -    target_name = '.'.join((str(source),) + version) -    last = env.InstallAs(os.path.join(target_dir, target_name), source) -    while len(version): -        version = version[:-1] -        target_name = '.'.join((str(source),) + version) -        action = SCons.Action.Action(symlink, "$TARGET -> $SOURCE") -        last = env.Command(os.path.join(target_dir, target_name), last, action)  +    if env['SHLIBSUFFIX'] == '.dll': +        dlls = env.FindIxes(sources, 'SHLIBPREFIX', 'SHLIBSUFFIX') +        install(env, dlls, 'bin') +        libs = env.FindIxes(sources, 'LIBPREFIX', 'LIBSUFFIX') +        install(env, libs, 'lib') +    else: +        for source in sources: +            target_dir =  os.path.join(install_dir, 'lib') +            target_name = '.'.join((str(source),) + version) +            last = env.InstallAs(os.path.join(target_dir, target_name), source) +            while len(version): +                version = version[:-1] +                target_name = '.'.join((str(source),) + version) +                action = SCons.Action.Action(symlink, "$TARGET -> $SOURCE") +                last = env.Command(os.path.join(target_dir, target_name), last, action)   def createInstallMethods(env): +    env.AddMethod(install_program, 'InstallProgram')      env.AddMethod(install_shared_library, 'InstallSharedLibrary') @@ -194,9 +99,6 @@ def num_jobs():  def generate(env):      """Common environment generation code""" -    if env.get('quiet', True): -        quietCommandLines(env) -      # Toolchain      platform = env['platform']      if env['toolchain'] == 'default': @@ -236,6 +138,8 @@ def generate(env):      env['build'] = build_dir      env.SConsignFile(os.path.join(build_dir, '.sconsign'))      env.CacheDir('build/cache') +    env['CONFIGUREDIR'] = os.path.join(build_dir, 'conf') +    env['CONFIGURELOG'] = os.path.join(os.path.abspath(build_dir), 'config.log')      # Parallel build      if env.GetOption('num_jobs') <= 1: @@ -257,8 +161,6 @@ def generate(env):              #'UNICODE',              ('_WIN32_WINNT', '0x0501'), # minimum required OS version              ('WINVER', '0x0501'), -            # http://msdn2.microsoft.com/en-us/library/6dwk3a1z.aspx, -            'WIN32_LEAN_AND_MEAN',          ]          if msvc and env['toolchain'] != 'winddk':              cppdefines += [ @@ -370,7 +272,6 @@ def generate(env):              '-Wno-long-long',              '-ffast-math',              '-fmessage-length=0', # be nice to Eclipse -            '-fno-strict-aliasing', # we violate strict pointer aliasing rules          ]          cflags += [              '-Werror=declaration-after-statement', @@ -538,8 +439,7 @@ def generate(env):      env.Append(LIBS = [])      # Custom builders and methods -    createConvenienceLibBuilder(env) -    createCodeGenerateMethod(env) +    env.Tool('custom')      createInstallMethods(env)      # for debugging diff --git a/scons/generic.py b/scons/generic.py deleted file mode 100644 index 859bf2ae64..0000000000 --- a/scons/generic.py +++ /dev/null @@ -1,590 +0,0 @@ -"""generic - -Generic tool that provides a commmon ground for all platforms. - -""" - -# -# Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. -# All Rights Reserved. -# -# Permission is hereby granted, free of charge, to any person obtaining a -# copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sub license, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice (including the -# next paragraph) shall be included in all copies or substantial portions -# of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. -# IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR -# ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - - -import os -import os.path -import re -import platform as _platform -import sys - -import SCons.Action -import SCons.Builder -import SCons.Scanner - - -def quietCommandLines(env): -    # Quiet command lines -    # See also http://www.scons.org/wiki/HidingCommandLinesInOutput -    env['CCCOMSTR'] = "Compiling $SOURCE ..." -    env['CXXCOMSTR'] = "Compiling $SOURCE ..." -    env['ARCOMSTR'] = "Archiving $TARGET ..." -    env['RANLIBCOMSTR'] = "" -    env['LINKCOMSTR'] = "Linking $TARGET ..." - - -def createConvenienceLibBuilder(env): -    """This is a utility function that creates the ConvenienceLibrary -    Builder in an Environment if it is not there already. - -    If it is already there, we return the existing one. - -    Based on the stock StaticLibrary and SharedLibrary builders. -    """ - -    try: -        convenience_lib = env['BUILDERS']['ConvenienceLibrary'] -    except KeyError: -        action_list = [ SCons.Action.Action("$ARCOM", "$ARCOMSTR") ] -        if env.Detect('ranlib'): -            ranlib_action = SCons.Action.Action("$RANLIBCOM", "$RANLIBCOMSTR") -            action_list.append(ranlib_action) - -        convenience_lib = SCons.Builder.Builder(action = action_list, -                                  emitter = '$LIBEMITTER', -                                  prefix = '$LIBPREFIX', -                                  suffix = '$LIBSUFFIX', -                                  src_suffix = '$SHOBJSUFFIX', -                                  src_builder = 'SharedObject') -        env['BUILDERS']['ConvenienceLibrary'] = convenience_lib - -    return convenience_lib - - -# TODO: handle import statements with multiple modules -# TODO: handle from import statements -import_re = re.compile(r'^import\s+(\S+)$', re.M) - -def python_scan(node, env, path): -    # http://www.scons.org/doc/0.98.5/HTML/scons-user/c2781.html#AEN2789 -    contents = node.get_contents() -    source_dir = node.get_dir() -    imports = import_re.findall(contents) -    results = [] -    for imp in imports: -        for dir in path: -            file = os.path.join(str(dir), imp.replace('.', os.sep) + '.py') -            if os.path.exists(file): -                results.append(env.File(file)) -                break -            file = os.path.join(str(dir), imp.replace('.', os.sep), '__init__.py') -            if os.path.exists(file): -                results.append(env.File(file)) -                break -    return results - -python_scanner = SCons.Scanner.Scanner(function = python_scan, skeys = ['.py']) - - -def code_generate(env, script, target, source, command): -    """Method to simplify code generation via python scripts. - -    http://www.scons.org/wiki/UsingCodeGenerators -    http://www.scons.org/doc/0.98.5/HTML/scons-user/c2768.html -    """ - -    # We're generating code using Python scripts, so we have to be -    # careful with our scons elements.  This entry represents -    # the generator file *in the source directory*. -    script_src = env.File(script).srcnode() - -    # This command creates generated code *in the build directory*. -    command = command.replace('$SCRIPT', script_src.path) -    code = env.Command(target, source, command) - -    # Explicitly mark that the generated code depends on the generator, -    # and on implicitly imported python modules -    path = (script_src.get_dir(),) -    deps = [script_src] -    deps += script_src.get_implicit_deps(env, python_scanner, path) -    env.Depends(code, deps) - -    # Running the Python script causes .pyc files to be generated in the -    # source directory.  When we clean up, they should go too. So add side -    # effects for .pyc files -    for dep in deps: -        pyc = env.File(str(dep) + 'c') -        env.SideEffect(pyc, code) - -    return code - - -def createCodeGenerateMethod(env): -    env.Append(SCANNERS = python_scanner) -    env.AddMethod(code_generate, 'CodeGenerate') - - -def symlink(target, source, env): -    target = str(target[0]) -    source = str(source[0]) -    if os.path.islink(target) or os.path.exists(target): -        os.remove(target) -    os.symlink(os.path.basename(source), target) - -def install_shared_library(env, source, version = ()): -    source = str(source[0]) -    version = tuple(map(str, version)) -    target_dir =  os.path.join(env.Dir('#.').srcnode().abspath, env['build'], 'lib') -    target_name = '.'.join((str(source),) + version) -    last = env.InstallAs(os.path.join(target_dir, target_name), source) -    while len(version): -        version = version[:-1] -        target_name = '.'.join((str(source),) + version) -        action = SCons.Action.Action(symlink, "$TARGET -> $SOURCE") -        last = env.Command(os.path.join(target_dir, target_name), last, action)  - -def createInstallMethods(env): -    env.AddMethod(install_shared_library, 'InstallSharedLibrary') - - -_platform_map = { -    'linux2': 'linux', -    'win32': 'windows', -} - - -_machine_map = { -	'x86': 'x86', -	'i386': 'x86', -	'i486': 'x86', -	'i586': 'x86', -	'i686': 'x86', -	'ppc': 'ppc', -	'x86_64': 'x86_64', -} - - -_toolchain_map = { -    'winddk': 'winddk', -    'wince': 'wcesdk', -} - - -_bool_map = { -    'y': 1,  -    'yes': 1, -    't': 1,  -    'true': 1,  -    '1': 1, -    'on': 1, -    'all': 1,  -    'n': 0,  -    'no': 0,  -    'f': 0,  -    'false': 0,  -    '0': 0, -    'off': 0, -    'none': 0, -} - - -def num_jobs(): -    try: -        return int(os.environ['NUMBER_OF_PROCESSORS']) -    except (ValueError, KeyError): -        pass - -    try: -        return os.sysconf('SC_NPROCESSORS_ONLN') -    except (ValueError, OSError, AttributeError): -        pass - -    try: -        return int(os.popen2("sysctl -n hw.ncpu")[1].read()) -    except ValueError: -        pass - -    return 1 - - -def generate(env): -    """Common environment generation code""" - -    from SCons.Script import ARGUMENTS - -    # FIXME: this is already too late -    #if env.get('quiet', False): -    #    quietCommandLines(env) - - -    # Platform -    try: -        env['platform'] = ARGUMENTS['platform'] -    except KeyError: -        env['platform'] = _platform_map.get(sys.platform, sys.platform) - -    # Machine -    try: -        env['machine'] = ARGUMENTS['machine'] -    except KeyError: -        env['machine'] = _machine_map.get(os.environ.get('PROCESSOR_ARCHITECTURE', _platform.machine()), 'generic') - -    # Toolchain -    try: -        env['toolchain'] = ARGUMENTS['toolchain'] -    except KeyError: -        if env['platform'] in ('windows', 'winddk', 'wince') and sys.platform != 'win32': -            env['toolchain'] = 'crossmingw' -        else: -            env['toolchain'] = _toolchain_map.get(env['platform'], 'default') -    if env['toolchain'] == 'crossmingw' and env['machine'] not in ('generic', 'x86'): -            env['machine'] = 'x86' - -    try: -        env['MSVS_VERSION'] = ARGUMENTS['MSVS_VERSION'] -    except KeyError: -        pass - -    # Build type -    env['debug'] = _bool_map[ARGUMENTS.get('debug', 'no')] -    env['profile'] = _bool_map[ARGUMENTS.get('profile', 'no')] - -    # Put build output in a separate dir, which depends on the current -    # configuration. See also http://www.scons.org/wiki/AdvancedBuildExample -    try: -        env['build'] = ARGUMENTS['build'] -    except KeyError: -        build_topdir = 'build' -        build_subdir = env['platform'] -        if env['machine'] != 'generic': -            build_subdir += '-' + env['machine'] -        if env['debug']: -            build_subdir += "-debug" -        if env['profile']: -            build_subdir += "-profile" -        env['build'] = os.path.join(build_topdir, build_subdir) -    # Place the .sconsign file in the build dir too, to avoid issues with -    # different scons versions building the same source file -    env.SConsignFile(os.path.join(env['build'], '.sconsign')) - -    # Parallel build -    if env.GetOption('num_jobs') <= 1: -        env.SetOption('num_jobs', num_jobs()) - -    # Summary -    print -    print '  platform=%s' % env['platform'] -    print '  machine=%s' % env['machine'] -    print '  toolchain=%s' % env['toolchain'] -    print '  debug=%s' % ['no', 'yes'][env['debug']] -    print '  profile=%s' % ['no', 'yes'][env['profile']] -    print '  build=%s' % env['build'] -    print '  %s jobs' % env.GetOption('num_jobs') -    print - -    # Load tool chain -    env.Tool(env['toolchain']) - -    env['gcc'] = 'gcc' in os.path.basename(env['CC']).split('-') -    env['msvc'] = env['CC'] == 'cl' - -    # shortcuts -    debug = env['debug'] -    machine = env['machine'] -    platform = env['platform'] -    x86 = env['machine'] == 'x86' -    ppc = env['machine'] == 'ppc' -    gcc = env['gcc'] -    msvc = env['msvc'] - -    # C preprocessor options -    cppdefines = [] -    if debug: -        cppdefines += ['DEBUG'] -    else: -        cppdefines += ['NDEBUG'] -    if env['profile']: -        cppdefines += ['PROFILE'] -    if platform == 'windows': -        cppdefines += [ -            'WIN32', -            '_WINDOWS', -            #'_UNICODE', -            #'UNICODE', -            # http://msdn2.microsoft.com/en-us/library/6dwk3a1z.aspx, -            #'WIN32_LEAN_AND_MEAN', -        ] -        if msvc: -            cppdefines += [ -                'VC_EXTRALEAN', -                '_USE_MATH_DEFINES', -                '_CRT_SECURE_NO_WARNINGS', -                '_CRT_SECURE_NO_DEPRECATE', -                '_SCL_SECURE_NO_WARNINGS', -                '_SCL_SECURE_NO_DEPRECATE', -            ] -        if debug: -            cppdefines += ['_DEBUG'] -    if platform == 'winddk': -        # Mimic WINDDK's builtin flags. See also: -        # - WINDDK's bin/makefile.new i386mk.inc for more info. -        # - buildchk_wxp_x86.log files, generated by the WINDDK's build -        # - http://alter.org.ua/docs/nt_kernel/vc8_proj/ -        cppdefines += [ -            ('_X86_', '1'), -            ('i386', '1'), -            'STD_CALL', -            ('CONDITION_HANDLING', '1'), -            ('NT_INST', '0'), -            ('WIN32', '100'), -            ('_NT1X_', '100'), -            ('WINNT', '1'), -            ('_WIN32_WINNT', '0x0501'), # minimum required OS version -            ('WINVER', '0x0501'), -            ('_WIN32_IE', '0x0603'), -            ('WIN32_LEAN_AND_MEAN', '1'), -            ('DEVL', '1'), -            ('__BUILDMACHINE__', 'WinDDK'), -            ('FPO', '0'), -        ] -        if debug: -            cppdefines += [('DBG', 1)] -    if platform == 'wince': -        cppdefines += [ -            '_CRT_SECURE_NO_DEPRECATE', -            '_USE_32BIT_TIME_T', -            'UNICODE', -            '_UNICODE', -            ('UNDER_CE', '600'), -            ('_WIN32_WCE', '0x600'), -            'WINCEOEM', -            'WINCEINTERNAL', -            'WIN32', -            'STRICT', -            'x86', -            '_X86_', -            'INTERNATIONAL', -            ('INTLMSG_CODEPAGE', '1252'), -        ] -    env.Append(CPPDEFINES = cppdefines) - -    # C preprocessor includes -    if platform == 'winddk': -        env.Append(CPPPATH = [ -            env['SDK_INC_PATH'], -            env['DDK_INC_PATH'], -            env['WDM_INC_PATH'], -            env['CRT_INC_PATH'], -        ]) - -    # C compiler options -    cflags = [] # C -    cxxflags = [] # C++ -    ccflags = [] # C & C++ -    if gcc: -        if debug: -            ccflags += ['-O0', '-g3'] -        elif env['toolchain'] == 'crossmingw': -            ccflags += ['-O0', '-g3'] # mingw 4.2.1 optimizer is broken -        else: -            ccflags += ['-O3', '-g0'] -        if env['machine'] == 'x86': -            ccflags += [ -                '-m32', -                #'-march=pentium4', -                '-mmmx', '-msse', '-msse2', # enable SIMD intrinsics -                #'-mfpmath=sse', -            ] -        if env['machine'] == 'x86_64': -            ccflags += ['-m64'] -        # See also: -        # - http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html -        ccflags += [ -            '-Wall', -            '-Wmissing-field-initializers', -            '-Wpointer-arith', -            '-Wno-long-long', -            '-ffast-math', -            '-fmessage-length=0', # be nice to Eclipse -        ] -        cflags += [ -            '-Werror=declaration-after-statement', -            '-Wmissing-prototypes', -            '-std=gnu99', -        ] -    if msvc: -        # See also: -        # - http://msdn.microsoft.com/en-us/library/19z1t1wy.aspx -        # - cl /? -        if debug: -            ccflags += [ -              '/Od', # disable optimizations -              '/Oi', # enable intrinsic functions -              '/Oy-', # disable frame pointer omission -              '/GL-', # disable whole program optimization -            ] -        else: -            ccflags += [ -              '/Ox', # maximum optimizations -              '/Oi', # enable intrinsic functions -              '/Ot', # favor code speed -              #'/fp:fast', # fast floating point  -            ] -        ccflags += [ -            '/W3', # warning level -            #'/Wp64', # enable 64 bit porting warnings -        ] -        if env['machine'] == 'x86': -            ccflags += [ -                #'/QIfist', # Suppress _ftol -                #'/arch:SSE2', # use the SSE2 instructions -            ] -        if platform == 'windows': -            ccflags += [ -                # TODO -            ] -        if platform == 'winddk': -            ccflags += [ -                '/Zl', # omit default library name in .OBJ -                '/Zp8', # 8bytes struct member alignment -                '/Gy', # separate functions for linker -                '/Gm-', # disable minimal rebuild -                '/WX', # treat warnings as errors -                '/Gz', # __stdcall Calling convention -                '/GX-', # disable C++ EH -                '/GR-', # disable C++ RTTI -                '/GF', # enable read-only string pooling -                '/G6', # optimize for PPro, P-II, P-III -                '/Ze', # enable extensions -                '/Gi-', # disable incremental compilation -                '/QIfdiv-', # disable Pentium FDIV fix -                '/hotpatch', # prepares an image for hotpatching. -                #'/Z7', #enable old-style debug info -            ] -        if platform == 'wince': -            # See also C:\WINCE600\public\common\oak\misc\makefile.def -            ccflags += [ -                '/Zl', # omit default library name in .OBJ -                '/GF', # enable read-only string pooling -                '/GR-', # disable C++ RTTI -                '/GS', # enable security checks -                # Allow disabling language conformance to maintain backward compat -                #'/Zc:wchar_t-', # don't force wchar_t as native type, instead of typedef -                #'/Zc:forScope-', # don't enforce Standard C++ for scoping rules -                #'/wd4867', -                #'/wd4430', -                #'/MT', -                #'/U_MT', -            ] -        # Automatic pdb generation -        # See http://scons.tigris.org/issues/show_bug.cgi?id=1656 -        env.EnsureSConsVersion(0, 98, 0) -        env['PDB'] = '${TARGET.base}.pdb' -    env.Append(CCFLAGS = ccflags) -    env.Append(CFLAGS = cflags) -    env.Append(CXXFLAGS = cxxflags) - -    if env['platform'] == 'windows' and msvc: -        # Choose the appropriate MSVC CRT -        # http://msdn.microsoft.com/en-us/library/2kzt1wy3.aspx -        if env['debug']: -            env.Append(CCFLAGS = ['/MTd']) -            env.Append(SHCCFLAGS = ['/LDd']) -        else: -            env.Append(CCFLAGS = ['/MT']) -            env.Append(SHCCFLAGS = ['/LD']) -     -    # Assembler options -    if gcc: -        if env['machine'] == 'x86': -            env.Append(ASFLAGS = ['-m32']) -        if env['machine'] == 'x86_64': -            env.Append(ASFLAGS = ['-m64']) - -    # Linker options -    linkflags = [] -    if gcc: -        if env['machine'] == 'x86': -            linkflags += ['-m32'] -        if env['machine'] == 'x86_64': -            linkflags += ['-m64'] -    if platform == 'windows' and msvc: -        # See also: -        # - http://msdn2.microsoft.com/en-us/library/y0zzbyt4.aspx -        linkflags += [ -            '/fixed:no', -            '/incremental:no', -        ] -    if platform == 'winddk': -        linkflags += [ -            '/merge:_PAGE=PAGE', -            '/merge:_TEXT=.text', -            '/section:INIT,d', -            '/opt:ref', -            '/opt:icf', -            '/ignore:4198,4010,4037,4039,4065,4070,4078,4087,4089,4221', -            '/incremental:no', -            '/fullbuild', -            '/release', -            '/nodefaultlib', -            '/wx', -            '/debug', -            '/debugtype:cv', -            '/version:5.1', -            '/osversion:5.1', -            '/functionpadmin:5', -            '/safeseh', -            '/pdbcompress', -            '/stack:0x40000,0x1000', -            '/driver', -            '/align:0x80', -            '/subsystem:native,5.01', -            '/base:0x10000', - -            '/entry:DrvEnableDriver', -        ] -        if env['debug'] or env['profile']: -            linkflags += [ -                '/MAP', # http://msdn.microsoft.com/en-us/library/k7xkk3e2.aspx -            ] -    if platform == 'wince': -        linkflags += [ -            '/nodefaultlib', -            #'/incremental:no', -            #'/fullbuild', -            '/entry:_DllMainCRTStartup', -        ] -    env.Append(LINKFLAGS = linkflags) - -    # Default libs -    env.Append(LIBS = []) - -    # Custom builders and methods -    createConvenienceLibBuilder(env) -    createCodeGenerateMethod(env) -    createInstallMethods(env) - -    # for debugging -    #print env.Dump() - - -def exists(env): -    return 1 diff --git a/scons/llvm.py b/scons/llvm.py index 7b26650290..37c503ec98 100644 --- a/scons/llvm.py +++ b/scons/llvm.py @@ -65,6 +65,7 @@ def generate(env):              env.AppendUnique(CPPDEFINES = [                  '__STDC_LIMIT_MACROS',                   '__STDC_CONSTANT_MACROS', +                'HAVE_STDINT_H',              ])              env.Prepend(LIBPATH = [os.path.join(llvm_dir, 'lib')])              env.Prepend(LIBS = [ @@ -98,6 +99,16 @@ def generate(env):                  'imagehlp',                  'psapi',              ]) +            if env['msvc']: +                # Some of the LLVM C headers use the inline keyword without +                # defining it. +                env.Append(CPPDEFINES = [('inline', '__inline')]) +                if env['debug']: +                    # LLVM libraries are static, build with /MT, and they +                    # automatically link agains LIBCMT. When we're doing a +                    # debug build we'll be linking against LIBCMTD, so disable +                    # that. +                    env.Append(LINKFLAGS = ['/nodefaultlib:LIBCMT'])              env['LLVM_VERSION'] = '2.6'          return      elif env.Detect('llvm-config'): diff --git a/scons/mslib_sa.py b/scons/mslib_sa.py index 50d47ee37b..bdc0dd9251 100644 --- a/scons/mslib_sa.py +++ b/scons/mslib_sa.py @@ -7,7 +7,7 @@ Based on SCons.Tool.mslib, without the MSVC detection.  """  # -# 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 @@ -130,4 +130,8 @@ def generate(env):  def exists(env):      return env.Detect('lib') or env.Detect('link') -# vim:set ts=4 sw=4 et: +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/mslink_sa.py b/scons/mslink_sa.py index 53331def1a..0ecdf24a92 100644 --- a/scons/mslink_sa.py +++ b/scons/mslink_sa.py @@ -7,7 +7,7 @@ Based on SCons.Tool.mslink, without the MSVS detection.  """  # -# 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 @@ -45,9 +45,9 @@ def pdbGenerator(env, target, source, for_signature):      except (AttributeError, IndexError):          return None -def windowsShlinkTargets(target, source, env, for_signature): +def _dllTargets(target, source, env, for_signature, paramtp):      listCmd = [] -    dll = env.FindIxes(target, 'SHLIBPREFIX', 'SHLIBSUFFIX') +    dll = env.FindIxes(target, '%sPREFIX' % paramtp, '%sSUFFIX' % paramtp)      if dll: listCmd.append("/out:%s"%dll.get_string(for_signature))      implib = env.FindIxes(target, 'LIBPREFIX', 'LIBSUFFIX') @@ -55,12 +55,15 @@ def windowsShlinkTargets(target, source, env, for_signature):      return listCmd -def windowsShlinkSources(target, source, env, for_signature): +def _dllSources(target, source, env, for_signature, paramtp):      listCmd = []      deffile = env.FindIxes(source, "WINDOWSDEFPREFIX", "WINDOWSDEFSUFFIX")      for src in source: -        if src == deffile: +        # Check explicitly for a non-None deffile so that the __cmp__ +        # method of the base SCons.Util.Proxy class used for some Node +        # proxies doesn't try to use a non-existent __dict__ attribute. +        if deffile and src == deffile:              # Treat this source as a .def file.              listCmd.append("/def:%s" % src.get_string(for_signature))          else: @@ -68,17 +71,32 @@ def windowsShlinkSources(target, source, env, for_signature):              listCmd.append(src)      return listCmd -def windowsLibEmitter(target, source, env): +def windowsShlinkTargets(target, source, env, for_signature): +    return _dllTargets(target, source, env, for_signature, 'SHLIB') + +def windowsShlinkSources(target, source, env, for_signature): +    return _dllSources(target, source, env, for_signature, 'SHLIB') + +def _windowsLdmodTargets(target, source, env, for_signature): +    """Get targets for loadable modules.""" +    return _dllTargets(target, source, env, for_signature, 'LDMODULE') + +def _windowsLdmodSources(target, source, env, for_signature): +    """Get sources for loadable modules.""" +    return _dllSources(target, source, env, for_signature, 'LDMODULE') + +def _dllEmitter(target, source, env, paramtp): +    """Common implementation of dll emitter."""      SCons.Tool.msvc.validate_vars(env)      extratargets = []      extrasources = [] -    dll = env.FindIxes(target, "SHLIBPREFIX", "SHLIBSUFFIX") +    dll = env.FindIxes(target, '%sPREFIX' % paramtp, '%sSUFFIX' % paramtp)      no_import_lib = env.get('no_import_lib', 0)      if not dll: -        raise SCons.Errors.UserError, "A shared library should have exactly one target with the suffix: %s" % env.subst("$SHLIBSUFFIX") +        raise SCons.Errors.UserError, 'A shared library should have exactly one target with the suffix: %s' % env.subst('$%sSUFFIX' % paramtp)      insert_def = env.subst("$WINDOWS_INSERT_DEF")      if not insert_def in ['', '0', 0] and \ @@ -87,7 +105,7 @@ def windowsLibEmitter(target, source, env):          # append a def file to the list of sources          extrasources.append(              env.ReplaceIxes(dll, -                            "SHLIBPREFIX", "SHLIBSUFFIX", +                            '%sPREFIX' % paramtp, '%sSUFFIX' % paramtp,                              "WINDOWSDEFPREFIX", "WINDOWSDEFSUFFIX"))      if env.has_key('PDB') and env['PDB']: @@ -100,16 +118,27 @@ def windowsLibEmitter(target, source, env):          # Append an import library to the list of targets.          extratargets.append(              env.ReplaceIxes(dll, -                            "SHLIBPREFIX", "SHLIBSUFFIX", +                            '%sPREFIX' % paramtp, '%sSUFFIX' % paramtp,                              "LIBPREFIX", "LIBSUFFIX"))          # and .exp file is created if there are exports from a DLL          extratargets.append(              env.ReplaceIxes(dll, -                            "SHLIBPREFIX", "SHLIBSUFFIX", +                            '%sPREFIX' % paramtp, '%sSUFFIX' % paramtp,                              "WINDOWSEXPPREFIX", "WINDOWSEXPSUFFIX"))      return (target+extratargets, source+extrasources) +def windowsLibEmitter(target, source, env): +    return _dllEmitter(target, source, env, 'SHLIB') + +def ldmodEmitter(target, source, env): +    """Emitter for loadable modules. +     +    Loadable modules are identical to shared libraries on Windows, but building +    them is subject to different parameters (LDMODULE*). +    """ +    return _dllEmitter(target, source, env, 'LDMODULE') +  def prog_emitter(target, source, env):      SCons.Tool.msvc.validate_vars(env) @@ -138,8 +167,10 @@ def RegServerFunc(target, source, env):  regServerAction = SCons.Action.Action("$REGSVRCOM", "$REGSVRCOMSTR")  regServerCheck = SCons.Action.Action(RegServerFunc, None) -shlibLinkAction = SCons.Action.Action('${TEMPFILE("$SHLINK $SHLINKFLAGS $_SHLINK_TARGETS $( $_LIBDIRFLAGS $) $_LIBFLAGS $_PDB $_SHLINK_SOURCES")}') -compositeLinkAction = shlibLinkAction + regServerCheck +shlibLinkAction = SCons.Action.Action('${TEMPFILE("$SHLINK $SHLINKFLAGS $_SHLINK_TARGETS $_LIBDIRFLAGS $_LIBFLAGS $_PDB $_SHLINK_SOURCES")}') +compositeShLinkAction = shlibLinkAction + regServerCheck +ldmodLinkAction = SCons.Action.Action('${TEMPFILE("$LDMODULE $LDMODULEFLAGS $_LDMODULE_TARGETS $_LIBDIRFLAGS $_LIBFLAGS $_PDB $_LDMODULE_SOURCES")}') +compositeLdmodAction = ldmodLinkAction + regServerCheck  def generate(env):      """Add Builders and construction variables for ar to an Environment.""" @@ -150,12 +181,12 @@ def generate(env):      env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS /dll')      env['_SHLINK_TARGETS'] = windowsShlinkTargets      env['_SHLINK_SOURCES'] = windowsShlinkSources -    env['SHLINKCOM']   =  compositeLinkAction +    env['SHLINKCOM']   =  compositeShLinkAction      env.Append(SHLIBEMITTER = [windowsLibEmitter])      env['LINK']        = 'link'      env['LINKFLAGS']   = SCons.Util.CLVar('/nologo')      env['_PDB'] = pdbGenerator -    env['LINKCOM'] = '${TEMPFILE("$LINK $LINKFLAGS /OUT:$TARGET.windows $( $_LIBDIRFLAGS $) $_LIBFLAGS $_PDB $SOURCES.windows")}' +    env['LINKCOM'] = '${TEMPFILE("$LINK $LINKFLAGS /OUT:$TARGET.windows $_LIBDIRFLAGS $_LIBFLAGS $_PDB $SOURCES.windows")}'      env.Append(PROGEMITTER = [prog_emitter])      env['LIBDIRPREFIX']='/LIBPATH:'      env['LIBDIRSUFFIX']='' @@ -184,19 +215,19 @@ def generate(env):      env['REGSVRFLAGS'] = '/s '      env['REGSVRCOM'] = '$REGSVR $REGSVRFLAGS ${TARGET.windows}' -    # For most platforms, a loadable module is the same as a shared -    # library.  Platforms which are different can override these, but -    # setting them the same means that LoadableModule works everywhere. +    # Loadable modules are on Windows the same as shared libraries, but they +    # are subject to different build parameters (LDMODULE* variables). +    # Therefore LDMODULE* variables correspond as much as possible to +    # SHLINK*/SHLIB* ones.      SCons.Tool.createLoadableModuleBuilder(env)      env['LDMODULE'] = '$SHLINK'      env['LDMODULEPREFIX'] = '$SHLIBPREFIX'      env['LDMODULESUFFIX'] = '$SHLIBSUFFIX'      env['LDMODULEFLAGS'] = '$SHLINKFLAGS' -    # We can't use '$SHLINKCOM' here because that will stringify the -    # action list on expansion, and will then try to execute expanded -    # strings, with the upshot that it would try to execute RegServerFunc -    # as a command. -    env['LDMODULECOM'] = compositeLinkAction +    env['_LDMODULE_TARGETS'] = _windowsLdmodTargets +    env['_LDMODULE_SOURCES'] = _windowsLdmodSources +    env['LDMODULEEMITTER'] = [ldmodEmitter] +    env['LDMODULECOM'] = compositeLdmodAction  def exists(env):      platform = env.get('PLATFORM', '') @@ -208,4 +239,8 @@ def exists(env):          return env.Detect('link')      return None -# vim:set ts=4 sw=4 et: +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/scons/msvc_sa.py b/scons/msvc_sa.py index 136d305265..a913662920 100644 --- a/scons/msvc_sa.py +++ b/scons/msvc_sa.py @@ -7,7 +7,7 @@ Based on SCons.Tool.msvc, without the MSVS detection.  """  # -# 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 @@ -40,6 +40,7 @@ import SCons.Platform.win32  import SCons.Tool  import SCons.Util  import SCons.Warnings +import SCons.Scanner.RC  CSuffixes = ['.c', '.C']  CXXSuffixes = ['.cc', '.cpp', '.cxx', '.c++', '.C++'] @@ -97,47 +98,114 @@ pch_action = SCons.Action.Action('$PCHCOM', '$PCHCOMSTR')  pch_builder = SCons.Builder.Builder(action=pch_action, suffix='.pch',                                      emitter=pch_emitter,                                      source_scanner=SCons.Tool.SourceFileScanner) + + +# Logic to build .rc files into .res files (resource files) +res_scanner = SCons.Scanner.RC.RCScan()  res_action = SCons.Action.Action('$RCCOM', '$RCCOMSTR')  res_builder = SCons.Builder.Builder(action=res_action,                                      src_suffix='.rc',                                      suffix='.res',                                      src_builder=[], -                                    source_scanner=SCons.Tool.SourceFileScanner) -SCons.Tool.SourceFileScanner.add_scanner('.rc', SCons.Defaults.CScan) +                                    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['CCCOMFLAGS'] = '$CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c $SOURCES /Fo$TARGET $CCPCHFLAGS $CCPDBFLAGS' +    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 $CFLAGS $CCFLAGS $CCCOMFLAGS' +    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 $SHCFLAGS $SHCCFLAGS $CCCOMFLAGS' +    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 $CXXFLAGS $CCCOMFLAGS' +    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 $SHCXXFLAGS $CCCOMFLAGS' +    env['SHCXXCOM']   = '$SHCXX $_MSVC_OUTPUT_FLAG /c $CHANGED_SOURCES $SHCXXFLAGS $SHCCFLAGS $_CCCOMCOM'      env['CPPDEFPREFIX']  = '/D'      env['CPPDEFSUFFIX']  = ''      env['INCPREFIX']  = '/I' @@ -148,6 +216,7 @@ def generate(env):      env['RC'] = 'rc'      env['RCFLAGS'] = SCons.Util.CLVar('') +    env['RCSUFFIXES']=['.rc','.rc2']      env['RCCOM'] = '$RC $_CPPDEFFLAGS $_CPPINCFLAGS $RCFLAGS /fo$TARGET $SOURCES'      env['BUILDERS']['RES'] = res_builder      env['OBJPREFIX']      = '' @@ -159,7 +228,7 @@ def generate(env):      env['CXXFILESUFFIX'] = '.cc'      env['PCHPDBFLAGS'] = SCons.Util.CLVar(['${(PDB and "/Yd") or ""}']) -    env['PCHCOM'] = '$CXX $CXXFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c $SOURCES /Fo${TARGETS[1]} /Yc$PCHSTOP /Fp${TARGETS[0]} $CCPDBFLAGS $PCHPDBFLAGS' +    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'): @@ -170,4 +239,8 @@ def generate(env):  def exists(env):      return env.Detect('cl') -# vim:set ts=4 sw=4 et: +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: | 
