diff options
author | Russel Winder <russel@winder.org.uk> | 2015-12-24 16:32:14 (GMT) |
---|---|---|
committer | Russel Winder <russel@winder.org.uk> | 2015-12-24 16:32:14 (GMT) |
commit | 2a270c8f314e959c78e9deda29c8f250bb934dd6 (patch) | |
tree | 7008e644357036404f0861c8ba1bbbf43b2b4123 /src/engine/SCons/Executor.py | |
parent | a7d764ed831fa3243aa0bd3307f641e1e1f9f8a8 (diff) | |
parent | 9d558dd65deacc958edc1f0da2dab1ec56ff4e4e (diff) | |
download | SCons-2a270c8f314e959c78e9deda29c8f250bb934dd6.zip SCons-2a270c8f314e959c78e9deda29c8f250bb934dd6.tar.gz SCons-2a270c8f314e959c78e9deda29c8f250bb934dd6.tar.bz2 |
Post merge commit for safety. Building Fortran code works, but tests fail.
Diffstat (limited to 'src/engine/SCons/Executor.py')
-rw-r--r-- | src/engine/SCons/Executor.py | 179 |
1 files changed, 102 insertions, 77 deletions
diff --git a/src/engine/SCons/Executor.py b/src/engine/SCons/Executor.py index 2c53f21..eace84a 100644 --- a/src/engine/SCons/Executor.py +++ b/src/engine/SCons/Executor.py @@ -40,6 +40,10 @@ import SCons.Memoize class Batch(object): """Remembers exact association between targets and sources of executor.""" + + __slots__ = ('targets', + 'sources') + def __init__(self, targets=[], sources=[]): self.targets = targets self.sources = sources @@ -109,6 +113,47 @@ def rfile(node): return rfile() +def execute_nothing(obj, target, kw): + return 0 + +def execute_action_list(obj, target, kw): + """Actually execute the action list.""" + env = obj.get_build_env() + kw = obj.get_kw(kw) + status = 0 + for act in obj.get_action_list(): + args = ([], [], env) + status = act(*args, **kw) + if isinstance(status, SCons.Errors.BuildError): + status.executor = obj + raise status + elif status: + msg = "Error %s" % status + raise SCons.Errors.BuildError( + errstr=msg, + node=obj.batches[0].targets, + executor=obj, + action=act) + return status + +_do_execute_map = {0 : execute_nothing, + 1 : execute_action_list} + + +def execute_actions_str(obj): + env = obj.get_build_env() + return "\n".join([action.genstring(obj.get_all_targets(), + obj.get_all_sources(), + env) + for action in obj.get_action_list()]) + +def execute_null_str(obj): + return '' + +_execute_str_map = {0 : execute_null_str, + 1 : execute_actions_str} + + class Executor(object): """A class for controlling instances of executing an action. @@ -117,10 +162,21 @@ class Executor(object): and sources for later processing as needed. """ - if SCons.Memoize.use_memoizer: - __metaclass__ = SCons.Memoize.Memoized_Metaclass - - memoizer_counters = [] + __slots__ = ('pre_actions', + 'post_actions', + 'env', + 'overridelist', + 'batches', + 'builder_kw', + '_memo', + 'lvars', + '_changed_sources_list', + '_changed_targets_list', + '_unchanged_sources_list', + '_unchanged_targets_list', + 'action_list', + '_do_execute', + '_execute_str') def __init__(self, action, env=None, overridelist=[{}], targets=[], sources=[], builder_kw={}): @@ -135,6 +191,8 @@ class Executor(object): else: self.batches = [] self.builder_kw = builder_kw + self._do_execute = 1 + self._execute_str = 1 self._memo = {} def get_lvars(self): @@ -185,14 +243,12 @@ class Executor(object): return self._changed_targets_list def _get_source(self, *args, **kw): - #return SCons.Util.NodeList([rfile(self.batches[0].sources[0]).get_subst_proxy()]) return rfile(self.batches[0].sources[0]).get_subst_proxy() def _get_sources(self, *args, **kw): return SCons.Util.NodeList([rfile(n).get_subst_proxy() for n in self.get_all_sources()]) def _get_target(self, *args, **kw): - #return SCons.Util.NodeList([self.batches[0].targets[0].get_subst_proxy()]) return self.batches[0].targets[0].get_subst_proxy() def _get_targets(self, *args, **kw): @@ -284,8 +340,7 @@ class Executor(object): result.extend(target.side_effects) return result - memoizer_counters.append(SCons.Memoize.CountValue('get_build_env')) - + @SCons.Memoize.CountMethodCall def get_build_env(self): """Fetch or create the appropriate build Environment for this Executor. @@ -330,36 +385,12 @@ class Executor(object): result['executor'] = self return result - def do_nothing(self, target, kw): - return 0 - - def do_execute(self, target, kw): - """Actually execute the action list.""" - env = self.get_build_env() - kw = self.get_kw(kw) - status = 0 - for act in self.get_action_list(): - #args = (self.get_all_targets(), self.get_all_sources(), env) - args = ([], [], env) - status = act(*args, **kw) - if isinstance(status, SCons.Errors.BuildError): - status.executor = self - raise status - elif status: - msg = "Error %s" % status - raise SCons.Errors.BuildError( - errstr=msg, - node=self.batches[0].targets, - executor=self, - action=act) - return status - # use extra indirection because with new-style objects (Python 2.2 # and above) we can't override special methods, and nullify() needs # to be able to do this. def __call__(self, target, **kw): - return self.do_execute(target, kw) + return _do_execute_map[self._do_execute](self, target, kw) def cleanup(self): self._memo = {} @@ -403,24 +434,15 @@ class Executor(object): # another extra indirection for new-style objects and nullify... - def my_str(self): - env = self.get_build_env() - return "\n".join([action.genstring(self.get_all_targets(), - self.get_all_sources(), - env) - for action in self.get_action_list()]) - - def __str__(self): - return self.my_str() + return _execute_str_map[self._execute_str](self) def nullify(self): self.cleanup() - self.do_execute = self.do_nothing - self.my_str = lambda: '' - - memoizer_counters.append(SCons.Memoize.CountValue('get_contents')) + self._do_execute = 0 + self._execute_str = 0 + @SCons.Memoize.CountMethodCall def get_contents(self): """Fetch the signature contents. This is the main reason this class exists, so we can compute this once and cache it regardless @@ -461,29 +483,15 @@ class Executor(object): each individual target, which is a hell of a lot more efficient. """ env = self.get_build_env() + path = self.get_build_scanner_path + kw = self.get_kw() # TODO(batch): scan by batches) deps = [] - if scanner: - for node in node_list: - node.disambiguate() - s = scanner.select(node) - if not s: - continue - path = self.get_build_scanner_path(s) - deps.extend(node.get_implicit_deps(env, s, path)) - else: - kw = self.get_kw() - for node in node_list: - node.disambiguate() - scanner = node.get_env_scanner(env, kw) - if not scanner: - continue - scanner = scanner.select(node) - if not scanner: - continue - path = self.get_build_scanner_path(scanner) - deps.extend(node.get_implicit_deps(env, scanner, path)) + + for node in node_list: + node.disambiguate() + deps.extend(node.get_implicit_deps(env, scanner, path, kw)) deps.extend(self.get_implicit_deps()) @@ -493,8 +501,7 @@ class Executor(object): def _get_unignored_sources_key(self, node, ignore=()): return (node,) + tuple(ignore) - memoizer_counters.append(SCons.Memoize.CountDict('get_unignored_sources', _get_unignored_sources_key)) - + @SCons.Memoize.CountDictCall(_get_unignored_sources_key) def get_unignored_sources(self, node, ignore=()): key = (node,) + tuple(ignore) try: @@ -554,19 +561,20 @@ def AddBatchExecutor(key, executor): nullenv = None +import SCons.Util +class NullEnvironment(SCons.Util.Null): + import SCons.CacheDir + _CacheDir_path = None + _CacheDir = SCons.CacheDir.CacheDir(None) + def get_CacheDir(self): + return self._CacheDir + + def get_NullEnvironment(): """Use singleton pattern for Null Environments.""" global nullenv - import SCons.Util - class NullEnvironment(SCons.Util.Null): - import SCons.CacheDir - _CacheDir_path = None - _CacheDir = SCons.CacheDir.CacheDir(None) - def get_CacheDir(self): - return self._CacheDir - - if not nullenv: + if nullenv is None: nullenv = NullEnvironment() return nullenv @@ -578,6 +586,23 @@ class Null(object): disassociate Builders from Nodes entirely, so we're not going to worry about unit tests for this--at least for now. """ + + __slots__ = ('pre_actions', + 'post_actions', + 'env', + 'overridelist', + 'batches', + 'builder_kw', + '_memo', + 'lvars', + '_changed_sources_list', + '_changed_targets_list', + '_unchanged_sources_list', + '_unchanged_targets_list', + 'action_list', + '_do_execute', + '_execute_str') + def __init__(self, *args, **kw): if SCons.Debug.track_instances: logInstanceCreation(self, 'Executor.Null') self.batches = [Batch(kw['targets'][:], [])] |