| Index: site_scons/site_tools/environment_tools.py | 
| =================================================================== | 
| --- site_scons/site_tools/environment_tools.py	(revision 12583) | 
| +++ site_scons/site_tools/environment_tools.py	(working copy) | 
| @@ -1,284 +0,0 @@ | 
| -#!/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. | 
| - | 
| -"""Set up tools for environments for for software construction toolkit. | 
| - | 
| -This module is a SCons tool which should be include in all environments.  It | 
| -will automatically be included by the component_setup tool. | 
| -""" | 
| - | 
| - | 
| -import os | 
| -import SCons | 
| - | 
| - | 
| -#------------------------------------------------------------------------------ | 
| - | 
| - | 
| -def FilterOut(self, **kw): | 
| -  """Removes values from existing construction variables in an Environment. | 
| - | 
| -  The values to remove should be a list.  For example: | 
| - | 
| -  self.FilterOut(CPPDEFINES=['REMOVE_ME', 'ME_TOO']) | 
| - | 
| -  Args: | 
| -    self: Environment to alter. | 
| -    kw: (Any other named arguments are values to remove). | 
| -  """ | 
| - | 
| -  kw = SCons.Environment.copy_non_reserved_keywords(kw) | 
| -  for key, val in kw.items(): | 
| -    envval = self.get(key, None) | 
| -    if envval is None: | 
| -      # No existing variable in the environment, so nothing to delete. | 
| -      continue | 
| - | 
| -    for vremove in val: | 
| -      # Use while not if, so we can handle duplicates. | 
| -      while vremove in envval: | 
| -        envval.remove(vremove) | 
| - | 
| -    self[key] = envval | 
| - | 
| -    # TODO(sgk): SCons.Environment.Append() has much more logic to deal | 
| -    # with various types of values.  We should handle all those cases in here | 
| -    # too.  (If variable is a dict, etc.) | 
| - | 
| -#------------------------------------------------------------------------------ | 
| - | 
| - | 
| -def Overlap(self, values1, values2): | 
| -  """Checks for overlap between the values. | 
| - | 
| -  Args: | 
| -    self: Environment to use for variable substitution. | 
| -    values1: First value(s) to compare.  May be a string or list of strings. | 
| -    values2: Second value(s) to compare.  May be a string or list of strings. | 
| - | 
| -  Returns: | 
| -    The list of values in common after substitution, or an empty list if | 
| -    the values do not overlap. | 
| - | 
| -  Converts the values to a set of plain strings via self.SubstList2() before | 
| -  comparison, so SCons $ variables are evaluated. | 
| -  """ | 
| -  set1 = set(self.SubstList2(values1)) | 
| -  set2 = set(self.SubstList2(values2)) | 
| -  return list(set1.intersection(set2)) | 
| - | 
| -#------------------------------------------------------------------------------ | 
| - | 
| - | 
| -def ApplySConscript(self, sconscript_file): | 
| -  """Applies a SConscript to the current environment. | 
| - | 
| -  Args: | 
| -    self: Environment to modify. | 
| -    sconscript_file: Name of SConscript file to apply. | 
| - | 
| -  Returns: | 
| -    The return value from the call to SConscript(). | 
| - | 
| -  ApplySConscript() should be used when an existing SConscript which sets up an | 
| -  environment gets too large, or when there is common setup between multiple | 
| -  environments which can't be reduced into a parent environment which the | 
| -  multiple child environments Clone() from.  The latter case is necessary | 
| -  because env.Clone() only enables single inheritance for environments. | 
| - | 
| -  ApplySConscript() is NOT intended to replace the Tool() method.  If you need | 
| -  to add methods or builders to one or more environments, do that as a tool | 
| -  (and write unit tests for them). | 
| - | 
| -  ApplySConscript() is equivalent to the following SCons call: | 
| -      SConscript(sconscript_file, exports={'env':self}) | 
| - | 
| -  The called SConscript should import the 'env' variable to get access to the | 
| -  calling environment: | 
| -      Import('env') | 
| - | 
| -  Changes made to env in the called SConscript will be applied to the | 
| -  environment calling ApplySConscript() - that is, env in the called SConscript | 
| -  is a reference to the calling environment. | 
| - | 
| -  If you need to export multiple variables to the called SConscript, or return | 
| -  variables from it, use the existing SConscript() function. | 
| -  """ | 
| -  return self.SConscript(sconscript_file, exports={'env': self}) | 
| - | 
| -#------------------------------------------------------------------------------ | 
| - | 
| - | 
| -def BuildSConscript(self, sconscript_file): | 
| -  """Builds a SConscript based on the current environment. | 
| - | 
| -  Args: | 
| -    self: Environment to clone and pass to the called SConscript. | 
| -    sconscript_file: Name of SConscript file to build.  If this is a directory, | 
| -        this method will look for sconscript_file+'/build.scons', and if that | 
| -        is not found, sconscript_file+'/SConscript'. | 
| - | 
| -  Returns: | 
| -    The return value from the call to SConscript(). | 
| - | 
| -  BuildSConscript() should be used when an existing SConscript which builds a | 
| -  project gets too large, or when a group of SConscripts are logically related | 
| -  but should not directly affect each others' environments (for example, a | 
| -  library might want to build a number of unit tests which exist in | 
| -  subdirectories, but not allow those tests' SConscripts to affect/pollute the | 
| -  library's environment. | 
| - | 
| -  BuildSConscript() is NOT intended to replace the Tool() method.  If you need | 
| -  to add methods or builders to one or more environments, do that as a tool | 
| -  (and write unit tests for them). | 
| - | 
| -  BuildSConscript() is equivalent to the following SCons call: | 
| -      SConscript(sconscript_file, exports={'env':self.Clone()}) | 
| -  or if sconscript_file is a directory: | 
| -      SConscript(sconscript_file+'/build.scons', exports={'env':self.Clone()}) | 
| - | 
| -  The called SConscript should import the 'env' variable to get access to the | 
| -  calling environment: | 
| -      Import('env') | 
| - | 
| -  Changes made to env in the called SConscript will NOT be applied to the | 
| -  environment calling BuildSConscript() - that is, env in the called SConscript | 
| -  is a clone/copy of the calling environment, not a reference to that | 
| -  environment. | 
| - | 
| -  If you need to export multiple variables to the called SConscript, or return | 
| -  variables from it, use the existing SConscript() function. | 
| -  """ | 
| -  # Need to look for the source node, since by default SCons will look for the | 
| -  # entry in the variant_dir, which won't exist (and thus won't be a directory | 
| -  # or a file).  This isn't a problem in BuildComponents(), since the variant | 
| -  # dir is only set inside its call to SConscript(). | 
| -  if self.Entry(sconscript_file).srcnode().isdir(): | 
| -    # Building a subdirectory, so look for build.scons or SConscript | 
| -    script_file = sconscript_file + '/build.scons' | 
| -    if not self.File(script_file).srcnode().exists(): | 
| -      script_file = sconscript_file + '/SConscript' | 
| -  else: | 
| -    script_file = sconscript_file | 
| - | 
| -  self.SConscript(script_file, exports={'env': self.Clone()}) | 
| - | 
| -#------------------------------------------------------------------------------ | 
| - | 
| - | 
| -def SubstList2(self, *args): | 
| -  """Replacement subst_list designed for flags/parameters, not command lines. | 
| - | 
| -  Args: | 
| -    self: Environment context. | 
| -    args: One or more strings or lists of strings. | 
| - | 
| -  Returns: | 
| -    A flattened, substituted list of strings. | 
| - | 
| -  SCons's built-in subst_list evaluates (substitutes) variables in its | 
| -  arguments, and returns a list of lists (one per positional argument).  Since | 
| -  it is designed for use in command line expansion, the list items are | 
| -  SCons.Subst.CmdStringHolder instances.  These instances can't be passed into | 
| -  env.File() (or subsequent calls to env.subst(), either).  The returned | 
| -  nested lists also need to be flattened via env.Flatten() before the caller | 
| -  can iterate over the contents. | 
| - | 
| -  SubstList2() does a subst_list, flattens the result, then maps the flattened | 
| -  list to strings. | 
| - | 
| -  It is better to do: | 
| -    for x in env.SubstList2('$MYPARAMS'): | 
| -  than to do: | 
| -    for x in env.get('MYPARAMS', []): | 
| -  and definitely better than: | 
| -    for x in env['MYPARAMS']: | 
| -  which will throw an exception if MYPARAMS isn't defined. | 
| -  """ | 
| -  return map(str, self.Flatten(self.subst_list(args))) | 
| - | 
| - | 
| -#------------------------------------------------------------------------------ | 
| - | 
| - | 
| -def RelativePath(self, source, target, sep=os.sep, source_is_file=False): | 
| -  """Calculates the relative path from source to target. | 
| - | 
| -  Args: | 
| -    self: Environment context. | 
| -    source: Source path or node. | 
| -    target: Target path or node. | 
| -    sep: Path separator to use in returned relative path. | 
| -    source_is_file: If true, calculates the relative path from the directory | 
| -        containing the source, rather than the source itself.  Note that if | 
| -        source is a node, you can pass in source.dir instead, which is shorter. | 
| - | 
| -  Returns: | 
| -    The relative path from source to target. | 
| -  """ | 
| -  # Split source and target into list of directories | 
| -  source = self.Entry(str(source)) | 
| -  if source_is_file: | 
| -    source = source.dir | 
| -  source = source.abspath.split(os.sep) | 
| -  target = self.Entry(str(target)).abspath.split(os.sep) | 
| - | 
| -  # Handle source and target identical | 
| -  if source == target: | 
| -    if source_is_file: | 
| -      return source[-1]         # Bare filename | 
| -    else: | 
| -      return '.'                # Directory pointing to itself | 
| - | 
| -  # TODO(rspangler): Handle UNC paths and drive letters (fine if they're the | 
| -  # same, but if they're different, there IS no relative path) | 
| - | 
| -  # Remove common elements | 
| -  while source and target and source[0] == target[0]: | 
| -    source.pop(0) | 
| -    target.pop(0) | 
| -  # Join the remaining elements | 
| -  return sep.join(['..'] * len(source) + target) | 
| - | 
| - | 
| -#------------------------------------------------------------------------------ | 
| - | 
| - | 
| -def generate(env): | 
| -  # NOTE: SCons requires the use of this name, which fails gpylint. | 
| -  """SCons entry point for this tool.""" | 
| - | 
| -  # Add methods to environment | 
| -  env.AddMethod(ApplySConscript) | 
| -  env.AddMethod(BuildSConscript) | 
| -  env.AddMethod(FilterOut) | 
| -  env.AddMethod(Overlap) | 
| -  env.AddMethod(RelativePath) | 
| -  env.AddMethod(SubstList2) | 
|  |