Fix use of timestamps with --implicit-cache. (Anthony Roach)
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Sat, 1 May 2004 19:21:11 +0000 (19:21 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Sat, 1 May 2004 19:21:11 +0000 (19:21 +0000)
git-svn-id: http://scons.tigris.org/svn/scons/trunk@965 fdb21ef1-2011-0410-befe-b5e4ea1792b1

doc/man/scons.1
src/CHANGES.txt
src/RELEASE.txt
src/engine/SCons/Node/__init__.py
src/engine/SCons/Scanner/ScannerTests.py
src/engine/SCons/Scanner/__init__.py
src/engine/SCons/Sig/__init__.py
test/SourceSignatures.py
test/scan-once.py

index ba4e6901043213a0d8205889f24121a3cffd9816..bb0bbd3c98527d92ef50fdcdb6515e268b6ab11e 100644 (file)
@@ -7156,8 +7156,9 @@ and turn it into the appropriate class of Node
 to be returned by this Scanner object.
 
 .IP scan_check
-An optional Python function that takes a Node (file)
-as an argument and returns whether the
+An optional Python function that takes two arguments,
+a Node (file) and a construction environment,
+and returns whether the
 Node should, in fact,
 be scanned for dependencies.
 This check can be used to eliminate unnecessary
index 1d54390a39c6f70876c62ca3ca26655260517944..3e7fa911a2c1fa74949916357620b8786bb2f09c 100644 (file)
@@ -120,6 +120,10 @@ RELEASE 0.96 - XXX
 
   - Fix a bug introduced in building shared libraries under MinGW.
 
+  From Anthony Roach:
+
+  - Fix use of the --implicit-cache option with timestamp signatures.
+
   From sam th:
 
   - Allow SConf.CheckLib() to search a list of libraries, like the
index c7b46fdd86c2bd57a5277adc623a9259bda2156a..e651afb25b544b22fbdebf06e7ef1d069fe33c55 100644 (file)
@@ -37,9 +37,13 @@ RELEASE 0.96 - XXX
           import anydbm
           SConsignFile('.sconsign_file_name', anydbm)
 
-    - The internal Scanner.add_skey() method longer works for the default
-      scanners, which now use construction variables to hold their lists
-      of suffixes.  If you had a custom Tool specification that was
+    - The scan_check function that can be supplied to a custom Scanner now
+      must take two arguments, the Node to be checked and a construction
+      environment.  It previously only used the Node as an argument.
+
+    - The internal Scanner.add_skey() method no longer works for the
+      default scanners, which now use construction variables to hold their
+      lists of suffixes.  If you had a custom Tool specification that was
       reaching into the internals in this way to add a suffix to one of
       the following scanner, you must now add the suffix to a construction
       environment through which you plan to call the scanner, as follows:
index ceac5caf1863f166dfa3db6027c82c709a32e5da..9897d1ac79014e779e29ef877150137e2b2656d0 100644 (file)
@@ -390,12 +390,14 @@ class Node:
         if not self.has_builder():
             return
 
+        build_env = self.get_build_env()
+
         if implicit_cache and not implicit_deps_changed:
             implicit = self.get_stored_implicit()
             if implicit is not None:
                 implicit = map(self.implicit_factory, implicit)
                 self._add_child(self.implicit, self.implicit_dict, implicit)
-                calc = SCons.Sig.default_calc
+                calc = build_env.get_calculator()
                 if implicit_deps_unchanged or calc.current(self, calc.bsig(self)):
                     return
                 else:
@@ -407,8 +409,6 @@ class Node:
                     self._children_reset()
                     self.del_binfo()
 
-        build_env = self.get_build_env()
-
         for child in self.children(scan=0):
             scanner = child.source_scanner
             if scanner:
index 91a0f8c8a50bd3f10ddc3df81a8936c1ec89a4f6..4e662a2ae5e3ba1b147f1212053f46c422006a70 100644 (file)
@@ -26,6 +26,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 import sys
 import unittest
 import UserDict
+import SCons.Sig
 
 import SCons.Scanner
 
@@ -45,6 +46,8 @@ class DummyEnvironment(UserDict.UserDict):
         if type(path) != type([]):
             path = [path]
         return map(self.subst, path)
+    def get_calculator(self):
+        return SCons.Sig.default_calc
 
 class FindPathDirsTestCase(unittest.TestCase):
     def test_FindPathDirs(self):
@@ -61,7 +64,7 @@ class FindPathDirsTestCase(unittest.TestCase):
         assert result == ('xxx', 'foo'), result
 
 class ScannerTestCase(unittest.TestCase):
-    
+
     def func(self, filename, env, target, *args):
         self.filename = filename
         self.env = env
@@ -69,7 +72,7 @@ class ScannerTestCase(unittest.TestCase):
 
         if len(args) > 0:
             self.arg = args[0]
-        
+
         return self.deps
 
     def test(self, scanner, env, filename, deps, *args):
@@ -148,7 +151,7 @@ class ScannerTestCase(unittest.TestCase):
         """Test the Scanner.Base class scan_check() method"""
         def my_scan(filename, env, target, *args):
             return []
-        def check(node, s=self):
+        def check(node, env, s=self):
             s.checked[node] = 1
             return 1
         env = DummyEnvironment()
index 102849db869f53473a3592b5d5421629b8b62fea..8f6c9e6a9eea1f1d778837cf98e27af497853eda 100644 (file)
@@ -158,7 +158,7 @@ class Base:
         environment that will be passed to the scanner function. A list of
         direct dependency nodes for the specified node will be returned.
         """
-        if self.scan_check and not self.scan_check(node):
+        if self.scan_check and not self.scan_check(node, env):
             return []
 
         if not self.argument is _null:
@@ -199,8 +199,8 @@ class Current(Base):
     """
 
     def __init__(self, *args, **kw):
-        def current_check(node):
-            c = not node.has_builder() or node.current(SCons.Sig.default_calc)
+        def current_check(node, env):
+            c = not node.has_builder() or node.current(env.get_calculator())
             return c
         kw['scan_check'] = current_check
         apply(Base.__init__, (self,) + args, kw)
index 6bdfe099e28d90cb9589858981cb6ecb4305170e..dac3f6c11d9d9c07a8c573f12a9c747a366caaef 100644 (file)
@@ -458,6 +458,9 @@ class Calculator:
         
         oldtime, oldbsig, oldcsig = node.get_prevsiginfo()
 
+        if type(newsig) != type(oldbsig):
+            return 0
+
         if not node.has_builder() and node.get_timestamp() == oldtime:
             return 1
 
index e982fbe8f7d25602f687d4a4453bbb2984a78513..10dfb29c48b815b0daa2a422ee27862a3e3129e1 100644 (file)
@@ -27,6 +27,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 import imp
 import os
 import os.path
+import time
 
 import TestSCons
 
@@ -172,4 +173,117 @@ scons: `f8.out' is up to date.
 
 test.up_to_date(arguments = 'f5.out f6.out f7.out f8.out')
 
+# Ensure that switching signature types causes a rebuild:
+test.write('SConstruct', """
+SourceSignatures('MD5')
+
+def build(env, target, source):
+    open(str(target[0]), 'wt').write(open(str(source[0]), 'rt').read())
+B = Builder(action = build)
+env = Environment(BUILDERS = { 'B' : B })
+env.B(target = 'switch.out', source = 'switch.in')
+""")
+
+test.write('switch.in', "switch.in\n")
+
+test.run(arguments = 'switch.out',
+         stdout = test.wrap_stdout("""\
+build("switch.out", "switch.in")
+"""))
+
+test.up_to_date(arguments = 'switch.out')
+
+test.write('SConstruct', """
+SourceSignatures('timestamp')
+
+def build(env, target, source):
+    open(str(target[0]), 'wt').write(open(str(source[0]), 'rt').read())
+B = Builder(action = build)
+env = Environment(BUILDERS = { 'B' : B })
+env.B(target = 'switch.out', source = 'switch.in')
+""")
+
+test.run(arguments = 'switch.out',
+         stdout = test.wrap_stdout("""\
+build("switch.out", "switch.in")
+"""))
+
+test.up_to_date(arguments = 'switch.out')
+
+test.write('SConstruct', """
+SourceSignatures('MD5')
+
+def build(env, target, source):
+    open(str(target[0]), 'wt').write(open(str(source[0]), 'rt').read())
+B = Builder(action = build)
+env = Environment(BUILDERS = { 'B' : B })
+env.B(target = 'switch.out', source = 'switch.in')
+""")
+
+test.run(arguments = 'switch.out',
+         stdout = test.wrap_stdout("""\
+build("switch.out", "switch.in")
+"""))
+
+test.up_to_date(arguments = 'switch.out')
+
+test.write('switch.in', "switch.in 2\n")
+
+test.run(arguments = 'switch.out',
+         stdout = test.wrap_stdout("""\
+build("switch.out", "switch.in")
+"""))
+
+
+# Test both implicit_cache and timestamp signatures at the same time:
+test.write('SConstruct', """
+SetOption('implicit_cache', 1)
+SourceSignatures('timestamp')
+
+def build(env, target, source):
+    open(str(target[0]), 'wt').write(open(str(source[0]), 'rt').read())
+B = Builder(action = build)
+env = Environment(BUILDERS = { 'B' : B })
+env.B(target = 'both.out', source = 'both.in')
+""")
+
+test.write('both.in', "both.in 1\n")
+
+test.run(arguments = 'both.out',
+         stdout = test.wrap_stdout("""\
+build("both.out", "both.in")
+"""))
+
+time.sleep(2)
+
+test.write('both.in', "both.in 2\n")
+
+test.run(arguments = 'both.out',
+         stdout = test.wrap_stdout("""\
+build("both.out", "both.in")
+"""))
+
+time.sleep(2)
+
+test.write('both.in', "both.in 3\n")
+
+test.run(arguments = 'both.out',
+         stdout = test.wrap_stdout("""\
+build("both.out", "both.in")
+"""))
+
+time.sleep(2)
+
+test.write('both.in', "both.in 4\n")
+
+test.run(arguments = 'both.out',
+         stdout = test.wrap_stdout("""\
+build("both.out", "both.in")
+"""))
+
+time.sleep(2)
+
+
+test.up_to_date(arguments = 'both.out')
+
 test.pass_test()
index cfc4a25c802a8b271430e2f6afbe8f3b181e4d29..52b45050909778c2277da7f4425aab6d0640af99 100644 (file)
@@ -62,7 +62,7 @@ def scan(node, env, envkey, arg):
     print 'XScanner: node =', os.path.split(str(node))[1]
     return []
 
-def exists_check(node):
+def exists_check(node, env):
     return os.path.exists(str(node))
 
 XScanner = Scanner(name = 'XScanner',