summaryrefslogtreecommitdiffstats
path: root/src/engine/SCons/Executor.py
diff options
context:
space:
mode:
authorRussel Winder <russel@winder.org.uk>2015-12-24 16:32:14 (GMT)
committerRussel Winder <russel@winder.org.uk>2015-12-24 16:32:14 (GMT)
commit2a270c8f314e959c78e9deda29c8f250bb934dd6 (patch)
tree7008e644357036404f0861c8ba1bbbf43b2b4123 /src/engine/SCons/Executor.py
parenta7d764ed831fa3243aa0bd3307f641e1e1f9f8a8 (diff)
parent9d558dd65deacc958edc1f0da2dab1ec56ff4e4e (diff)
downloadSCons-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.py179
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'][:], [])]