| Index: site_scons/site_tools/concat_source.py
|
| ===================================================================
|
| --- site_scons/site_tools/concat_source.py (revision 0)
|
| +++ site_scons/site_tools/concat_source.py (revision 0)
|
| @@ -0,0 +1,135 @@
|
| +#!/usr/bin/python2.4
|
| +# Copyright 2008, Google Inc.
|
| +# All rights reserved.
|
| +#
|
| +# Redistribution and use in source and binary forms, with or without
|
| +# modification, are permitted provided that the following conditions are
|
| +# met:
|
| +#
|
| +# * Redistributions of source code must retain the above copyright
|
| +# notice, this list of conditions and the following disclaimer.
|
| +# * Redistributions in binary form must reproduce the above
|
| +# copyright notice, this list of conditions and the following disclaimer
|
| +# in the documentation and/or other materials provided with the
|
| +# distribution.
|
| +# * Neither the name of Google Inc. nor the names of its
|
| +# contributors may be used to endorse or promote products derived from
|
| +# this software without specific prior written permission.
|
| +#
|
| +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
| +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
| +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
| +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
| +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
| +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
| +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
| +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
| +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
| +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
| +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
| +
|
| +"""Source concatenation builder for SCons."""
|
| +
|
| +
|
| +import SCons.Script
|
| +
|
| +
|
| +def ConcatSourceBuilder(target, source, env):
|
| + """ConcatSource builder.
|
| +
|
| + Args:
|
| + target: List of target nodes
|
| + source: List of source nodes
|
| + env: Environment in which to build
|
| +
|
| + Returns:
|
| + None if successful; 1 if error.
|
| + """
|
| + if len(target) != 1:
|
| + print 'ERROR: multiple ConcatSource targets when 1 expected'
|
| + return 1
|
| +
|
| + output_lines = [
|
| + '// This file is auto-generated by the ConcatSource builder.']
|
| +
|
| + for source_file in source:
|
| + # Skip source files which are not CPP files. These will be passed through
|
| + # to the output list by the pseudo-builder.
|
| + if source_file.suffix not in env['CONCAT_SOURCE_SUFFIXES']:
|
| + continue
|
| +
|
| + source_path = str(source_file)
|
| +
|
| + if 'msvc' in env['TOOLS']:
|
| + # Add message pragma for nicer progress indication when building with
|
| + # MSVC.
|
| + output_lines.append('#pragma message("--%s")' % (
|
| + source_path.replace("\\", "/")))
|
| +
|
| + output_lines.append('#include "%s"' % source_path)
|
| +
|
| + # Need an EOL at the end of the file for more finicky build tools
|
| + output_lines.append('\n')
|
| +
|
| + output_file = open(str(target[0]), 'w')
|
| + output_file.write('\n'.join(output_lines))
|
| + output_file.close()
|
| +
|
| +
|
| +def ConcatSourcePseudoBuilder(self, target, source):
|
| + """ConcatSource pseudo-builder; calls builder or passes through source nodes.
|
| +
|
| + Args:
|
| + self: Environment in which to build
|
| + target: List of target nodes
|
| + source: List of source nodes
|
| +
|
| + Returns:
|
| + If self['CONCAT_SOURCE_ENABLE'], calls self.ConcatSource and returns
|
| + the list of target nodes. Otherwise, returns the list of source nodes.
|
| + Source nodes which are not CPP files are passed through unchanged to the
|
| + list of output nodes.
|
| + """
|
| + if self.get('CONCAT_SOURCE_ENABLE', True):
|
| + # Scan down source list and separate CPP sources (which we concatenate)
|
| + # from other files (which we pass through).
|
| + cppsource = []
|
| + outputs = []
|
| + for source_file in SCons.Script.Flatten(source):
|
| + if self.File(source_file).suffix in self['CONCAT_SOURCE_SUFFIXES']:
|
| + cppsource.append(source_file)
|
| + else:
|
| + outputs.append(source_file)
|
| +
|
| + if len(cppsource) > 1:
|
| + # More than one file, so concatenate them together
|
| + outputs += self.ConcatSourceBuilder(target, cppsource)
|
| + else:
|
| + # <2 files, so pass them through; no need for a ConcatSource target
|
| + outputs += cppsource
|
| + return outputs
|
| + else:
|
| + # ConcatSource is disabled, so pass through the list of source nodes.
|
| + return source
|
| +
|
| +
|
| +def generate(env):
|
| + # NOTE: SCons requires the use of this name, which fails gpylint.
|
| + """SCons entry point for this tool."""
|
| +
|
| + # Add the builder
|
| + action = SCons.Script.Action(ConcatSourceBuilder,
|
| + varlist = ['CONCAT_SOURCE_SUFFIXES'])
|
| + builder = SCons.Script.Builder(action = action, suffix = '$CXXFILESUFFIX')
|
| + env.Append(BUILDERS={'ConcatSourceBuilder': builder})
|
| +
|
| + # Suffixes of sources we can concatenate. Files not in this list will be
|
| + # passed through untouched. (Note that on Mac, Objective C/C++ files
|
| + # cannot be concatenated with regular C/C++ files.)
|
| + # TODO(rspangler): Probably shouldn't mix C, C++ either...
|
| + env['CONCAT_SOURCE_SUFFIXES'] = ['.c', '.C', '.cxx', '.cpp', '.c++', '.cc',
|
| + '.h', '.H', '.hxx', '.hpp', '.hh']
|
| +
|
| + # Add a psuedo-builder method which can look at the environment to determine
|
| + # whether to call the ConcatSource builder or not
|
| + env.AddMethod(ConcatSourcePseudoBuilder, 'ConcatSource')
|
|
|