Home | Trees | Indices | Help |
|
---|
|
1 # 2 # Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation 3 # 4 # Permission is hereby granted, free of charge, to any person obtaining 5 # a copy of this software and associated documentation files (the 6 # "Software"), to deal in the Software without restriction, including 7 # without limitation the rights to use, copy, modify, merge, publish, 8 # distribute, sublicense, and/or sell copies of the Software, and to 9 # permit persons to whom the Software is furnished to do so, subject to 10 # the following conditions: 11 # 12 # The above copyright notice and this permission notice shall be included 13 # in all copies or substantial portions of the Software. 14 # 15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY 16 # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 17 # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 19 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 20 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 21 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 # 23 24 __revision__ = "src/engine/SCons/Script/Interactive.py 5110 2010/07/25 16:14:38 bdeegan" 25 26 __doc__ = """ 27 SCons interactive mode 28 """ 29 30 # TODO: 31 # 32 # This has the potential to grow into something with a really big life 33 # of its own, which might or might not be a good thing. Nevertheless, 34 # here are some enhancements that will probably be requested some day 35 # and are worth keeping in mind (assuming this takes off): 36 # 37 # - A command to re-read / re-load the SConscript files. This may 38 # involve allowing people to specify command-line options (e.g. -f, 39 # -I, --no-site-dir) that affect how the SConscript files are read. 40 # 41 # - Additional command-line options on the "build" command. 42 # 43 # Of the supported options that seemed to make sense (after a quick 44 # pass through the list), the ones that seemed likely enough to be 45 # used are listed in the man page and have explicit test scripts. 46 # 47 # These had code changed in Script/Main.py to support them, but didn't 48 # seem likely to be used regularly, so had no test scripts added: 49 # 50 # build --diskcheck=* 51 # build --implicit-cache=* 52 # build --implicit-deps-changed=* 53 # build --implicit-deps-unchanged=* 54 # 55 # These look like they should "just work" with no changes to the 56 # existing code, but like those above, look unlikely to be used and 57 # therefore had no test scripts added: 58 # 59 # build --random 60 # 61 # These I'm not sure about. They might be useful for individual 62 # "build" commands, and may even work, but they seem unlikely enough 63 # that we'll wait until they're requested before spending any time on 64 # writing test scripts for them, or investigating whether they work. 65 # 66 # build -q [??? is there a useful analog to the exit status?] 67 # build --duplicate= 68 # build --profile= 69 # build --max-drift= 70 # build --warn=* 71 # build --Y 72 # 73 # - Most of the SCons command-line options that the "build" command 74 # supports should be settable as default options that apply to all 75 # subsequent "build" commands. Maybe a "set {option}" command that 76 # maps to "SetOption('{option}')". 77 # 78 # - Need something in the 'help' command that prints the -h output. 79 # 80 # - A command to run the configure subsystem separately (must see how 81 # this interacts with the new automake model). 82 # 83 # - Command-line completion of target names; maybe even of SCons options? 84 # Completion is something that's supported by the Python cmd module, 85 # so this should be doable without too much trouble. 86 # 87 88 import cmd 89 import copy 90 import os 91 import re 92 import shlex 93 import string 94 import sys 95 96 try: 97 import readline 98 except ImportError: 99 pass 100102 """\ 103 build [TARGETS] Build the specified TARGETS and their dependencies. 104 'b' is a synonym. 105 clean [TARGETS] Clean (remove) the specified TARGETS and their 106 dependencies. 'c' is a synonym. 107 exit Exit SCons interactive mode. 108 help [COMMAND] Prints help for the specified COMMAND. 'h' and 109 '?' are synonyms. 110 shell [COMMANDLINE] Execute COMMANDLINE in a subshell. 'sh' and '!' 111 are synonyms. 112 version Prints SCons version information. 113 """ 114 115 synonyms = { 116 'b' : 'build', 117 'c' : 'clean', 118 'h' : 'help', 119 'scons' : 'build', 120 'sh' : 'shell', 121 } 122227 228 def add_to_seen_nodes(node, parent, seen_nodes=seen_nodes): 229 seen_nodes[node] = 1 230 231 # If this file is in a VariantDir and has a 232 # corresponding source file in the source tree, remember the 233 # node in the source tree, too. This is needed in 234 # particular to clear cached implicit dependencies on the 235 # source file, since the scanner will scan it if the 236 # VariantDir was created with duplicate=0. 237 try: 238 rfile_method = node.rfile 239 except AttributeError: 240 return 241 else: 242 rfile = rfile_method() 243 if rfile != node: 244 seen_nodes[rfile] = 1 245 246 for node in nodes: 247 walker = SCons.Node.Walker(node, 248 kids_func=get_unseen_children, 249 eval_func=add_to_seen_nodes) 250 n = walker.next() 251 while n: 252 n = walker.next() 253 254 for node in seen_nodes.keys(): 255 # Call node.clear() to clear most of the state 256 node.clear() 257 # node.clear() doesn't reset node.state, so call 258 # node.set_state() to reset it manually 259 node.set_state(SCons.Node.no_state) 260 node.implicit = None 261 262 # Debug: Uncomment to verify that all Taskmaster reference 263 # counts have been reset to zero. 264 #if node.ref_count != 0: 265 # from SCons.Debug import Trace 266 # Trace('node %s, ref_count %s !!!\n' % (node, node.ref_count)) 267 268 SCons.SConsign.Reset() 269 SCons.Script.Main.progress_display("scons: done clearing node information.") 270124 cmd.Cmd.__init__(self) 125 for key, val in kw.items(): 126 setattr(self, key, val) 127 128 if sys.platform == 'win32': 129 self.shell_variable = 'COMSPEC' 130 else: 131 self.shell_variable = 'SHELL'132 135137 line = string.strip(line) 138 if not line: 139 print self.lastcmd 140 return self.emptyline() 141 self.lastcmd = line 142 if line[0] == '!': 143 line = 'shell ' + line[1:] 144 elif line[0] == '?': 145 line = 'help ' + line[1:] 146 if os.sep == '\\': 147 line = string.replace(line, '\\', '\\\\') 148 argv = shlex.split(line) 149 argv[0] = self.synonyms.get(argv[0], argv[0]) 150 if not argv[0]: 151 return self.default(line) 152 else: 153 try: 154 func = getattr(self, 'do_' + argv[0]) 155 except AttributeError: 156 return self.default(argv) 157 return func(argv)158160 """\ 161 build [TARGETS] Build the specified TARGETS and their 162 dependencies. 'b' is a synonym. 163 """ 164 import SCons.Node 165 import SCons.SConsign 166 import SCons.Script.Main 167 168 options = copy.deepcopy(self.options) 169 170 options, targets = self.parser.parse_args(argv[1:], values=options) 171 172 SCons.Script.COMMAND_LINE_TARGETS = targets 173 174 if targets: 175 SCons.Script.BUILD_TARGETS = targets 176 else: 177 # If the user didn't specify any targets on the command line, 178 # use the list of default targets. 179 SCons.Script.BUILD_TARGETS = SCons.Script._build_plus_default 180 181 nodes = SCons.Script.Main._build_targets(self.fs, 182 options, 183 targets, 184 self.target_top) 185 186 if not nodes: 187 return 188 189 # Call each of the Node's alter_targets() methods, which may 190 # provide additional targets that ended up as part of the build 191 # (the canonical example being a VariantDir() when we're building 192 # from a source directory) and which we therefore need their 193 # state cleared, too. 194 x = [] 195 for n in nodes: 196 x.extend(n.alter_targets()[0]) 197 nodes.extend(x) 198 199 # Clean up so that we can perform the next build correctly. 200 # 201 # We do this by walking over all the children of the targets, 202 # and clearing their state. 203 # 204 # We currently have to re-scan each node to find their 205 # children, because built nodes have already been partially 206 # cleared and don't remember their children. (In scons 207 # 0.96.1 and earlier, this wasn't the case, and we didn't 208 # have to re-scan the nodes.) 209 # 210 # Because we have to re-scan each node, we can't clear the 211 # nodes as we walk over them, because we may end up rescanning 212 # a cleared node as we scan a later node. Therefore, only 213 # store the list of nodes that need to be cleared as we walk 214 # the tree, and clear them in a separate pass. 215 # 216 # XXX: Someone more familiar with the inner workings of scons 217 # may be able to point out a more efficient way to do this. 218 219 SCons.Script.Main.progress_display("scons: Clearing cached node information ...") 220 221 seen_nodes = {} 222 223 def get_unseen_children(node, parent, seen_nodes=seen_nodes): 224 def is_unseen(node, seen_nodes=seen_nodes): 225 return not seen_nodes.has_key(node)226 return filter(is_unseen, node.children(scan=1))272 """\ 273 clean [TARGETS] Clean (remove) the specified TARGETS 274 and their dependencies. 'c' is a synonym. 275 """ 276 return self.do_build(['build', '--clean'] + argv[1:])277 281283 try: 284 # If help_<arg>() exists, then call it. 285 func = getattr(self, 'help_' + arg) 286 except AttributeError: 287 try: 288 func = getattr(self, 'do_' + arg) 289 except AttributeError: 290 doc = None 291 else: 292 doc = self._doc_to_help(func) 293 if doc: 294 sys.stdout.write(doc + '\n') 295 sys.stdout.flush() 296 else: 297 doc = self.strip_initial_spaces(func()) 298 if doc: 299 sys.stdout.write(doc + '\n') 300 sys.stdout.flush()301 307309 #lines = s.split('\n') 310 lines = string.split(s, '\n') 311 spaces = re.match(' *', lines[0]).group(0) 312 #def strip_spaces(l): 313 # if l.startswith(spaces): 314 # l = l[len(spaces):] 315 # return l 316 #return '\n'.join([ strip_spaces(l) for l in lines ]) 317 def strip_spaces(l, spaces=spaces): 318 if l[:len(spaces)] == spaces: 319 l = l[len(spaces):] 320 return l321 lines = map(strip_spaces, lines) 322 return string.join(lines, '\n') 323 329331 """\ 332 help [COMMAND] Prints help for the specified COMMAND. 'h' 333 and '?' are synonyms. 334 """ 335 if argv[1:]: 336 for arg in argv[1:]: 337 if self._do_one_help(arg): 338 break 339 else: 340 # If bare 'help' is called, print this class's doc 341 # string (if it has one). 342 doc = self._doc_to_help(self.__class__) 343 if doc: 344 sys.stdout.write(doc + '\n') 345 sys.stdout.flush()346348 """\ 349 shell [COMMANDLINE] Execute COMMANDLINE in a subshell. 'sh' and 350 '!' are synonyms. 351 """ 352 import subprocess 353 argv = argv[1:] 354 if not argv: 355 argv = os.environ[self.shell_variable] 356 try: 357 # Per "[Python-Dev] subprocess insufficiently platform-independent?" 358 # http://mail.python.org/pipermail/python-dev/2008-August/081979.html "+ 359 # Doing the right thing with an argument list currently 360 # requires different shell= values on Windows and Linux. 361 p = subprocess.Popen(argv, shell=(sys.platform=='win32')) 362 except EnvironmentError, e: 363 sys.stderr.write('scons: %s: %s\n' % (argv[0], e.strerror)) 364 else: 365 p.wait()366368 """\ 369 version Prints SCons version information. 370 """ 371 sys.stdout.write(self.parser.version + '\n')372374 c = SConsInteractiveCmd(prompt = 'scons>>> ', 375 fs = fs, 376 parser = parser, 377 options = options, 378 targets = targets, 379 target_top = target_top) 380 c.cmdloop()381 382 # Local Variables: 383 # tab-width:4 384 # indent-tabs-mode:nil 385 # End: 386 # vim: set expandtab tabstop=4 shiftwidth=4: 387
Home | Trees | Indices | Help |
|
---|
Generated by Epydoc 3.0.1 on Sun Jul 25 16:21:32 2010 | http://epydoc.sourceforge.net |