Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(175)

Side by Side Diff: third_party/scons/scons-local/SCons/Action.py

Issue 20025: Update SCons to latest checkpoint release, 1.2.0.d20090113.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 11 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « third_party/scons/scons-README ('k') | third_party/scons/scons-local/SCons/Builder.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 """SCons.Action 1 """SCons.Action
2 2
3 This encapsulates information about executing any sort of action that 3 This encapsulates information about executing any sort of action that
4 can build one or more target Nodes (typically files) from one or more 4 can build one or more target Nodes (typically files) from one or more
5 source Nodes (also typically files) given a specific Environment. 5 source Nodes (also typically files) given a specific Environment.
6 6
7 The base class here is ActionBase. The base class supplies just a few 7 The base class here is ActionBase. The base class supplies just a few
8 OO utility methods and some generic methods for displaying information 8 OO utility methods and some generic methods for displaying information
9 about an Action in response to the various commands that control printing. 9 about an Action in response to the various commands that control printing.
10 10
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 There is a related independent ActionCaller class that looks like a 69 There is a related independent ActionCaller class that looks like a
70 regular Action, and which serves as a wrapper for arbitrary functions 70 regular Action, and which serves as a wrapper for arbitrary functions
71 that we want to let the user specify the arguments to now, but actually 71 that we want to let the user specify the arguments to now, but actually
72 execute later (when an out-of-date check determines that it's needed to 72 execute later (when an out-of-date check determines that it's needed to
73 be executed, for example). Objects of this class are returned by an 73 be executed, for example). Objects of this class are returned by an
74 ActionFactory class that provides a __call__() method as a convenient 74 ActionFactory class that provides a __call__() method as a convenient
75 way for wrapping up the functions. 75 way for wrapping up the functions.
76 76
77 """ 77 """
78 78
79 # Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundat ion 79 # Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons F oundation
80 # 80 #
81 # Permission is hereby granted, free of charge, to any person obtaining 81 # Permission is hereby granted, free of charge, to any person obtaining
82 # a copy of this software and associated documentation files (the 82 # a copy of this software and associated documentation files (the
83 # "Software"), to deal in the Software without restriction, including 83 # "Software"), to deal in the Software without restriction, including
84 # without limitation the rights to use, copy, modify, merge, publish, 84 # without limitation the rights to use, copy, modify, merge, publish,
85 # distribute, sublicense, and/or sell copies of the Software, and to 85 # distribute, sublicense, and/or sell copies of the Software, and to
86 # permit persons to whom the Software is furnished to do so, subject to 86 # permit persons to whom the Software is furnished to do so, subject to
87 # the following conditions: 87 # the following conditions:
88 # 88 #
89 # The above copyright notice and this permission notice shall be included 89 # The above copyright notice and this permission notice shall be included
90 # in all copies or substantial portions of the Software. 90 # in all copies or substantial portions of the Software.
91 # 91 #
92 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY 92 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
93 # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 93 # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
94 # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 94 # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
95 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 95 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
96 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 96 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
97 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 97 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
98 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 98 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
99 99
100 __revision__ = "src/engine/SCons/Action.py 3842 2008/12/20 22:59:52 scons" 100 __revision__ = "src/engine/SCons/Action.py 3897 2009/01/13 06:45:54 scons"
101 101
102 import cPickle 102 import cPickle
103 import dis 103 import dis
104 import os 104 import os
105 import string 105 import string
106 import sys 106 import sys
107 import subprocess 107 import subprocess
108 108
109 from SCons.Debug import logInstanceCreation 109 from SCons.Debug import logInstanceCreation
110 import SCons.Errors 110 import SCons.Errors
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 return None 385 return None
386 386
387 def _do_create_list_action(act, kw): 387 def _do_create_list_action(act, kw):
388 """A factory for list actions. Convert the input list into Actions 388 """A factory for list actions. Convert the input list into Actions
389 and then wrap them in a ListAction.""" 389 and then wrap them in a ListAction."""
390 acts = [] 390 acts = []
391 for a in act: 391 for a in act:
392 aa = _do_create_action(a, kw) 392 aa = _do_create_action(a, kw)
393 if aa is not None: acts.append(aa) 393 if aa is not None: acts.append(aa)
394 if not acts: 394 if not acts:
395 return None 395 return ListAction([])
396 elif len(acts) == 1: 396 elif len(acts) == 1:
397 return acts[0] 397 return acts[0]
398 else: 398 else:
399 return ListAction(acts) 399 return ListAction(acts)
400 400
401 def Action(act, *args, **kw): 401 def Action(act, *args, **kw):
402 """A factory for action objects.""" 402 """A factory for action objects."""
403 # Really simple: the _do_create_* routines do the heavy lifting. 403 # Really simple: the _do_create_* routines do the heavy lifting.
404 _do_create_keywords(args, kw) 404 _do_create_keywords(args, kw)
405 if is_List(act): 405 if is_List(act):
406 return _do_create_list_action(act, kw) 406 return _do_create_list_action(act, kw)
407 return _do_create_action(act, kw) 407 return _do_create_action(act, kw)
408 408
409 class ActionBase: 409 class ActionBase:
410 """Base class for all types of action objects that can be held by 410 """Base class for all types of action objects that can be held by
411 other objects (Builders, Executors, etc.) This provides the 411 other objects (Builders, Executors, etc.) This provides the
412 common methods for manipulating and combining those actions.""" 412 common methods for manipulating and combining those actions."""
413 413
414 def __cmp__(self, other): 414 def __cmp__(self, other):
415 return cmp(self.__dict__, other) 415 return cmp(self.__dict__, other)
416 416
417 def no_batch_key(self, env, target, source):
418 return None
419
420 batch_key = no_batch_key
421
417 def genstring(self, target, source, env): 422 def genstring(self, target, source, env):
418 return str(self) 423 return str(self)
419 424
420 def get_contents(self, target, source, env): 425 def get_contents(self, target, source, env):
421 result = [ self.get_presig(target, source, env) ] 426 result = [ self.get_presig(target, source, env) ]
422 # This should never happen, as the Action() factory should wrap 427 # This should never happen, as the Action() factory should wrap
423 # the varlist, but just in case an action is created directly, 428 # the varlist, but just in case an action is created directly,
424 # we duplicate this check here. 429 # we duplicate this check here.
425 vl = self.varlist 430 vl = self.varlist
426 if is_String(vl): vl = (vl,) 431 if is_String(vl): vl = (vl,)
(...skipping 12 matching lines...) Expand all
439 # in order to return the proper string here, since 444 # in order to return the proper string here, since
440 # it may call LazyAction, which looks up a key 445 # it may call LazyAction, which looks up a key
441 # in that env. So we temporarily remember the env here, 446 # in that env. So we temporarily remember the env here,
442 # and CommandGeneratorAction will use this env 447 # and CommandGeneratorAction will use this env
443 # when it calls its _generate method. 448 # when it calls its _generate method.
444 self.presub_env = env 449 self.presub_env = env
445 lines = string.split(str(self), '\n') 450 lines = string.split(str(self), '\n')
446 self.presub_env = None # don't need this any more 451 self.presub_env = None # don't need this any more
447 return lines 452 return lines
448 453
449 def get_executor(self, env, overrides, tlist, slist, executor_kw): 454 def get_targets(self, env, executor):
450 """Return the Executor for this Action.""" 455 """
451 return SCons.Executor.Executor(self, env, overrides, 456 Returns the type of targets ($TARGETS, $CHANGED_TARGETS) used
452 tlist, slist, executor_kw) 457 by this action.
458 """
459 return self.targets
453 460
454 class _ActionAction(ActionBase): 461 class _ActionAction(ActionBase):
455 """Base class for actions that create output objects.""" 462 """Base class for actions that create output objects."""
456 def __init__(self, cmdstr=_null, strfunction=_null, varlist=(), 463 def __init__(self, cmdstr=_null, strfunction=_null, varlist=(),
457 presub=_null, chdir=None, exitstatfunc=None, 464 presub=_null, chdir=None, exitstatfunc=None,
465 batch_key=None, targets='$TARGETS',
458 **kw): 466 **kw):
459 self.cmdstr = cmdstr 467 self.cmdstr = cmdstr
460 if strfunction is not _null: 468 if strfunction is not _null:
461 if strfunction is None: 469 if strfunction is None:
462 self.cmdstr = None 470 self.cmdstr = None
463 else: 471 else:
464 self.strfunction = strfunction 472 self.strfunction = strfunction
465 self.varlist = varlist 473 self.varlist = varlist
466 self.presub = presub 474 self.presub = presub
467 self.chdir = chdir 475 self.chdir = chdir
468 if not exitstatfunc: 476 if not exitstatfunc:
469 exitstatfunc = default_exitstatfunc 477 exitstatfunc = default_exitstatfunc
470 self.exitstatfunc = exitstatfunc 478 self.exitstatfunc = exitstatfunc
471 479
480 self.targets = targets
481
482 if batch_key:
483 if not callable(batch_key):
484 # They have set batch_key, but not to their own
485 # callable. The default behavior here will batch
486 # *all* targets+sources using this action, separated
487 # for each construction environment.
488 def default_batch_key(self, env, target, source):
489 return (id(self), id(env))
490 batch_key = default_batch_key
491 SCons.Util.AddMethod(self, batch_key, 'batch_key')
492
472 def print_cmd_line(self, s, target, source, env): 493 def print_cmd_line(self, s, target, source, env):
473 sys.stdout.write(s + "\n") 494 sys.stdout.write(s + "\n")
474 495
475 def __call__(self, target, source, env, 496 def __call__(self, target, source, env,
476 exitstatfunc=_null, 497 exitstatfunc=_null,
477 presub=_null, 498 presub=_null,
478 show=_null, 499 show=_null,
479 execute=_null, 500 execute=_null,
480 chdir=_null): 501 chdir=_null,
502 executor=None):
481 if not is_List(target): 503 if not is_List(target):
482 target = [target] 504 target = [target]
483 if not is_List(source): 505 if not is_List(source):
484 source = [source] 506 source = [source]
485 507
486 if presub is _null: 508 if presub is _null:
487 presub = self.presub 509 presub = self.presub
488 if presub is _null: 510 if presub is _null:
489 presub = print_actions_presub 511 presub = print_actions_presub
490 if exitstatfunc is _null: exitstatfunc = self.exitstatfunc 512 if exitstatfunc is _null: exitstatfunc = self.exitstatfunc
491 if show is _null: show = print_actions 513 if show is _null: show = print_actions
492 if execute is _null: execute = execute_actions 514 if execute is _null: execute = execute_actions
493 if chdir is _null: chdir = self.chdir 515 if chdir is _null: chdir = self.chdir
494 save_cwd = None 516 save_cwd = None
495 if chdir: 517 if chdir:
496 save_cwd = os.getcwd() 518 save_cwd = os.getcwd()
497 try: 519 try:
498 chdir = str(chdir.abspath) 520 chdir = str(chdir.abspath)
499 except AttributeError: 521 except AttributeError:
500 if not is_String(chdir): 522 if not is_String(chdir):
501 chdir = str(target[0].dir) 523 if executor:
524 chdir = str(executor.batches[0].targets[0].dir)
525 else:
526 chdir = str(target[0].dir)
502 if presub: 527 if presub:
528 if executor:
529 target = executor.get_all_targets()
530 source = executor.get_all_sources()
503 t = string.join(map(str, target), ' and ') 531 t = string.join(map(str, target), ' and ')
504 l = string.join(self.presub_lines(env), '\n ') 532 l = string.join(self.presub_lines(env), '\n ')
505 out = "Building %s with action:\n %s\n" % (t, l) 533 out = "Building %s with action:\n %s\n" % (t, l)
506 sys.stdout.write(out) 534 sys.stdout.write(out)
507 cmd = None 535 cmd = None
508 if show and self.strfunction: 536 if show and self.strfunction:
509 cmd = self.strfunction(target, source, env) 537 if executor:
538 target = executor.get_all_targets()
539 source = executor.get_all_sources()
540 try:
541 cmd = self.strfunction(target, source, env, executor)
542 except TypeError:
543 cmd = self.strfunction(target, source, env)
510 if cmd: 544 if cmd:
511 if chdir: 545 if chdir:
512 cmd = ('os.chdir(%s)\n' % repr(chdir)) + cmd 546 cmd = ('os.chdir(%s)\n' % repr(chdir)) + cmd
513 try: 547 try:
514 get = env.get 548 get = env.get
515 except AttributeError: 549 except AttributeError:
516 print_func = self.print_cmd_line 550 print_func = self.print_cmd_line
517 else: 551 else:
518 print_func = get('PRINT_CMD_LINE_FUNC') 552 print_func = get('PRINT_CMD_LINE_FUNC')
519 if not print_func: 553 if not print_func:
520 print_func = self.print_cmd_line 554 print_func = self.print_cmd_line
521 print_func(cmd, target, source, env) 555 print_func(cmd, target, source, env)
522 stat = 0 556 stat = 0
523 if execute: 557 if execute:
524 if chdir: 558 if chdir:
525 os.chdir(chdir) 559 os.chdir(chdir)
526 try: 560 try:
527 stat = self.execute(target, source, env) 561 stat = self.execute(target, source, env, executor=executor)
528 if isinstance(stat, SCons.Errors.BuildError): 562 if isinstance(stat, SCons.Errors.BuildError):
529 s = exitstatfunc(stat.status) 563 s = exitstatfunc(stat.status)
530 if s: 564 if s:
531 stat.status = s 565 stat.status = s
532 else: 566 else:
533 stat = s 567 stat = s
534 else: 568 else:
535 stat = exitstatfunc(stat) 569 stat = exitstatfunc(stat)
536 finally: 570 finally:
537 if save_cwd: 571 if save_cwd:
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
650 if filter(is_List, cmd): 684 if filter(is_List, cmd):
651 raise TypeError, "CommandAction should be given only " \ 685 raise TypeError, "CommandAction should be given only " \
652 "a single command" 686 "a single command"
653 self.cmd_list = cmd 687 self.cmd_list = cmd
654 688
655 def __str__(self): 689 def __str__(self):
656 if is_List(self.cmd_list): 690 if is_List(self.cmd_list):
657 return string.join(map(str, self.cmd_list), ' ') 691 return string.join(map(str, self.cmd_list), ' ')
658 return str(self.cmd_list) 692 return str(self.cmd_list)
659 693
660 def process(self, target, source, env): 694 def process(self, target, source, env, executor=None):
661 result = env.subst_list(self.cmd_list, 0, target, source) 695 if executor:
696 result = env.subst_list(self.cmd_list, 0, executor=executor)
697 else:
698 result = env.subst_list(self.cmd_list, 0, target, source)
662 silent = None 699 silent = None
663 ignore = None 700 ignore = None
664 while 1: 701 while 1:
665 try: c = result[0][0][0] 702 try: c = result[0][0][0]
666 except IndexError: c = None 703 except IndexError: c = None
667 if c == '@': silent = 1 704 if c == '@': silent = 1
668 elif c == '-': ignore = 1 705 elif c == '-': ignore = 1
669 else: break 706 else: break
670 result[0][0] = result[0][0][1:] 707 result[0][0] = result[0][0][1:]
671 try: 708 try:
672 if not result[0][0]: 709 if not result[0][0]:
673 result[0] = result[0][1:] 710 result[0] = result[0][1:]
674 except IndexError: 711 except IndexError:
675 pass 712 pass
676 return result, ignore, silent 713 return result, ignore, silent
677 714
678 def strfunction(self, target, source, env): 715 def strfunction(self, target, source, env, executor=None):
679 if self.cmdstr is None: 716 if self.cmdstr is None:
680 return None 717 return None
681 if self.cmdstr is not _null: 718 if self.cmdstr is not _null:
682 from SCons.Subst import SUBST_RAW 719 from SCons.Subst import SUBST_RAW
683 c = env.subst(self.cmdstr, SUBST_RAW, target, source) 720 if executor:
721 c = env.subst(self.cmdstr, SUBST_RAW, executor=executor)
722 else:
723 c = env.subst(self.cmdstr, SUBST_RAW, target, source)
684 if c: 724 if c:
685 return c 725 return c
686 cmd_list, ignore, silent = self.process(target, source, env) 726 cmd_list, ignore, silent = self.process(target, source, env, executor)
687 if silent: 727 if silent:
688 return '' 728 return ''
689 return _string_from_cmd_list(cmd_list[0]) 729 return _string_from_cmd_list(cmd_list[0])
690 730
691 def execute(self, target, source, env): 731 def execute(self, target, source, env, executor=None):
692 """Execute a command action. 732 """Execute a command action.
693 733
694 This will handle lists of commands as well as individual commands, 734 This will handle lists of commands as well as individual commands,
695 because construction variable substitution may turn a single 735 because construction variable substitution may turn a single
696 "command" into a list. This means that this class can actually 736 "command" into a list. This means that this class can actually
697 handle lists of commands, even though that's not how we use it 737 handle lists of commands, even though that's not how we use it
698 externally. 738 externally.
699 """ 739 """
700 escape_list = SCons.Subst.escape_list 740 escape_list = SCons.Subst.escape_list
701 flatten_sequence = SCons.Util.flatten_sequence 741 flatten_sequence = SCons.Util.flatten_sequence
(...skipping 24 matching lines...) Expand all
726 # value to stick in an environment variable: 766 # value to stick in an environment variable:
727 value = flatten_sequence(value) 767 value = flatten_sequence(value)
728 ENV[key] = string.join(map(str, value), os.pathsep) 768 ENV[key] = string.join(map(str, value), os.pathsep)
729 else: 769 else:
730 # If it isn't a string or a list, then we just coerce 770 # If it isn't a string or a list, then we just coerce
731 # it to a string, which is the proper way to handle 771 # it to a string, which is the proper way to handle
732 # Dir and File instances and will produce something 772 # Dir and File instances and will produce something
733 # reasonable for just about everything else: 773 # reasonable for just about everything else:
734 ENV[key] = str(value) 774 ENV[key] = str(value)
735 775
736 cmd_list, ignore, silent = self.process(target, map(rfile, source), env) 776 if executor:
777 target = executor.get_all_targets()
778 source = executor.get_all_sources()
779 cmd_list, ignore, silent = self.process(target, map(rfile, source), env, executor)
737 780
738 # Use len() to filter out any "command" that's zero-length. 781 # Use len() to filter out any "command" that's zero-length.
739 for cmd_line in filter(len, cmd_list): 782 for cmd_line in filter(len, cmd_list):
740 # Escape the command line for the interpreter we are using. 783 # Escape the command line for the interpreter we are using.
741 cmd_line = escape_list(cmd_line, escape) 784 cmd_line = escape_list(cmd_line, escape)
742 result = spawn(shell, escape, cmd_line[0], cmd_line, ENV) 785 result = spawn(shell, escape, cmd_line[0], cmd_line, ENV)
743 if not ignore and result: 786 if not ignore and result:
744 msg = "Error %s" % result 787 msg = "Error %s" % result
745 return SCons.Errors.BuildError(errstr=msg, 788 return SCons.Errors.BuildError(errstr=msg,
746 status=result, 789 status=result,
747 action=self, 790 action=self,
748 command=cmd_line) 791 command=cmd_line)
749 return 0 792 return 0
750 793
751 def get_presig(self, target, source, env): 794 def get_presig(self, target, source, env, executor=None):
752 """Return the signature contents of this action's command line. 795 """Return the signature contents of this action's command line.
753 796
754 This strips $(-$) and everything in between the string, 797 This strips $(-$) and everything in between the string,
755 since those parts don't affect signatures. 798 since those parts don't affect signatures.
756 """ 799 """
757 from SCons.Subst import SUBST_SIG 800 from SCons.Subst import SUBST_SIG
758 cmd = self.cmd_list 801 cmd = self.cmd_list
759 if is_List(cmd): 802 if is_List(cmd):
760 cmd = string.join(map(str, cmd)) 803 cmd = string.join(map(str, cmd))
761 else: 804 else:
762 cmd = str(cmd) 805 cmd = str(cmd)
763 return env.subst_target_source(cmd, SUBST_SIG, target, source) 806 if executor:
807 return env.subst_target_source(cmd, SUBST_SIG, executor=executor)
808 else:
809 return env.subst_target_source(cmd, SUBST_SIG, target, source)
764 810
765 def get_implicit_deps(self, target, source, env): 811 def get_implicit_deps(self, target, source, env, executor=None):
766 icd = env.get('IMPLICIT_COMMAND_DEPENDENCIES', True) 812 icd = env.get('IMPLICIT_COMMAND_DEPENDENCIES', True)
767 if is_String(icd) and icd[:1] == '$': 813 if is_String(icd) and icd[:1] == '$':
768 icd = env.subst(icd) 814 icd = env.subst(icd)
769 if not icd or icd in ('0', 'None'): 815 if not icd or icd in ('0', 'None'):
770 return [] 816 return []
771 from SCons.Subst import SUBST_SIG 817 from SCons.Subst import SUBST_SIG
772 cmd_list = env.subst_list(self.cmd_list, SUBST_SIG, target, source) 818 if executor:
819 cmd_list = env.subst_list(self.cmd_list, SUBST_SIG, executor=executo r)
820 else:
821 cmd_list = env.subst_list(self.cmd_list, SUBST_SIG, target, source)
773 res = [] 822 res = []
774 for cmd_line in cmd_list: 823 for cmd_line in cmd_list:
775 if cmd_line: 824 if cmd_line:
776 d = env.WhereIs(str(cmd_line[0])) 825 d = env.WhereIs(str(cmd_line[0]))
777 if d: 826 if d:
778 res.append(env.fs.File(d)) 827 res.append(env.fs.File(d))
779 return res 828 return res
780 829
781 class CommandGeneratorAction(ActionBase): 830 class CommandGeneratorAction(ActionBase):
782 """Class for command-generator actions.""" 831 """Class for command-generator actions."""
783 def __init__(self, generator, kw): 832 def __init__(self, generator, kw):
784 if __debug__: logInstanceCreation(self, 'Action.CommandGeneratorAction') 833 if __debug__: logInstanceCreation(self, 'Action.CommandGeneratorAction')
785 self.generator = generator 834 self.generator = generator
786 self.gen_kw = kw 835 self.gen_kw = kw
787 self.varlist = kw.get('varlist', ()) 836 self.varlist = kw.get('varlist', ())
837 self.targets = kw.get('targets', '$TARGETS')
788 838
789 def _generate(self, target, source, env, for_signature): 839 def _generate(self, target, source, env, for_signature, executor=None):
790 # ensure that target is a list, to make it easier to write 840 # ensure that target is a list, to make it easier to write
791 # generator functions: 841 # generator functions:
792 if not is_List(target): 842 if not is_List(target):
793 target = [target] 843 target = [target]
794 844
795 ret = self.generator(target=target, source=source, env=env, for_signatur e=for_signature) 845 if executor:
846 target = executor.get_all_targets()
847 source = executor.get_all_sources()
848 ret = self.generator(target=target,
849 source=source,
850 env=env,
851 for_signature=for_signature)
796 #TODO(1.5) gen_cmd = Action(ret, **self.gen_kw) 852 #TODO(1.5) gen_cmd = Action(ret, **self.gen_kw)
797 gen_cmd = apply(Action, (ret,), self.gen_kw) 853 gen_cmd = apply(Action, (ret,), self.gen_kw)
798 if not gen_cmd: 854 if not gen_cmd:
799 raise SCons.Errors.UserError("Object returned from command generator : %s cannot be used to create an Action." % repr(ret)) 855 raise SCons.Errors.UserError("Object returned from command generator : %s cannot be used to create an Action." % repr(ret))
800 return gen_cmd 856 return gen_cmd
801 857
802 def __str__(self): 858 def __str__(self):
803 try: 859 try:
804 env = self.presub_env 860 env = self.presub_env
805 except AttributeError: 861 except AttributeError:
806 env = None 862 env = None
807 if env is None: 863 if env is None:
808 env = SCons.Defaults.DefaultEnvironment() 864 env = SCons.Defaults.DefaultEnvironment()
809 act = self._generate([], [], env, 1) 865 act = self._generate([], [], env, 1)
810 return str(act) 866 return str(act)
811 867
812 def genstring(self, target, source, env): 868 def batch_key(self, env, target, source):
813 return self._generate(target, source, env, 1).genstring(target, source, env) 869 return self._generate(target, source, env, 1).batch_key(env, target, sou rce)
870
871 def genstring(self, target, source, env, executor=None):
872 return self._generate(target, source, env, 1, executor).genstring(target , source, env)
814 873
815 def __call__(self, target, source, env, exitstatfunc=_null, presub=_null, 874 def __call__(self, target, source, env, exitstatfunc=_null, presub=_null,
816 show=_null, execute=_null, chdir=_null): 875 show=_null, execute=_null, chdir=_null, executor=None):
817 act = self._generate(target, source, env, 0) 876 act = self._generate(target, source, env, 0, executor)
877 if act is None:
878 raise UserError("While building `%s': Cannot deduce file extension f rom source files: %s" % (repr(map(str, target)), repr(map(str, source))))
818 return act(target, source, env, exitstatfunc, presub, 879 return act(target, source, env, exitstatfunc, presub,
819 show, execute, chdir) 880 show, execute, chdir, executor)
820 881
821 def get_presig(self, target, source, env): 882 def get_presig(self, target, source, env, executor=None):
822 """Return the signature contents of this action's command line. 883 """Return the signature contents of this action's command line.
823 884
824 This strips $(-$) and everything in between the string, 885 This strips $(-$) and everything in between the string,
825 since those parts don't affect signatures. 886 since those parts don't affect signatures.
826 """ 887 """
827 return self._generate(target, source, env, 1).get_presig(target, source, env) 888 return self._generate(target, source, env, 1, executor).get_presig(targe t, source, env)
828 889
829 def get_implicit_deps(self, target, source, env): 890 def get_implicit_deps(self, target, source, env, executor=None):
830 return self._generate(target, source, env, 1).get_implicit_deps(target, source, env) 891 return self._generate(target, source, env, 1, executor).get_implicit_dep s(target, source, env)
892
893 def get_targets(self, env, executor):
894 return self._generate(None, None, env, 1, executor).get_targets(env, exe cutor)
831 895
832 896
833 897
834 # A LazyAction is a kind of hybrid generator and command action for 898 # A LazyAction is a kind of hybrid generator and command action for
835 # strings of the form "$VAR". These strings normally expand to other 899 # strings of the form "$VAR". These strings normally expand to other
836 # strings (think "$CCCOM" to "$CC -c -o $TARGET $SOURCE"), but we also 900 # strings (think "$CCCOM" to "$CC -c -o $TARGET $SOURCE"), but we also
837 # want to be able to replace them with functions in the construction 901 # want to be able to replace them with functions in the construction
838 # environment. Consequently, we want lazy evaluation and creation of 902 # environment. Consequently, we want lazy evaluation and creation of
839 # an Action in the case of the function, but that's overkill in the more 903 # an Action in the case of the function, but that's overkill in the more
840 # normal case of expansion to other strings. 904 # normal case of expansion to other strings.
(...skipping 16 matching lines...) Expand all
857 self.var = SCons.Util.to_String(var) 921 self.var = SCons.Util.to_String(var)
858 self.gen_kw = kw 922 self.gen_kw = kw
859 923
860 def get_parent_class(self, env): 924 def get_parent_class(self, env):
861 c = env.get(self.var) 925 c = env.get(self.var)
862 if is_String(c) and not '\n' in c: 926 if is_String(c) and not '\n' in c:
863 return CommandAction 927 return CommandAction
864 return CommandGeneratorAction 928 return CommandGeneratorAction
865 929
866 def _generate_cache(self, env): 930 def _generate_cache(self, env):
867 c = env.get(self.var, '') 931 if env:
932 c = env.get(self.var, '')
933 else:
934 c = ''
868 #TODO(1.5) gen_cmd = Action(c, **self.gen_kw) 935 #TODO(1.5) gen_cmd = Action(c, **self.gen_kw)
869 gen_cmd = apply(Action, (c,), self.gen_kw) 936 gen_cmd = apply(Action, (c,), self.gen_kw)
870 if not gen_cmd: 937 if not gen_cmd:
871 raise SCons.Errors.UserError("$%s value %s cannot be used to create an Action." % (self.var, repr(c))) 938 raise SCons.Errors.UserError("$%s value %s cannot be used to create an Action." % (self.var, repr(c)))
872 return gen_cmd 939 return gen_cmd
873 940
874 def _generate(self, target, source, env, for_signature): 941 def _generate(self, target, source, env, for_signature, executor=None):
875 return self._generate_cache(env) 942 return self._generate_cache(env)
876 943
877 def __call__(self, target, source, env, *args, **kw): 944 def __call__(self, target, source, env, *args, **kw):
878 args = (self, target, source, env) + args 945 args = (self, target, source, env) + args
879 c = self.get_parent_class(env) 946 c = self.get_parent_class(env)
880 #TODO(1.5) return c.__call__(*args, **kw) 947 #TODO(1.5) return c.__call__(*args, **kw)
881 return apply(c.__call__, args, kw) 948 return apply(c.__call__, args, kw)
882 949
883 def get_presig(self, target, source, env): 950 def get_presig(self, target, source, env):
884 c = self.get_parent_class(env) 951 c = self.get_parent_class(env)
(...skipping 23 matching lines...) Expand all
908 975
909 def function_name(self): 976 def function_name(self):
910 try: 977 try:
911 return self.execfunction.__name__ 978 return self.execfunction.__name__
912 except AttributeError: 979 except AttributeError:
913 try: 980 try:
914 return self.execfunction.__class__.__name__ 981 return self.execfunction.__class__.__name__
915 except AttributeError: 982 except AttributeError:
916 return "unknown_python_function" 983 return "unknown_python_function"
917 984
918 def strfunction(self, target, source, env): 985 def strfunction(self, target, source, env, executor=None):
919 if self.cmdstr is None: 986 if self.cmdstr is None:
920 return None 987 return None
921 if self.cmdstr is not _null: 988 if self.cmdstr is not _null:
922 from SCons.Subst import SUBST_RAW 989 from SCons.Subst import SUBST_RAW
923 c = env.subst(self.cmdstr, SUBST_RAW, target, source) 990 if executor:
991 c = env.subst(self.cmdstr, SUBST_RAW, executor=executor)
992 else:
993 c = env.subst(self.cmdstr, SUBST_RAW, target, source)
924 if c: 994 if c:
925 return c 995 return c
926 def array(a): 996 def array(a):
927 def quote(s): 997 def quote(s):
928 try: 998 try:
929 str_for_display = s.str_for_display 999 str_for_display = s.str_for_display
930 except AttributeError: 1000 except AttributeError:
931 s = repr(s) 1001 s = repr(s)
932 else: 1002 else:
933 s = str_for_display() 1003 s = str_for_display()
(...skipping 12 matching lines...) Expand all
946 tstr = array(target) 1016 tstr = array(target)
947 sstr = array(source) 1017 sstr = array(source)
948 return "%s(%s, %s)" % (name, tstr, sstr) 1018 return "%s(%s, %s)" % (name, tstr, sstr)
949 1019
950 def __str__(self): 1020 def __str__(self):
951 name = self.function_name() 1021 name = self.function_name()
952 if name == 'ActionCaller': 1022 if name == 'ActionCaller':
953 return str(self.execfunction) 1023 return str(self.execfunction)
954 return "%s(target, source, env)" % name 1024 return "%s(target, source, env)" % name
955 1025
956 def execute(self, target, source, env): 1026 def execute(self, target, source, env, executor=None):
957 exc_info = (None,None,None) 1027 exc_info = (None,None,None)
958 try: 1028 try:
1029 if executor:
1030 target = executor.get_all_targets()
1031 source = executor.get_all_sources()
959 rsources = map(rfile, source) 1032 rsources = map(rfile, source)
960 try: 1033 try:
961 result = self.execfunction(target=target, source=rsources, env=e nv) 1034 result = self.execfunction(target=target, source=rsources, env=e nv)
962 except KeyboardInterrupt, e: 1035 except KeyboardInterrupt, e:
963 raise 1036 raise
964 except SystemExit, e: 1037 except SystemExit, e:
965 raise 1038 raise
966 except Exception, e: 1039 except Exception, e:
967 result = e 1040 result = e
968 exc_info = sys.exc_info() 1041 exc_info = sys.exc_info()
969 1042
970 if result: 1043 if result:
971 result = SCons.Errors.convert_to_BuildError(result, exc_info) 1044 result = SCons.Errors.convert_to_BuildError(result, exc_info)
972 result.node=target 1045 result.node=target
973 result.action=self 1046 result.action=self
974 result.command=self.strfunction(target, source, env) 1047 try:
1048 result.command=self.strfunction(target, source, env, executo r)
1049 except TypeError:
1050 result.command=self.strfunction(target, source, env)
975 1051
976 # FIXME: This maintains backward compatibility with respect to 1052 # FIXME: This maintains backward compatibility with respect to
977 # which type of exceptions were returned by raising an 1053 # which type of exceptions were returned by raising an
978 # exception and which ones were returned by value. It would 1054 # exception and which ones were returned by value. It would
979 # probably be best to always return them by value here, but 1055 # probably be best to always return them by value here, but
980 # some codes do not check the return value of Actions and I do 1056 # some codes do not check the return value of Actions and I do
981 # not have the time to modify them at this point. 1057 # not have the time to modify them at this point.
982 if (exc_info[1] and 1058 if (exc_info[1] and
983 not isinstance(exc_info[1],EnvironmentError)): 1059 not isinstance(exc_info[1],EnvironmentError)):
984 raise result 1060 raise result
(...skipping 21 matching lines...) Expand all
1006 def __init__(self, list): 1082 def __init__(self, list):
1007 if __debug__: logInstanceCreation(self, 'Action.ListAction') 1083 if __debug__: logInstanceCreation(self, 'Action.ListAction')
1008 def list_of_actions(x): 1084 def list_of_actions(x):
1009 if isinstance(x, ActionBase): 1085 if isinstance(x, ActionBase):
1010 return x 1086 return x
1011 return Action(x) 1087 return Action(x)
1012 self.list = map(list_of_actions, list) 1088 self.list = map(list_of_actions, list)
1013 # our children will have had any varlist 1089 # our children will have had any varlist
1014 # applied; we don't need to do it again 1090 # applied; we don't need to do it again
1015 self.varlist = () 1091 self.varlist = ()
1092 self.targets = '$TARGETS'
1016 1093
1017 def genstring(self, target, source, env): 1094 def genstring(self, target, source, env):
1018 return string.join(map(lambda a, t=target, s=source, e=env: 1095 return string.join(map(lambda a, t=target, s=source, e=env:
1019 a.genstring(t, s, e), 1096 a.genstring(t, s, e),
1020 self.list), 1097 self.list),
1021 '\n') 1098 '\n')
1022 1099
1023 def __str__(self): 1100 def __str__(self):
1024 return string.join(map(str, self.list), '\n') 1101 return string.join(map(str, self.list), '\n')
1025 1102
1026 def presub_lines(self, env): 1103 def presub_lines(self, env):
1027 return SCons.Util.flatten_sequence( 1104 return SCons.Util.flatten_sequence(
1028 map(lambda a, env=env: a.presub_lines(env), self.list)) 1105 map(lambda a, env=env: a.presub_lines(env), self.list))
1029 1106
1030 def get_presig(self, target, source, env): 1107 def get_presig(self, target, source, env):
1031 """Return the signature contents of this action list. 1108 """Return the signature contents of this action list.
1032 1109
1033 Simple concatenation of the signatures of the elements. 1110 Simple concatenation of the signatures of the elements.
1034 """ 1111 """
1035 return string.join(map(lambda x, t=target, s=source, e=env: 1112 return string.join(map(lambda x, t=target, s=source, e=env:
1036 x.get_contents(t, s, e), 1113 x.get_contents(t, s, e),
1037 self.list), 1114 self.list),
1038 "") 1115 "")
1039 1116
1040 def __call__(self, target, source, env, exitstatfunc=_null, presub=_null, 1117 def __call__(self, target, source, env, exitstatfunc=_null, presub=_null,
1041 show=_null, execute=_null, chdir=_null): 1118 show=_null, execute=_null, chdir=_null, executor=None):
1119 if executor:
1120 target = executor.get_all_targets()
1121 source = executor.get_all_sources()
1042 for act in self.list: 1122 for act in self.list:
1043 stat = act(target, source, env, exitstatfunc, presub, 1123 stat = act(target, source, env, exitstatfunc, presub,
1044 show, execute, chdir) 1124 show, execute, chdir, executor)
1045 if stat: 1125 if stat:
1046 return stat 1126 return stat
1047 return 0 1127 return 0
1048 1128
1049 def get_implicit_deps(self, target, source, env): 1129 def get_implicit_deps(self, target, source, env):
1050 result = [] 1130 result = []
1051 for act in self.list: 1131 for act in self.list:
1052 result.extend(act.get_implicit_deps(target, source, env)) 1132 result.extend(act.get_implicit_deps(target, source, env))
1053 return result 1133 return result
1054 1134
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1104 return map(lambda x, self=self, t=target, s=source, e=env: 1184 return map(lambda x, self=self, t=target, s=source, e=env:
1105 self.subst(x, t, s, e), 1185 self.subst(x, t, s, e),
1106 self.args) 1186 self.args)
1107 1187
1108 def subst_kw(self, target, source, env): 1188 def subst_kw(self, target, source, env):
1109 kw = {} 1189 kw = {}
1110 for key in self.kw.keys(): 1190 for key in self.kw.keys():
1111 kw[key] = self.subst(self.kw[key], target, source, env) 1191 kw[key] = self.subst(self.kw[key], target, source, env)
1112 return kw 1192 return kw
1113 1193
1114 def __call__(self, target, source, env): 1194 def __call__(self, target, source, env, executor=None):
1115 args = self.subst_args(target, source, env) 1195 args = self.subst_args(target, source, env)
1116 kw = self.subst_kw(target, source, env) 1196 kw = self.subst_kw(target, source, env)
1117 #TODO(1.5) return self.parent.actfunc(*args, **kw) 1197 #TODO(1.5) return self.parent.actfunc(*args, **kw)
1118 return apply(self.parent.actfunc, args, kw) 1198 return apply(self.parent.actfunc, args, kw)
1119 1199
1120 def strfunction(self, target, source, env): 1200 def strfunction(self, target, source, env):
1121 args = self.subst_args(target, source, env) 1201 args = self.subst_args(target, source, env)
1122 kw = self.subst_kw(target, source, env) 1202 kw = self.subst_kw(target, source, env)
1123 #TODO(1.5) return self.parent.strfunc(*args, **kw) 1203 #TODO(1.5) return self.parent.strfunc(*args, **kw)
1124 return apply(self.parent.strfunc, args, kw) 1204 return apply(self.parent.strfunc, args, kw)
(...skipping 13 matching lines...) Expand all
1138 """ 1218 """
1139 def __init__(self, actfunc, strfunc, convert=lambda x: x): 1219 def __init__(self, actfunc, strfunc, convert=lambda x: x):
1140 self.actfunc = actfunc 1220 self.actfunc = actfunc
1141 self.strfunc = strfunc 1221 self.strfunc = strfunc
1142 self.convert = convert 1222 self.convert = convert
1143 1223
1144 def __call__(self, *args, **kw): 1224 def __call__(self, *args, **kw):
1145 ac = ActionCaller(self, args, kw) 1225 ac = ActionCaller(self, args, kw)
1146 action = Action(ac, strfunction=ac.strfunction) 1226 action = Action(ac, strfunction=ac.strfunction)
1147 return action 1227 return action
OLDNEW
« no previous file with comments | « third_party/scons/scons-README ('k') | third_party/scons/scons-local/SCons/Builder.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698