ad999913136d25aeedcf77160836b421cce08d93
[senf.git] / scons / scons-1.2.0 / engine / SCons / Script / __init__.py
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 3842 2008/12/20 22:59:52 scons"
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.Variables
88 import SCons.Defaults
89
90 import Main
91
92 main                    = Main.main
93
94 # The following are global class definitions and variables that used to
95 # live directly in this module back before 0.96.90, when it contained
96 # a lot of code.  Some SConscript files in widely-distributed packages
97 # (Blender is the specific example) actually reached into SCons.Script
98 # directly to use some of these.  Rather than break those SConscript
99 # files, we're going to propagate these names into the SCons.Script
100 # namespace here.
101 #
102 # Some of these are commented out because it's *really* unlikely anyone
103 # used them, but we're going to leave the comment here to try to make
104 # it obvious what to do if the situation arises.
105 BuildTask               = Main.BuildTask
106 CleanTask               = Main.CleanTask
107 QuestionTask            = Main.QuestionTask
108 #PrintHelp               = Main.PrintHelp
109 #SConscriptSettableOptions = Main.SConscriptSettableOptions
110
111 AddOption               = Main.AddOption
112 GetOption               = Main.GetOption
113 SetOption               = Main.SetOption
114 Progress                = Main.Progress
115 GetBuildFailures        = Main.GetBuildFailures
116
117 #keep_going_on_error     = Main.keep_going_on_error
118 #print_dtree             = Main.print_dtree
119 #print_explanations      = Main.print_explanations
120 #print_includes          = Main.print_includes
121 #print_objects           = Main.print_objects
122 #print_time              = Main.print_time
123 #print_tree              = Main.print_tree
124 #memory_stats            = Main.memory_stats
125 #ignore_errors           = Main.ignore_errors
126 #sconscript_time         = Main.sconscript_time
127 #command_time            = Main.command_time
128 #exit_status             = Main.exit_status
129 #profiling               = Main.profiling
130 #repositories            = Main.repositories
131
132 #
133 import SConscript
134 _SConscript = SConscript
135
136 call_stack              = _SConscript.call_stack
137
138 #
139 Action                  = SCons.Action.Action
140 AddMethod               = SCons.Util.AddMethod
141 AllowSubstExceptions    = SCons.Subst.SetAllowableExceptions
142 Builder                 = SCons.Builder.Builder
143 Configure               = _SConscript.Configure
144 Environment             = SCons.Environment.Environment
145 #OptParser               = SCons.SConsOptions.OptParser
146 FindPathDirs            = SCons.Scanner.FindPathDirs
147 Platform                = SCons.Platform.Platform
148 Return                  = _SConscript.Return
149 Scanner                 = SCons.Scanner.Base
150 Tool                    = SCons.Tool.Tool
151 WhereIs                 = SCons.Util.WhereIs
152
153 #
154 BoolVariable            = SCons.Variables.BoolVariable
155 EnumVariable            = SCons.Variables.EnumVariable
156 ListVariable            = SCons.Variables.ListVariable
157 PackageVariable         = SCons.Variables.PackageVariable
158 PathVariable            = SCons.Variables.PathVariable
159
160 # Deprecated names that will go away some day.
161 BoolOption              = SCons.Options.BoolOption
162 EnumOption              = SCons.Options.EnumOption
163 ListOption              = SCons.Options.ListOption
164 PackageOption           = SCons.Options.PackageOption
165 PathOption              = SCons.Options.PathOption
166
167 # Action factories.
168 Chmod                   = SCons.Defaults.Chmod
169 Copy                    = SCons.Defaults.Copy
170 Delete                  = SCons.Defaults.Delete
171 Mkdir                   = SCons.Defaults.Mkdir
172 Move                    = SCons.Defaults.Move
173 Touch                   = SCons.Defaults.Touch
174
175 # Pre-made, public scanners.
176 CScanner                = SCons.Tool.CScanner
177 DScanner                = SCons.Tool.DScanner
178 DirScanner              = SCons.Defaults.DirScanner
179 ProgramScanner          = SCons.Tool.ProgramScanner
180 SourceFileScanner       = SCons.Tool.SourceFileScanner
181
182 # Functions we might still convert to Environment methods.
183 CScan                   = SCons.Defaults.CScan
184 DefaultEnvironment      = SCons.Defaults.DefaultEnvironment
185
186 # Other variables we provide.
187 class TargetList(UserList.UserList):
188     def _do_nothing(self, *args, **kw):
189         pass
190     def _add_Default(self, list):
191         self.extend(list)
192     def _clear(self):
193         del self[:]
194
195 ARGUMENTS               = {}
196 ARGLIST                 = []
197 BUILD_TARGETS           = TargetList()
198 COMMAND_LINE_TARGETS    = []
199 DEFAULT_TARGETS         = []
200
201 # BUILD_TARGETS can be modified in the SConscript files.  If so, we
202 # want to treat the modified BUILD_TARGETS list as if they specified
203 # targets on the command line.  To do that, though, we need to know if
204 # BUILD_TARGETS was modified through "official" APIs or by hand.  We do
205 # this by updating two lists in parallel, the documented BUILD_TARGETS
206 # list, above, and this internal _build_plus_default targets list which
207 # should only have "official" API changes.  Then Script/Main.py can
208 # compare these two afterwards to figure out if the user added their
209 # own targets to BUILD_TARGETS.
210 _build_plus_default = TargetList()
211
212 def _Add_Arguments(alist):
213     for arg in alist:
214         a, b = string.split(arg, '=', 1)
215         ARGUMENTS[a] = b
216         ARGLIST.append((a, b))
217
218 def _Add_Targets(tlist):
219     if tlist:
220         COMMAND_LINE_TARGETS.extend(tlist)
221         BUILD_TARGETS.extend(tlist)
222         BUILD_TARGETS._add_Default = BUILD_TARGETS._do_nothing
223         BUILD_TARGETS._clear = BUILD_TARGETS._do_nothing
224         _build_plus_default.extend(tlist)
225         _build_plus_default._add_Default = _build_plus_default._do_nothing
226         _build_plus_default._clear = _build_plus_default._do_nothing
227
228 def _Set_Default_Targets_Has_Been_Called(d, fs):
229     return DEFAULT_TARGETS
230
231 def _Set_Default_Targets_Has_Not_Been_Called(d, fs):
232     if d is None:
233         d = [fs.Dir('.')]
234     return d
235
236 _Get_Default_Targets = _Set_Default_Targets_Has_Not_Been_Called
237
238 def _Set_Default_Targets(env, tlist):
239     global DEFAULT_TARGETS
240     global _Get_Default_Targets
241     _Get_Default_Targets = _Set_Default_Targets_Has_Been_Called
242     for t in tlist:
243         if t is None:
244             # Delete the elements from the list in-place, don't
245             # reassign an empty list to DEFAULT_TARGETS, so that the
246             # variables will still point to the same object we point to.
247             del DEFAULT_TARGETS[:]
248             BUILD_TARGETS._clear()
249             _build_plus_default._clear()
250         elif isinstance(t, SCons.Node.Node):
251             DEFAULT_TARGETS.append(t)
252             BUILD_TARGETS._add_Default([t])
253             _build_plus_default._add_Default([t])
254         else:
255             nodes = env.arg2nodes(t, env.fs.Entry)
256             DEFAULT_TARGETS.extend(nodes)
257             BUILD_TARGETS._add_Default(nodes)
258             _build_plus_default._add_Default(nodes)
259
260 #
261 help_text = None
262
263 def HelpFunction(text):
264     global help_text
265     if SCons.Script.help_text is None:
266         SCons.Script.help_text = text
267     else:
268         help_text = help_text + text
269
270 #
271 # Will be non-zero if we are reading an SConscript file.
272 sconscript_reading = 0
273
274 #
275 def Variables(files=[], args=ARGUMENTS):
276     return SCons.Variables.Variables(files, args)
277
278 def Options(files=[], args=ARGUMENTS):
279     return SCons.Options.Options(files, args)
280
281 # The list of global functions to add to the SConscript name space
282 # that end up calling corresponding methods or Builders in the
283 # DefaultEnvironment().
284 GlobalDefaultEnvironmentFunctions = [
285     # Methods from the SConsEnvironment class, above.
286     'Default',
287     'EnsurePythonVersion',
288     'EnsureSConsVersion',
289     'Exit',
290     'Export',
291     'GetLaunchDir',
292     'Help',
293     'Import',
294     #'SConscript', is handled separately, below.
295     'SConscriptChdir',
296
297     # Methods from the Environment.Base class.
298     'AddPostAction',
299     'AddPreAction',
300     'Alias',
301     'AlwaysBuild',
302     'BuildDir',
303     'CacheDir',
304     'Clean',
305     #The Command() method is handled separately, below.
306     'Decider',
307     'Depends',
308     'Dir',
309     'NoClean',
310     'NoCache',
311     'Entry',
312     'Execute',
313     'File',
314     'FindFile',
315     'FindInstalledFiles',
316     'FindSourceFiles',
317     'Flatten',
318     'GetBuildPath',
319     'Glob',
320     'Ignore',
321     'Install',
322     'InstallAs',
323     'Literal',
324     'Local',
325     'ParseDepends',
326     'Precious',
327     'Repository',
328     'Requires',
329     'SConsignFile',
330     'SideEffect',
331     'SourceCode',
332     'SourceSignatures',
333     'Split',
334     'Tag',
335     'TargetSignatures',
336     'Value',
337     'VariantDir',
338 ]
339
340 GlobalDefaultBuilders = [
341     # Supported builders.
342     'CFile',
343     'CXXFile',
344     'DVI',
345     'Jar',
346     'Java',
347     'JavaH',
348     'Library',
349     'M4',
350     'MSVSProject',
351     'Object',
352     'PCH',
353     'PDF',
354     'PostScript',
355     'Program',
356     'RES',
357     'RMIC',
358     'SharedLibrary',
359     'SharedObject',
360     'StaticLibrary',
361     'StaticObject',
362     'Tar',
363     'TypeLibrary',
364     'Zip',
365     'Package',
366 ]
367
368 for name in GlobalDefaultEnvironmentFunctions + GlobalDefaultBuilders:
369     exec "%s = _SConscript.DefaultEnvironmentCall(%s)" % (name, repr(name))
370 del name
371
372 # There are a handful of variables that used to live in the
373 # Script/SConscript.py module that some SConscript files out there were
374 # accessing directly as SCons.Script.SConscript.*.  The problem is that
375 # "SConscript" in this namespace is no longer a module, it's a global
376 # function call--or more precisely, an object that implements a global
377 # function call through the default Environment.  Nevertheless, we can
378 # maintain backwards compatibility for SConscripts that were reaching in
379 # this way by hanging some attributes off the "SConscript" object here.
380 SConscript = _SConscript.DefaultEnvironmentCall('SConscript')
381
382 # Make SConscript look enough like the module it used to be so
383 # that pychecker doesn't barf.
384 SConscript.__name__ = 'SConscript'
385
386 SConscript.Arguments = ARGUMENTS
387 SConscript.ArgList = ARGLIST
388 SConscript.BuildTargets = BUILD_TARGETS
389 SConscript.CommandLineTargets = COMMAND_LINE_TARGETS
390 SConscript.DefaultTargets = DEFAULT_TARGETS
391
392 # The global Command() function must be handled differently than the
393 # global functions for other construction environment methods because
394 # we want people to be able to use Actions that must expand $TARGET
395 # and $SOURCE later, when (and if) the Action is invoked to build
396 # the target(s).  We do this with the subst=1 argument, which creates
397 # a DefaultEnvironmentCall instance that wraps up a normal default
398 # construction environment that performs variable substitution, not a
399 # proxy that doesn't.
400 #
401 # There's a flaw here, though, because any other $-variables on a command
402 # line will *also* be expanded, each to a null string, but that should
403 # only be a problem in the unusual case where someone was passing a '$'
404 # on a command line and *expected* the $ to get through to the shell
405 # because they were calling Command() and not env.Command()...  This is
406 # unlikely enough that we're going to leave this as is and cross that
407 # bridge if someone actually comes to it.
408 Command = _SConscript.DefaultEnvironmentCall('Command', subst=1)