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