summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Knight <knight@baldmt.com>2002-07-12 06:17:59 (GMT)
committerSteven Knight <knight@baldmt.com>2002-07-12 06:17:59 (GMT)
commit721c0b5439329cce1a68d44c0e58204a83d9d354 (patch)
tree640ad8f81638eaf79461675d47418643fbb2e6b1
parent25846c09acbebca4f41664a76dfc6175b3617e90 (diff)
downloadSCons-721c0b5439329cce1a68d44c0e58204a83d9d354.zip
SCons-721c0b5439329cce1a68d44c0e58204a83d9d354.tar.gz
SCons-721c0b5439329cce1a68d44c0e58204a83d9d354.tar.bz2
Added --implicit-deps-unchanged option. Added GetLaunchDir() function. Added SetBuildSignatureType() function. (Anthony Roach)
-rw-r--r--doc/man/scons.17
-rw-r--r--src/CHANGES.txt6
-rw-r--r--src/engine/SCons/Node/__init__.py5
-rw-r--r--src/engine/SCons/Script/SConscript.py15
-rw-r--r--src/engine/SCons/Script/__init__.py9
-rw-r--r--src/engine/SCons/Sig/__init__.py13
-rw-r--r--test/SetBuildSignatureType.py122
-rw-r--r--test/option--U.py6
-rw-r--r--test/option--implicit-cache.py31
9 files changed, 210 insertions, 4 deletions
diff --git a/doc/man/scons.1 b/doc/man/scons.1
index 8c02eff..8761335 100644
--- a/doc/man/scons.1
+++ b/doc/man/scons.1
@@ -400,6 +400,13 @@ dependency is added earlier in the implicit dependency search path
(e.g. CPPPATH) than a current implicit dependency with the same name.
.TP
+--implicit-deps-unchanged
+Force SCons to ignore changes in the implicit dependencies.
+This causes cached implicit dependencies to always be used.
+This implies
+.BR --implicit-cache .
+
+.TP
.RI -j " N" ", --jobs=" N
Specifies the number of jobs (commands) to run simultaneously.
If there is more than one
diff --git a/src/CHANGES.txt b/src/CHANGES.txt
index 8cc8060..6b0c79c 100644
--- a/src/CHANGES.txt
+++ b/src/CHANGES.txt
@@ -135,6 +135,12 @@ RELEASE 0.08 -
suffix computation, code cleanup in MultiStepBuilder.__call__(),
and replicating some logic in scons_subst().
+ - Add a --implicit-deps-unchanged option.
+
+ - Add a GetLaunchDir() function.
+
+ - Add a SetBuildSignatureType() function.
+
From Zed Shaw:
- Add an Append() method to Environments, to append values to
diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py
index 1e23198..bc0539e 100644
--- a/src/engine/SCons/Node/__init__.py
+++ b/src/engine/SCons/Node/__init__.py
@@ -57,6 +57,9 @@ stack = 6 # nodes that are in the current Taskmaster execution stack
# controls whether implicit depedencies are cached:
implicit_cache = 0
+# controls whether implicit dep changes are ignored:
+implicit_deps_unchanged = 0
+
class Node:
"""The base Node class, for entities that we know how to
build, or use to build other Nodes.
@@ -203,7 +206,7 @@ class Node:
implicit = map(self.builder.source_factory, implicit)
self._add_child(self.implicit, implicit)
calc = SCons.Sig.default_calc
- if calc.current(self, calc.bsig(self)):
+ if implicit_deps_unchanged or calc.current(self, calc.bsig(self)):
return
else:
# one of this node's sources has changed, so
diff --git a/src/engine/SCons/Script/SConscript.py b/src/engine/SCons/Script/SConscript.py
index 0f65732..48c4046 100644
--- a/src/engine/SCons/Script/SConscript.py
+++ b/src/engine/SCons/Script/SConscript.py
@@ -39,6 +39,7 @@ import SCons.Node.FS
import SCons.Platform
import SCons.Tool
import SCons.Util
+import SCons.Sig
import os
import os.path
@@ -48,6 +49,7 @@ import sys
default_targets = []
print_help = 0
arguments = {}
+launch_dir = os.path.abspath(os.curdir)
# global exports set by Export():
global_exports = {}
@@ -243,6 +245,17 @@ def Import(*vars):
except KeyError,x:
raise SCons.Errors.UserError, "Import of non-existant variable '%s'"%x
+def GetLaunchDir():
+ return launch_dir
+
+def SetBuildSignatureType(type):
+ 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
+
def BuildDefaultGlobals():
"""
Create a dictionary containing all the default globals for
@@ -281,4 +294,6 @@ def BuildDefaultGlobals():
globals['Split'] = SCons.Util.Split
globals['Tool'] = SCons.Tool.Tool
globals['WhereIs'] = SCons.Util.WhereIs
+ globals['GetLaunchDir'] = GetLaunchDir
+ globals['SetBuildSignatureType'] = SetBuildSignatureType
return globals
diff --git a/src/engine/SCons/Script/__init__.py b/src/engine/SCons/Script/__init__.py
index 6f87353..1d53fed 100644
--- a/src/engine/SCons/Script/__init__.py
+++ b/src/engine/SCons/Script/__init__.py
@@ -550,6 +550,15 @@ def options_init():
long = ['implicit-cache'],
help = "Cache implicit dependencies")
+ def opt_implicit_deps_unchanged(opt, arg):
+ import SCons.Node
+ SCons.Node.implicit_cache = 1
+ SCons.Node.implicit_deps_unchanged = 1
+
+ Option(func = opt_implicit_deps_unchanged,
+ long = ['implicit-deps-unchanged'],
+ help = "Ignore changes in implicit deps.")
+
def opt_j(opt, arg):
global num_jobs
try:
diff --git a/src/engine/SCons/Sig/__init__.py b/src/engine/SCons/Sig/__init__.py
index 553c9ce..0e629fb 100644
--- a/src/engine/SCons/Sig/__init__.py
+++ b/src/engine/SCons/Sig/__init__.py
@@ -38,6 +38,10 @@ import time
#XXX Get rid of the global array so this becomes re-entrant.
sig_files = []
+# 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:
@@ -359,13 +363,13 @@ class Calculator:
def get_signature(self, node):
"""
- Get the appropriate signature for a node.
+ Get the appropriate build signature for a node.
node - the node
returns - the signature or None if the signature could not
be computed.
- This method does not store the signature in the node and
+ This method does not store the signature in the node or
in the .sconsign file.
"""
@@ -374,7 +378,10 @@ class Calculator:
# directory) so bail right away.
return None
elif node.builder:
- return self.bsig(node)
+ if build_signature:
+ return self.bsig(node)
+ else:
+ return self.csig(node)
elif not node.exists():
return None
else:
diff --git a/test/SetBuildSignatureType.py b/test/SetBuildSignatureType.py
new file mode 100644
index 0000000..39534dd
--- /dev/null
+++ b/test/SetBuildSignatureType.py
@@ -0,0 +1,122 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2001, 2002 Steven Knight
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+test.write('SConstruct', """
+env = Environment()
+
+def copy1(env, source, target):
+ print 'copy %s -> %s'%(str(source[0]), str(target[0]))
+ open(str(target[0]), 'wb').write(open(str(source[0]), 'rb').read())
+
+def copy2(env, source, target):
+ return copy1(env, source, target)
+
+env['BUILDERS']['Copy1'] = Builder(action=copy1)
+env['BUILDERS']['Copy2'] = Builder(action=copy2)
+
+env.Copy2('foo.out', 'foo.in')
+env.Copy1('foo.out.out', 'foo.out')
+
+SetBuildSignatureType('content')
+""")
+
+test.write('foo.in', 'foo.in')
+
+test.run(arguments='foo.out.out', stdout='copy foo.in -> foo.out\ncopy foo.out -> foo.out.out\n')
+
+test.run(arguments='foo.out.out', stdout='scons: "foo.out.out" is up to date.\n')
+
+test.write('SConstruct', """
+env = Environment()
+
+def copy1(env, source, target):
+ print 'copy %s -> %s'%(str(source[0]), str(target[0]))
+ open(str(target[0]), 'wb').write(open(str(source[0]), 'rb').read())
+
+def copy2(env, source, target):
+ # added this line
+ return copy1(env, source, target)
+
+env['BUILDERS']['Copy1'] = Builder(action=copy1)
+env['BUILDERS']['Copy2'] = Builder(action=copy2)
+
+env.Copy2('foo.out', 'foo.in')
+env.Copy1('foo.out.out', 'foo.out')
+
+SetBuildSignatureType('content')
+""")
+
+test.run(arguments='foo.out.out', stdout='copy foo.in -> foo.out\nscons: "foo.out.out" is up to date.\n')
+
+test.write('SConstruct', """
+env = Environment()
+
+def copy1(env, source, target):
+ print 'copy %s -> %s'%(str(source[0]), str(target[0]))
+ open(str(target[0]), 'wb').write(open(str(source[0]), 'rb').read())
+
+def copy2(env, source, target):
+ # added this line
+ return copy1(env, source, target)
+
+env['BUILDERS']['Copy1'] = Builder(action=copy1)
+env['BUILDERS']['Copy2'] = Builder(action=copy2)
+
+env.Copy2('foo.out', 'foo.in')
+env.Copy1('foo.out.out', 'foo.out')
+
+SetBuildSignatureType('build')
+""")
+
+test.run(arguments='foo.out.out', stdout='copy foo.out -> foo.out.out\n')
+
+test.write('SConstruct', """
+env = Environment()
+
+def copy1(env, source, target):
+ print 'copy %s -> %s'%(str(source[0]), str(target[0]))
+ open(str(target[0]), 'wb').write(open(str(source[0]), 'rb').read())
+
+def copy2(env, source, target):
+ return copy1(env, source, target)
+
+env['BUILDERS']['Copy1'] = Builder(action=copy1)
+env['BUILDERS']['Copy2'] = Builder(action=copy2)
+
+env.Copy2('foo.out', 'foo.in')
+env.Copy1('foo.out.out', 'foo.out')
+
+SetBuildSignatureType('build')
+""")
+
+test.run(arguments='foo.out.out', stdout='copy foo.in -> foo.out\ncopy foo.out -> foo.out.out\n')
+
+
+test.pass_test()
diff --git a/test/option--U.py b/test/option--U.py
index a683a8d..1facab8 100644
--- a/test/option--U.py
+++ b/test/option--U.py
@@ -54,6 +54,7 @@ Default(env.B(target = 'sub3/baz.out', source = 'sub3/baz.in'))
BuildDir('sub2b', 'sub2')
SConscript('sub2b/SConscript')
Default(env.B(target = 'sub2/xxx.out', source = 'xxx.in'))
+SConscript('SConscript')
""" % python)
test.write(['sub2', 'SConscript'], """
@@ -70,6 +71,7 @@ test.write(['sub2', 'bar.in'], "sub2/bar.in\n")
test.write(['sub3', 'baz.in'], "sub3/baz.in\n")
test.write('xxx.in', "xxx.in\n")
+test.write('SConscript', """assert GetLaunchDir() == '%s'"""%test.workpath('sub1'))
test.run(arguments = '-U foo.out', chdir = 'sub1')
test.fail_test(not os.path.exists(test.workpath('sub1', 'foo.out')))
@@ -81,6 +83,7 @@ test.fail_test(os.path.exists(test.workpath('sub2/xxx.out')))
test.unlink(['sub1', 'foo.out'])
+test.write('SConscript', """assert GetLaunchDir() == '%s'"""%test.workpath('sub1'))
test.run(arguments = '-U', chdir = 'sub1')
test.fail_test(os.path.exists(test.workpath('sub1', 'foo.out')))
test.fail_test(os.path.exists(test.workpath('sub2', 'bar.out')))
@@ -89,6 +92,7 @@ test.fail_test(os.path.exists(test.workpath('sub3', 'baz.out')))
test.fail_test(os.path.exists(test.workpath('bar.out')))
test.fail_test(os.path.exists(test.workpath('sub2/xxx.out')))
+test.write('SConscript', """assert GetLaunchDir() == '%s'"""%test.workpath('sub2'))
test.run(chdir = 'sub2', arguments = '-U')
test.fail_test(os.path.exists(test.workpath('sub1', 'foo.out')))
test.fail_test(not os.path.exists(test.workpath('sub2', 'bar.out')))
@@ -101,6 +105,7 @@ test.unlink(['sub2', 'bar.out'])
test.unlink(['sub2b', 'bar.out'])
test.unlink('bar.out')
+test.write('SConscript', """assert GetLaunchDir() == '%s'"""%test.workpath())
test.run(arguments='-U')
test.fail_test(not os.path.exists(test.workpath('sub1', 'foo.out')))
test.fail_test(os.path.exists(test.workpath('sub2', 'bar.out')))
@@ -113,6 +118,7 @@ test.unlink(['sub1', 'foo.out'])
test.unlink(['sub3', 'baz.out'])
test.unlink(['sub2', 'xxx.out'])
+test.write('SConscript', """assert GetLaunchDir() == '%s'"""%test.workpath('sub3'))
test.run(chdir = 'sub3', arguments='-U bar')
test.fail_test(os.path.exists(test.workpath('sub1', 'foo.out')))
test.fail_test(not os.path.exists(test.workpath('sub2', 'bar.out')))
diff --git a/test/option--implicit-cache.py b/test/option--implicit-cache.py
index 3460b2f..d6ca15c 100644
--- a/test/option--implicit-cache.py
+++ b/test/option--implicit-cache.py
@@ -27,6 +27,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import os
import sys
import TestSCons
+import string
if sys.platform == 'win32':
_exe = '.exe'
@@ -266,4 +267,34 @@ main(int argc, char *argv[])
test.run(arguments = "--implicit-cache one%s"%_obj)
test.run(arguments = "--implicit-cache one%s"%_obj)
+# Test forcing of implicit caching:
+test.write(['include', 'foo.h'],
+r"""
+#define FOO_STRING "include/foo.h 3\n"
+#include "bar.h"
+""")
+
+test.run(arguments = "--implicit-cache " + args)
+
+test.write(['include', 'foo.h'],
+r"""
+#define FOO_STRING "include/foo.h 3\n"
+#include "baz.h"
+#include "bar.h"
+""")
+
+test.run(arguments = "--implicit-deps-unchanged " + variant_prog)
+assert string.find(test.stdout(), 'is up to date') == -1, test.stdout()
+
+test.write(['include', 'baz.h'],
+r"""
+#define BAZ_STRING "include/baz.h 2\n"
+""")
+
+test.run(arguments = "--implicit-deps-unchanged " + variant_prog)
+assert string.find(test.stdout(), 'is up to date') != -1, test.stdout()
+
+test.run(arguments = variant_prog)
+assert string.find(test.stdout(), 'is up to date') == -1, test.stdout()
+
test.pass_test()