summaryrefslogtreecommitdiffstats
path: root/src/engine
diff options
context:
space:
mode:
authorSteven Knight <knight@baldmt.com>2003-09-12 13:07:20 (GMT)
committerSteven Knight <knight@baldmt.com>2003-09-12 13:07:20 (GMT)
commit1c2ac0f2ca0c14d1181add9cc66d9650fece1481 (patch)
tree6c7464dd52b17d0eaeec3cae1fb0b3e5e3a1897a /src/engine
parente181e48bb62502b88107536c2e8dbd5886bf17fd (diff)
downloadSCons-1c2ac0f2ca0c14d1181add9cc66d9650fece1481.zip
SCons-1c2ac0f2ca0c14d1181add9cc66d9650fece1481.tar.gz
SCons-1c2ac0f2ca0c14d1181add9cc66d9650fece1481.tar.bz2
Add SourceSignatures() and TargetSignatures() environment methods.
Diffstat (limited to 'src/engine')
-rw-r--r--src/engine/SCons/Defaults.py3
-rw-r--r--src/engine/SCons/Environment.py50
-rw-r--r--src/engine/SCons/EnvironmentTests.py48
-rw-r--r--src/engine/SCons/Node/__init__.py7
-rw-r--r--src/engine/SCons/Script/SConscript.py28
-rw-r--r--src/engine/SCons/Script/__init__.py6
-rw-r--r--src/engine/SCons/Sig/__init__.py4
-rw-r--r--src/engine/SCons/Taskmaster.py4
8 files changed, 114 insertions, 36 deletions
diff --git a/src/engine/SCons/Defaults.py b/src/engine/SCons/Defaults.py
index 66e8b00..798abb3 100644
--- a/src/engine/SCons/Defaults.py
+++ b/src/engine/SCons/Defaults.py
@@ -51,6 +51,7 @@ import SCons.Node.FS
import SCons.Scanner.C
import SCons.Scanner.Fortran
import SCons.Scanner.Prog
+import SCons.Sig
# A placeholder for a default Environment (for fetching source files
# from source code management systems and the like). This must be
@@ -64,6 +65,8 @@ def DefaultEnvironment(*args, **kw):
global _default_env
if not _default_env:
_default_env = apply(SCons.Environment.Environment, args, kw)
+ _default_env._build_signature = 1
+ _default_env._calc_module = SCons.Sig.default_module
return _default_env
diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py
index f2cc03f..3d00837 100644
--- a/src/engine/SCons/Environment.py
+++ b/src/engine/SCons/Environment.py
@@ -64,7 +64,12 @@ _null = _Null
DefaultTargets = None
CleanTargets = {}
-SigModule = None
+CalculatorArgs = {}
+
+# Pull UserError into the global name space for the benefit of
+# Environment().SourceSignatures(), which has some import statements
+# which seem to mess up its ability to reference SCons directly.
+UserError = SCons.Errors.UserError
def installFunc(target, source, env):
"""Install a source file into a target using the function specified
@@ -312,6 +317,21 @@ class Environment:
return nodes
+ def get_calculator(self):
+ try:
+ return self._calculator
+ except AttributeError:
+ try:
+ module = self._calc_module
+ c = apply(SCons.Sig.Calculator, (module,), CalculatorArgs)
+ except AttributeError:
+ # Note that we're calling get_calculator() here, so the
+ # DefaultEnvironment() must have a _calc_module attribute
+ # to avoid infinite recursion.
+ c = SCons.Defaults.DefaultEnvironment().get_calculator()
+ self._calculator = c
+ return c
+
def get_builder(self, name):
"""Fetch the builder with the specified name from the environment.
"""
@@ -358,6 +378,14 @@ class Environment:
return SCons.Util.scons_subst_list(string, self, mode,
target, source)
+ def use_build_signature(self):
+ try:
+ return self._build_signature
+ except AttributeError:
+ b = SCons.Defaults.DefaultEnvironment()._build_signature
+ self._build_signature = b
+ return b
+
#######################################################################
# Public methods for manipulating an Environment. These begin with
# upper-case letters. The essential characteristic of methods in
@@ -765,3 +793,23 @@ class Environment:
if len(entries) == 1:
return entries[0]
return entries
+
+ def SourceSignatures(self, type):
+ type = self.subst(type)
+ if type == 'MD5':
+ import SCons.Sig.MD5
+ self._calc_module = SCons.Sig.MD5
+ elif type == 'timestamp':
+ import SCons.Sig.TimeStamp
+ self._calc_module = SCons.Sig.TimeStamp
+ else:
+ raise UserError, "Unknown source signature type '%s'"%type
+
+ def TargetSignatures(self, type):
+ type = self.subst(type)
+ if type == 'build':
+ self._build_signature = 1
+ elif type == 'content':
+ self._build_signature = 0
+ else:
+ raise SCons.Errors.UserError, "Unknown target signature type '%s'"%type
diff --git a/src/engine/SCons/EnvironmentTests.py b/src/engine/SCons/EnvironmentTests.py
index 1dc47e2..baf501e 100644
--- a/src/engine/SCons/EnvironmentTests.py
+++ b/src/engine/SCons/EnvironmentTests.py
@@ -1310,6 +1310,54 @@ class EnvironmentTestCase(unittest.TestCase):
s = e.src_builder()
assert s is None, s
+ def test_SourceSignatures(type):
+ """Test the SourceSignatures() method"""
+ env = Environment(M = 'MD5', T = 'timestamp')
+
+ exc_caught = None
+ try:
+ env.SourceSignatures('invalid_type')
+ except SCons.Errors.UserError:
+ exc_caught = 1
+ assert exc_caught, "did not catch expected UserError"
+ assert not hasattr(env, '_calc_module')
+
+ env.SourceSignatures('MD5')
+ m = env._calc_module
+
+ env.SourceSignatures('$M')
+ assert env._calc_module is m
+
+ env.SourceSignatures('timestamp')
+ t = env._calc_module
+
+ env.SourceSignatures('$T')
+ assert env._calc_module is t
+
+ def test_TargetSignatures(type):
+ """Test the TargetSignatures() method"""
+ env = Environment(B = 'build', C = 'content')
+
+ exc_caught = None
+ try:
+ env.TargetSignatures('invalid_type')
+ except SCons.Errors.UserError:
+ exc_caught = 1
+ assert exc_caught, "did not catch expected UserError"
+ assert not hasattr(env, '_build_signature')
+
+ env.TargetSignatures('build')
+ assert env._build_signature == 1, env._build_signature
+
+ env.TargetSignatures('content')
+ assert env._build_signature == 0, env._build_signature
+
+ env.TargetSignatures('$B')
+ assert env._build_signature == 1, env._build_signature
+
+ env.TargetSignatures('$C')
+ assert env._build_signature == 0, env._build_signature
+
if __name__ == "__main__":
suite = unittest.makeSuite(EnvironmentTestCase, 'test_')
diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py
index ea61de6..3802aad 100644
--- a/src/engine/SCons/Node/__init__.py
+++ b/src/engine/SCons/Node/__init__.py
@@ -408,6 +408,10 @@ class Node:
return
self.env = env
+ def calculator(self):
+ env = self.env or SCons.Defaults.DefaultEnvironment()
+ return env.get_calculator()
+
def calc_signature(self, calc):
"""
Select and calculate the appropriate build signature for a node.
@@ -420,7 +424,8 @@ class Node:
return self._calculated_sig
except AttributeError:
if self.is_derived():
- if SCons.Sig.build_signature:
+ env = self.env or SCons.Defaults.DefaultEnvironment()
+ if env.use_build_signature():
sig = self.rfile().calc_bsig(calc, self)
else:
sig = self.rfile().calc_csig(calc, self)
diff --git a/src/engine/SCons/Script/SConscript.py b/src/engine/SCons/Script/SConscript.py
index b79c34a..4f29f26 100644
--- a/src/engine/SCons/Script/SConscript.py
+++ b/src/engine/SCons/Script/SConscript.py
@@ -394,33 +394,13 @@ def SetBuildSignatureType(type):
SCons.Warnings.warn(SCons.Warnings.DeprecatedWarning,
"The SetBuildSignatureType() function has been deprecated;\n" +\
"\tuse the TargetSignatures() function instead.")
- TargetSignatures(type)
-
-def TargetSignatures(type):
- import SCons.Sig
- if type == 'build':
- SCons.Sig.build_signature = 1
- elif type == 'content':
- SCons.Sig.build_signature = 0
- else:
- raise SCons.Errors.UserError, "Unknown build signature type '%s'"%type
+ SCons.Defaults.DefaultEnvironment().TargetSignatures(type)
def SetContentSignatureType(type):
SCons.Warnings.warn(SCons.Warnings.DeprecatedWarning,
"The SetContentSignatureType() function has been deprecated;\n" +\
"\tuse the SourceSignatures() function instead.")
- SourceSignatures(type)
-
-def SourceSignatures(type):
- if type == 'MD5':
- import SCons.Sig.MD5
- SCons.Script.sig_module = SCons.Sig.MD5
- elif type == 'timestamp':
- import SCons.Sig.TimeStamp
- SCons.Script.sig_module = SCons.Sig.TimeStamp
- else:
- raise SCons.Errors.UserError, "Unknown content signature type '%s'"%type
-
+ SCons.Defaults.DefaultEnvironment().SourceSignatures(type)
class Options(SCons.Options.Options):
def __init__(self, files=None, args=arguments):
@@ -534,9 +514,7 @@ def BuildDefaultGlobals():
globals['SetContentSignatureType'] = SetContentSignatureType
globals['SetJobs'] = SetJobs
globals['SetOption'] = SetOption
- globals['SourceSignatures'] = SourceSignatures
globals['Split'] = SCons.Util.Split
- globals['TargetSignatures'] = TargetSignatures
globals['Tool'] = SCons.Tool.Tool
globals['Value'] = SCons.Node.Python.Value
globals['WhereIs'] = SCons.Util.WhereIs
@@ -566,6 +544,8 @@ def BuildDefaultGlobals():
'Precious',
'SideEffect',
'SourceCode',
+ 'SourceSignatures',
+ 'TargetSignatures',
]
for name in EnvironmentMethods:
diff --git a/src/engine/SCons/Script/__init__.py b/src/engine/SCons/Script/__init__.py
index 34b112f..61e7561 100644
--- a/src/engine/SCons/Script/__init__.py
+++ b/src/engine/SCons/Script/__init__.py
@@ -233,7 +233,6 @@ command_time = 0
exit_status = 0 # exit status, assume success by default
profiling = 0
repositories = []
-sig_module = SCons.Sig.default_module
num_jobs = 1 # this is modifed by SConscript.SetJobs()
# Exceptions for this module
@@ -942,10 +941,7 @@ def _main(args, parser):
except AttributeError:
pass
- if not calc:
- SCons.Sig.default_calc = SCons.Sig.Calculator(module=sig_module,
- max_drift=ssoptions.get('max_drift'))
- calc = SCons.Sig.default_calc
+ SCons.Environment.CalculatorArgs['max_drift'] = ssoptions.get('max_drift')
if options.random:
def order(dependencies):
diff --git a/src/engine/SCons/Sig/__init__.py b/src/engine/SCons/Sig/__init__.py
index 0245a2c..4898f29 100644
--- a/src/engine/SCons/Sig/__init__.py
+++ b/src/engine/SCons/Sig/__init__.py
@@ -51,10 +51,6 @@ sig_files = []
SConsign_db = None
-# 1 means use build signature for derived source files
-# 0 means use content signature for derived source files
-build_signature = 1
-
def write():
global sig_files
for sig_file in sig_files:
diff --git a/src/engine/SCons/Taskmaster.py b/src/engine/SCons/Taskmaster.py
index 7937569..9b13b60 100644
--- a/src/engine/SCons/Taskmaster.py
+++ b/src/engine/SCons/Taskmaster.py
@@ -161,8 +161,10 @@ class Task:
def make_ready(self):
"""Make a task ready for execution."""
state = SCons.Node.up_to_date
+ calc = self.tm.calc
for t in self.targets:
- if not t.current(self.tm.calc):
+ c = calc or t.calculator()
+ if not t.current(c):
state = SCons.Node.executing
for t in self.targets:
if state == SCons.Node.executing: