SCons.Script

Package SCons :: Package Script |
[hide private]
[frames] | no frames]

# Source Code for Package SCons.Script

      1  """SCons.Script
      2
      3  This file implements the main() function used by the scons script.
      4
      5  Architecturally, this *is* the scons script, and will likely only be
      6  called from the external "scons" wrapper.  Consequently, anything here
      7  should not be, or be considered, part of the build engine.  If it's
      8  something that we expect other software to want to use, it should go in
      9  some other module.  If it's specific to the "scons" script invocation,
     10  it goes here.
     11
     12  """
     13
     14  #
     15  # Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
     16  #
     17  # Permission is hereby granted, free of charge, to any person obtaining
     18  # a copy of this software and associated documentation files (the
     19  # "Software"), to deal in the Software without restriction, including
     20  # without limitation the rights to use, copy, modify, merge, publish,
     21  # distribute, sublicense, and/or sell copies of the Software, and to
     22  # permit persons to whom the Software is furnished to do so, subject to
     23  # the following conditions:
     24  #
     25  # The above copyright notice and this permission notice shall be included
     26  # in all copies or substantial portions of the Software.
     27  #
     28  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
     29  # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
     30  # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     31  # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
     32  # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
     33  # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
     34  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     35  #
     36
     37  __revision__ = "src/engine/SCons/Script/__init__.py 2725 2008/03/31 12:52:02 knight"
     38
     39  import time
     40  start_time = time.time()
     41
     42  import os
     43  import string
     44  import sys
     45  import UserList
     46
     47  # Special chicken-and-egg handling of the "--debug=memoizer" flag:
     48  #
     49  # SCons.Memoize contains a metaclass implementation that affects how
     50  # the other classes are instantiated.  The Memoizer may add shim methods
     51  # to classes that have methods that cache computed values in order to
     52  # count and report the hits and misses.
     53  #
     54  # If we wait to enable the Memoization until after we've parsed the
     55  # command line options normally, it will be too late, because the Memoizer
     56  # will have already analyzed the classes that it's Memoizing and decided
     57  # to not add the shims.  So we use a special-case, up-front check for
     58  # the "--debug=memoizer" flag and enable Memoizer before we import any
     59  # of the other modules that use it.
     60
     61  _args = sys.argv + string.split(os.environ.get('SCONSFLAGS', ''))
     62  if "--debug=memoizer" in _args:
     63      import SCons.Memoize
     64      import SCons.Warnings
     65      try:
     66          SCons.Memoize.EnableMemoization()
     67      except SCons.Warnings.Warning:
     68          # Some warning was thrown (inability to --debug=memoizer on
     69          # Python 1.5.2 because it doesn't have metaclasses).  Arrange
     70          # for it to be displayed or not after warnings are configured.
     71          import Main
     72          exc_type, exc_value, tb = sys.exc_info()
     73          Main.delayed_warnings.append((exc_type, exc_value))
     74  del _args
     75
     76  import SCons.Action
     77  import SCons.Builder
     78  import SCons.Environment
     79  import SCons.Node.FS
     80  import SCons.Options
     81  import SCons.Platform
     82  import SCons.Scanner
     83  import SCons.SConf
     84  import SCons.Subst
     85  import SCons.Tool
     86  import SCons.Util
     87  import SCons.Defaults
     88
     89  import Main
     90
     91  main                    = Main.main
     92
     93  # The following are global class definitions and variables that used to
     94  # live directly in this module back before 0.96.90, when it contained
     95  # a lot of code.  Some SConscript files in widely-distributed packages
     96  # (Blender is the specific example) actually reached into SCons.Script
     97  # directly to use some of these.  Rather than break those SConscript
     98  # files, we're going to propagate these names into the SCons.Script
     99  # namespace here.
    100  #
    101  # Some of these are commented out because it's *really* unlikely anyone
    102  # used them, but we're going to leave the comment here to try to make
    103  # it obvious what to do if the situation arises.
    104  BuildTask               = Main.BuildTask
    105  CleanTask               = Main.CleanTask
    106  QuestionTask            = Main.QuestionTask
    107  #PrintHelp               = Main.PrintHelp
    108  #SConscriptSettableOptions = Main.SConscriptSettableOptions
    109
    110  AddOption               = Main.AddOption
    111  GetOption               = Main.GetOption
    112  SetOption               = Main.SetOption
    113  Progress                = Main.Progress
    114  GetBuildFailures        = Main.GetBuildFailures
    115
    116  #keep_going_on_error     = Main.keep_going_on_error
    117  #print_dtree             = Main.print_dtree
    118  #print_explanations      = Main.print_explanations
    119  #print_includes          = Main.print_includes
    120  #print_objects           = Main.print_objects
    121  #print_time              = Main.print_time
    122  #print_tree              = Main.print_tree
    123  #memory_stats            = Main.memory_stats
    124  #ignore_errors           = Main.ignore_errors
    125  #sconscript_time         = Main.sconscript_time
    126  #command_time            = Main.command_time
    127  #exit_status             = Main.exit_status
    128  #profiling               = Main.profiling
    129  #repositories            = Main.repositories
    130
    131  #
    132  import SConscript
    133  _SConscript = SConscript
    134
    135  call_stack              = _SConscript.call_stack
    136
    137  #
    138  Action                  = SCons.Action.Action
    139  AddMethod               = SCons.Util.AddMethod
    140  AllowSubstExceptions    = SCons.Subst.SetAllowableExceptions
    141  BoolOption              = SCons.Options.BoolOption
    142  Builder                 = SCons.Builder.Builder
    143  Configure               = _SConscript.Configure
    144  EnumOption              = SCons.Options.EnumOption
    145  Environment             = SCons.Environment.Environment
    146  #OptParser               = SCons.SConsOptions.OptParser
    147  FindPathDirs            = SCons.Scanner.FindPathDirs
    148  ListOption              = SCons.Options.ListOption
    149  PackageOption           = SCons.Options.PackageOption
    150  PathOption              = SCons.Options.PathOption
    151  Platform                = SCons.Platform.Platform
    152  Return                  = _SConscript.Return
    153  Scanner                 = SCons.Scanner.Base
    154  Tool                    = SCons.Tool.Tool
    155  WhereIs                 = SCons.Util.WhereIs
    156
    157  # Action factories.
    158  Chmod                   = SCons.Defaults.Chmod
    159  Copy                    = SCons.Defaults.Copy
    160  Delete                  = SCons.Defaults.Delete
    161  Mkdir                   = SCons.Defaults.Mkdir
    162  Move                    = SCons.Defaults.Move
    163  Touch                   = SCons.Defaults.Touch
    164
    165  # Pre-made, public scanners.
    166  CScanner                = SCons.Tool.CScanner
    167  DScanner                = SCons.Tool.DScanner
    168  DirScanner              = SCons.Defaults.DirScanner
    169  ProgramScanner          = SCons.Tool.ProgramScanner
    170  SourceFileScanner       = SCons.Tool.SourceFileScanner
    171
    172  # Functions we might still convert to Environment methods.
    173  CScan                   = SCons.Defaults.CScan
    174  DefaultEnvironment      = SCons.Defaults.DefaultEnvironment
    175
    176  # Other variables we provide.
    177 -class TargetList(UserList.UserList):
    178 -    def _do_nothing(self, *args, **kw):
    179          pass
    180 -    def _add_Default(self, list):
    181          self.extend(list)
    182 -    def _clear(self):
    183          del self[:]
    184
    185  ARGUMENTS               = {}
    186  ARGLIST                 = []
    187  BUILD_TARGETS           = TargetList()
    188  COMMAND_LINE_TARGETS    = []
    189  DEFAULT_TARGETS         = []
    190
    191  # BUILD_TARGETS can be modified in the SConscript files.  If so, we
    192  # want to treat the modified BUILD_TARGETS list as if they specified
    193  # targets on the command line.  To do that, though, we need to know if
    194  # BUILD_TARGETS was modified through "official" APIs or by hand.  We do
    195  # this by updating two lists in parallel, the documented BUILD_TARGETS
    196  # list, above, and this internal _build_plus_default targets list which
    197  # should only have "official" API changes.  Then Script/Main.py can
    198  # compare these two afterwards to figure out if the user added their
    199  # own targets to BUILD_TARGETS.
    200  _build_plus_default = TargetList()
    201
    202 -def _Add_Arguments(alist):
    203      for arg in alist:
    204          a, b = string.split(arg, '=', 1)
    205          ARGUMENTS[a] = b
    206          ARGLIST.append((a, b))
    207
    208 -def _Add_Targets(tlist):
    209      if tlist:
    210          COMMAND_LINE_TARGETS.extend(tlist)
    211          BUILD_TARGETS.extend(tlist)
    212          BUILD_TARGETS._add_Default = BUILD_TARGETS._do_nothing
    213          BUILD_TARGETS._clear = BUILD_TARGETS._do_nothing
    214          _build_plus_default.extend(tlist)
    215          _build_plus_default._add_Default = _build_plus_default._do_nothing
    216          _build_plus_default._clear = _build_plus_default._do_nothing
    217
    218 -def _Set_Default_Targets_Has_Been_Called(d, fs):
    219      return DEFAULT_TARGETS
    220
    221 -def _Set_Default_Targets_Has_Not_Been_Called(d, fs):
    222      if d is None:
    223          d = [fs.Dir('.')]
    224      return d
    225
    226  _Get_Default_Targets = _Set_Default_Targets_Has_Not_Been_Called
    227
    228 -def _Set_Default_Targets(env, tlist):
    229      global DEFAULT_TARGETS
    230      global _Get_Default_Targets
    231      _Get_Default_Targets = _Set_Default_Targets_Has_Been_Called
    232      for t in tlist:
    233          if t is None:
    234              # Delete the elements from the list in-place, don't
    235              # reassign an empty list to DEFAULT_TARGETS, so that the
    236              # variables will still point to the same object we point to.
    237              del DEFAULT_TARGETS[:]
    238              BUILD_TARGETS._clear()
    239              _build_plus_default._clear()
    240          elif isinstance(t, SCons.Node.Node):
    241              DEFAULT_TARGETS.append(t)
    242              BUILD_TARGETS._add_Default([t])
    243              _build_plus_default._add_Default([t])
    244          else:
    245              nodes = env.arg2nodes(t, env.fs.Entry)
    246              DEFAULT_TARGETS.extend(nodes)
    247              BUILD_TARGETS._add_Default(nodes)
    248              _build_plus_default._add_Default(nodes)
    249
    250  #
    251  help_text = None
    252
    253 -def HelpFunction(text):
    254      global help_text
    255      if SCons.Script.help_text is None:
    256          SCons.Script.help_text = text
    257      else:
    258          help_text = help_text + text
    259
    260  #
    261  # Will be non-zero if we are reading an SConscript file.
    262  sconscript_reading = 0
    263
    264  #
    265 -def Options(files=[], args=ARGUMENTS):
    266      return SCons.Options.Options(files, args)
    267
    268  # The list of global functions to add to the SConscript name space
    269  # that end up calling corresponding methods or Builders in the
    270  # DefaultEnvironment().
    271  GlobalDefaultEnvironmentFunctions = [
    272      # Methods from the SConsEnvironment class, above.
    273      'Default',
    274      'EnsurePythonVersion',
    275      'EnsureSConsVersion',
    276      'Exit',
    277      'Export',
    278      'GetLaunchDir',
    279      'Help',
    280      'Import',
    281      #'SConscript', is handled separately, below.
    282      'SConscriptChdir',
    283
    284      # Methods from the Environment.Base class.
    285      'AddPostAction',
    286      'AddPreAction',
    287      'Alias',
    288      'AlwaysBuild',
    289      'BuildDir',
    290      'CacheDir',
    291      'Clean',
    292      #The Command() method is handled separately, below.
    293      'Decider',
    294      'Depends',
    295      'Dir',
    296      'NoClean',
    297      'NoCache',
    298      'Entry',
    299      'Execute',
    300      'File',
    301      'FindFile',
    302      'FindInstalledFiles',
    303      'FindSourceFiles',
    304      'Flatten',
    305      'GetBuildPath',
    306      'Glob',
    307      'Ignore',
    308      'Install',
    309      'InstallAs',
    310      'Literal',
    311      'Local',
    312      'ParseDepends',
    313      'Precious',
    314      'Repository',
    315      'Requires',
    316      'SConsignFile',
    317      'SideEffect',
    318      'SourceCode',
    319      'SourceSignatures',
    320      'Split',
    321      'Tag',
    322      'TargetSignatures',
    323      'Value',
    324      'VariantDir',
    325  ]
    326
    327  GlobalDefaultBuilders = [
    328      # Supported builders.
    329      'CFile',
    330      'CXXFile',
    331      'DVI',
    332      'Jar',
    333      'Java',
    334      'JavaH',
    335      'Library',
    336      'M4',
    337      'MSVSProject',
    338      'Object',
    339      'PCH',
    340      'PDF',
    341      'PostScript',
    342      'Program',
    343      'RES',
    344      'RMIC',
    345      'SharedLibrary',
    346      'SharedObject',
    347      'StaticLibrary',
    348      'StaticObject',
    349      'Tar',
    350      'TypeLibrary',
    351      'Zip',
    352      'Package',
    353  ]
    354
    355  for name in GlobalDefaultEnvironmentFunctions + GlobalDefaultBuilders:
    356      exec "%s = _SConscript.DefaultEnvironmentCall(%s)" % (name, repr(name))
    357  del name
    358
    359  # There are a handful of variables that used to live in the
    360  # Script/SConscript.py module that some SConscript files out there were
    361  # accessing directly as SCons.Script.SConscript.*.  The problem is that
    362  # "SConscript" in this namespace is no longer a module, it's a global
    363  # function call--or more precisely, an object that implements a global
    364  # function call through the default Environment.  Nevertheless, we can
    365  # maintain backwards compatibility for SConscripts that were reaching in
    366  # this way by hanging some attributes off the "SConscript" object here.
    367  SConscript = _SConscript.DefaultEnvironmentCall('SConscript')
    368
    369  # Make SConscript look enough like the module it used to be so
    370  # that pychecker doesn't barf.
    371  SConscript.__name__ = 'SConscript'
    372
    373  SConscript.Arguments = ARGUMENTS
    374  SConscript.ArgList = ARGLIST
    375  SConscript.BuildTargets = BUILD_TARGETS
    376  SConscript.CommandLineTargets = COMMAND_LINE_TARGETS
    377  SConscript.DefaultTargets = DEFAULT_TARGETS
    378
    379  # The global Command() function must be handled differently than the
    380  # global functions for other construction environment methods because
    381  # we want people to be able to use Actions that must expand $TARGET
    382  # and $SOURCE later, when (and if) the Action is invoked to build
    383  # the target(s).  We do this with the subst=1 argument, which creates
    384  # a DefaultEnvironmentCall instance that wraps up a normal default
    385  # construction environment that performs variable substitution, not a
    386  # proxy that doesn't.
    387  #
    388  # There's a flaw here, though, because any other $-variables on a command
    389  # line will *also* be expanded, each to a null string, but that should
    390  # only be a problem in the unusual case where someone was passing a '$'
    391  # on a command line and *expected* the $ to get through to the shell
    392  # because they were calling Command() and not env.Command()...  This is
    393  # unlikely enough that we're going to leave this as is and cross that
    394  # bridge if someone actually comes to it.
    395  Command = _SConscript.DefaultEnvironmentCall('Command', subst=1)
    396