summaryrefslogtreecommitdiffstats
path: root/library/demos
diff options
context:
space:
mode:
authorKevin B Kenny <kennykb@acm.org>2009-12-15 03:43:32 (GMT)
committerKevin B Kenny <kennykb@acm.org>2009-12-15 03:43:32 (GMT)
commitbf9abb7ceed49cb412e42ac2f7f5d5d017da72c4 (patch)
treedee55299cef993236100ed0d0eefde6538e85908 /library/demos
parent8ee911aabfe4c142f7e1bc7cc347630c6351baf3 (diff)
downloadtk-bf9abb7ceed49cb412e42ac2f7f5d5d017da72c4.zip
tk-bf9abb7ceed49cb412e42ac2f7f5d5d017da72c4.tar.gz
tk-bf9abb7ceed49cb412e42ac2f7f5d5d017da72c4.tar.bz2
* library/demos/unicodeout.tcl: Added code to check for
right-to-left support on Windows and adjust Hebrew and Arabic character strings accordingly. Changed the Hebrew string to 'ktb ebryt' (ktav Ivrit, "Hebrew writing") to be consistent with at least the Greek and Russian strings. Thanks to Rodrigo Readi for calling the inconsistency to our attention.
Diffstat (limited to 'library/demos')
-rw-r--r--library/demos/unicodeout.tcl60
1 files changed, 41 insertions, 19 deletions
diff --git a/library/demos/unicodeout.tcl b/library/demos/unicodeout.tcl
index 3d733e1..8e108b6 100644
--- a/library/demos/unicodeout.tcl
+++ b/library/demos/unicodeout.tcl
@@ -3,7 +3,7 @@
# This demonstration script shows how you can produce output (in label
# widgets) using many different alphabets.
#
-# RCS: @(#) $Id: unicodeout.tcl,v 1.7 2007/12/13 15:27:07 dgp Exp $
+# RCS: @(#) $Id: unicodeout.tcl,v 1.7.2.1 2009/12/15 03:43:33 kennykb Exp $
if {![info exists widgetDemo]} {
error "This script should be run from the \"widget\" demo."
@@ -11,6 +11,26 @@ if {![info exists widgetDemo]} {
package require Tk
+# On Windows, we need to determine whether the font system will render
+# right-to-left text.
+
+if {[tk windowingsystem] eq {win32}} {
+ set rkey [join {
+ HKEY_LOCAL_MACHINE
+ SOFTWARE
+ Microsoft
+ {Windows NT}
+ CurrentVersion
+ LanguagePack
+ } \\]
+ set w32langs {}
+ if {![catch {package require registry}]} {
+ if {[catch {registry values $rkey} w32langs]} {
+ set w32langs {}
+ }
+ }
+}
+
set w .unicodeout
catch {destroy $w}
toplevel $w
@@ -55,32 +75,34 @@ set oldCursor [$w cget -cursor]
$w conf -cursor watch
update
-if {[tk windowingsystem] in {x11 win32}} {
- # Using presentation forms (pre-layouted)
- addSample $w Arabic \
- "\uFE94\uFEF4\uFE91\uFEAE\uFECC\uFEDF\uFE8D " \
- "\uFE94\uFEE4\uFEE0\uFEDC\uFEDF\uFE8D"
+if {[tk windowingsystem] eq {x11}
+ || (([tk windowingsystem] eq {win32}) && ({ARABIC} ni $w32langs))} {
+ # Using presentation forms (pre-layouted)
+ addSample $w Arabic \
+ "\uFE94\uFEF4\uFE91\uFEAE\uFECC\uFEDF\uFE8D " \
+ "\uFE94\uFEE4\uFEE0\uFEDC\uFEDF\uFE8D"
} else {
- # Using standard text characters
- addSample $w Arabic \
- "\u0627\u0644\u0643\u0644\u0645\u0629 " \
- "\u0627\u0644\u0639\u0631\u0628\u064A\u0629"
+ # Using standard text characters
+ addSample $w Arabic \
+ "\u0627\u0644\u0643\u0644\u0645\u0629 " \
+ "\u0627\u0644\u0639\u0631\u0628\u064A\u0629"
}
addSample $w "Trad. Chinese" "\u4E2D\u570B\u7684\u6F22\u5B57"
addSample $w "Simpl. Chinese" "\u6C49\u8BED"
addSample $w Greek \
"\u0395\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03AE " \
"\u03B3\u03BB\u03CE\u03C3\u03C3\u03B1"
-if {[tk windowingsystem] in {x11 win32}} {
- # Visual order (pre-layouted)
- addSample $w Hebrew \
- "\u05DD\u05D9\u05DC\u05E9\u05D5\u05E8\u05D9 " \
- "\u05DC\u05D9\u05D0\u05E8\u05E9\u05D9"
+if {[tk windowingsystem] eq {x11}
+ || (([tk windowingsystem] eq {win32}) && ({HEBREW} ni $w32langs))} {
+ # Visual order (pre-layouted)
+ addSample $w Hebrew \
+ "\u05EA\u05D9\u05E8\u05D1\u05E2 " \
+ "\u05D1\u05EA\u05DB"
} else {
- # Standard logical order
- addSample $w Hebrew \
- "\u05D9\u05E9\u05E8\u05D0\u05D9\u05DC " \
- "\u05D9\u05E8\u05D5\u05E9\u05DC\u05D9\u05DD"
+ # Standard logical order
+ addSample $w Hebrew \
+ "\u05DB\u05EA\u05D1 " \
+ "\u05E2\u05D1\u05E8\u05D9\u05EA"
}
addSample $w Japanese \
"\u65E5\u672C\u8A9E\u306E\u3072\u3089\u304C\u306A, " \
................ r2394 | stevenknight | 2007-08-28 21:37:04 -0500 (Tue, 28 Aug 2007) | 3 lines Separate the failure tests when trying to connect to an X server, so we can tell why it's failing... ................ r2395 | stevenknight | 2007-08-29 11:46:34 -0500 (Wed, 29 Aug 2007) | 3 lines Look for a raw exit status of 1, or the shifted exit status, so we're not dependent on how the test infrastructure hands it to us. ................ r2396 | stevenknight | 2007-08-29 18:12:39 -0500 (Wed, 29 Aug 2007) | 2 lines Disable universal_newlines when calling subprocess. ................ r2397 | stevenknight | 2007-08-29 18:13:29 -0500 (Wed, 29 Aug 2007) | 3 lines Add a Progress() hook to support display of per-Node progress while walking the DAG. ................ r2398 | stevenknight | 2007-08-29 19:43:12 -0500 (Wed, 29 Aug 2007) | 7 lines Add a test case (courtesy Greg Noel) to characterize how we handle mid-build changes to implicit dependency files (we currently don't detect the change and rebuild all dependents). Move two other test scripts related to implicit dependency behavior into a common subdirectory. ................ r2399 | stevenknight | 2007-08-30 10:32:50 -0500 (Thu, 30 Aug 2007) | 4 lines Add a $JAVABOOTCLASSPATH variable. Commonize $JAVA*PATH expansion with a utility class. (Greg Ward) ................ r2400 | stevenknight | 2007-08-30 10:59:56 -0500 (Thu, 30 Aug 2007) | 3 lines Make sure extra auxiliary files generated by LaTeX packages are deleted by scons -c. (Matthias Troffaes) ................ r2401 | stevenknight | 2007-08-30 18:43:24 -0500 (Thu, 30 Aug 2007) | 3 lines Issue 1589: when Cloning a construction environment, apply set variables both before and after calling tools (like during intialization). ................ r2402 | stevenknight | 2007-08-30 18:52:02 -0500 (Thu, 30 Aug 2007) | 3 lines Issue 1555: add Windows64 support for the Intel C compiler. (Gary Oberbrunner) ................ r2403 | stevenknight | 2007-08-30 19:57:24 -0500 (Thu, 30 Aug 2007) | 4 lines Issue 1493: have ParseConfig(), MergeFlags() and ParseFlags() handle output from *-config commands with quoted arguments (path names that contain spaces). ................ r2410 | stevenknight | 2007-09-04 00:28:46 -0500 (Tue, 04 Sep 2007) | 4 lines Add a shlex.split() compatability wrapper for pre-Python 2.3 versions. Unfortunately, it doesn't behave exactly like later versions (it doesn't detect mid-token quotes), but we're not going to worry about that. ................ r2411 | stevenknight | 2007-09-04 12:56:36 -0500 (Tue, 04 Sep 2007) | 3 lines Add a Sig.py module that generates a warning if user code tries to "import SCons.Sig" directly. ................ r2412 | stevenknight | 2007-09-04 20:53:09 -0500 (Tue, 04 Sep 2007) | 3 lines Make the Return() function return immediately. Add a stop= keyword argument in case anyone really needs the old behavior. ................ r2413 | stevenknight | 2007-09-05 10:38:40 -0500 (Wed, 05 Sep 2007) | 4 lines Refactor initialization of different pieces (the underlying InstallBuilder, the Install() and InstallAs() wrappers) into separate blocks. ................ r2414 | stevenknight | 2007-09-05 11:39:25 -0500 (Wed, 05 Sep 2007) | 4 lines Move the definitions of the wrapper functions to the global namespace (nesting them and delaying intialization of global variables doesn't save anything and just complicates reading the code). ................ r2415 | stevenknight | 2007-09-05 13:31:27 -0500 (Wed, 05 Sep 2007) | 3 lines When Cloning a construction environment, re-bind any methods added by the AddMethod() method to the new construction environment. ................ r2416 | stevenknight | 2007-09-06 10:04:18 -0500 (Thu, 06 Sep 2007) | 7 lines Add a MethodWrapper class that handles generic association of a callable and an object that wants to use the callable as a "method." Provide hooks for centralized cloning of the different "methods" on to a new, copied underlying environment (used by the env.Clone() method). Make BuilderWrapper a subclass of MethodWrapper. Modify env.Clone() for the new, combined way of handling these "methods." ................ r2417 | stevenknight | 2007-09-06 14:11:35 -0500 (Thu, 06 Sep 2007) | 2 lines Refactor test failure conditions to use test.must_match(). ................ r2418 | stevenknight | 2007-09-06 14:28:52 -0500 (Thu, 06 Sep 2007) | 9 lines Restore the ability to use the Install() and InstallAs() builders without having to specify the 'install' tool directly. Add a ToolInitializer class that handles delayed intialization of tool modules when added to a construction environment as a "method." Add an env.RemoveModule() method that takes care of removing an added MethodWrapper instance from the environment, deleting it from the list that gets copied on cloning (and changing the name of that list back to "added_methods"). ................ r2419 | stevenknight | 2007-09-07 06:27:33 -0500 (Fri, 07 Sep 2007) | 3 lines Issue 1725: avoid race conditions when pushing a file to CacheDir(). (Carsten Koch) ................ r2420 | pscholl | 2007-09-07 09:13:28 -0500 (Fri, 07 Sep 2007) | 7 lines * delete the push_emitter() function. Direct manipulation of the source and target lists seem the way to go for packaging. Fix all packagers using this function. * fix the internationalization testcase ................ r2421 | pscholl | 2007-09-07 09:14:12 -0500 (Fri, 07 Sep 2007) | 3 lines * new testcase for building multiple rpm packages from one scons call. ................ r2422 | stevenknight | 2007-09-07 14:12:22 -0500 (Fri, 07 Sep 2007) | 4 lines Capture a test script with a particular reported test case for multiple Package() calls spread across different SConscript subdirectories. (Use case courtesy Andrew Smith.) ................ r2423 | stevenknight | 2007-09-07 17:40:25 -0500 (Fri, 07 Sep 2007) | 4 lines Fix use of exitstatfunc on Action objects by getting rid of the ability to override exitstatfunc when calling a function (which we were only using internally to basically suppress whatever was set on the Action object). ................ r2424 | stevenknight | 2007-09-10 20:06:59 -0500 (Mon, 10 Sep 2007) | 3 lines Make sure the library dependencies show up in --tree=derived output. (The Microsoft toolchain used to fail this on SCons 0.97 and earlier.) ................ r2425 | stevenknight | 2007-09-10 22:25:27 -0500 (Mon, 10 Sep 2007) | 5 lines When adding a new entry to a directory, reset the .implicit attribute to None so that the directory will get "re-scanned" for implicit dependencies (the entries within the directory) if it gets re-visited later in the DAG walk. ................ r2426 | stevenknight | 2007-09-12 12:38:05 -0500 (Wed, 12 Sep 2007) | 2 lines String method fix for Python 1.5.2. ................ r2427 | stevenknight | 2007-09-12 12:38:29 -0500 (Wed, 12 Sep 2007) | 2 lines Remove left-over commented-out Trace() call. ................ r2428 | stevenknight | 2007-09-13 01:36:34 -0500 (Thu, 13 Sep 2007) | 2 lines Handle Java inner class names with $ in them. (Tzvetan Mikov) ................ r2429 | stevenknight | 2007-09-13 14:29:09 -0500 (Thu, 13 Sep 2007) | 2 lines Add a check that should (possibly) avoid import errors on Solaris. ................ r2430 | stevenknight | 2007-09-13 14:30:36 -0500 (Thu, 13 Sep 2007) | 5 lines Windows portability fixes for Progress() tests, restoring the original universal_newlines setting on the test infrastructure, changing file names to make the order in which Nodes are visited case-insensitive, and fixing line endings on output we expect to read from files. ................ r2431 | stevenknight | 2007-09-14 07:58:44 -0500 (Fri, 14 Sep 2007) | 2 lines Make sure all function examples are introduced by "Example:" or "Examples:". ................ r2432 | stevenknight | 2007-09-14 11:35:03 -0500 (Fri, 14 Sep 2007) | 3 lines Clean up Options files initialization so we don't have to check on usage for whether it's been set. ................ r2433 | stevenknight | 2007-09-14 23:12:32 -0500 (Fri, 14 Sep 2007) | 4 lines Fix use of {Source,Target}Signatures() with construction variable overrides by making the default decider_*() things unbound functions, instead of bound methods. ................ r2434 | stevenknight | 2007-09-14 23:14:25 -0500 (Fri, 14 Sep 2007) | 2 lines Don't use "True" in the test infrastructure, use 1 instead. ................ r2435 | stevenknight | 2007-09-15 00:52:56 -0500 (Sat, 15 Sep 2007) | 2 lines Avoid use of False in two tests. ................ r2436 | pscholl | 2007-09-17 08:14:35 -0500 (Mon, 17 Sep 2007) | 21 lines * additional testcase for packaging: * building multiple packages from one scons call * supplying explicit target names for msi and rpm * test the Find*Files() functions * modify the package-type option test to not only catch the PACKAGETYPE, but also the --package-type alias command line argument * move FindInstalledFiles to Environment.py and remove Find*Files() functions from the packaging module. * capitalize the VENDOR tag for msi * remove the superfluous packager.py files * Add documentation for FindInstalledFiles() and FindSourceFiles() ................ r2437 | stevenknight | 2007-09-17 11:06:28 -0500 (Mon, 17 Sep 2007) | 2 lines Provide compatibility for the variables defined in SCons.Sig. ................ r2438 | stevenknight | 2007-09-17 23:13:27 -0500 (Mon, 17 Sep 2007) | 5 lines Handle duplicate fies in a target list: only decrement the reference count once for the target, not once for each time it shows up in the list, so dependencies don't "disappear" from the DAG walk because the reference count gets decremented past zero. ................ r2439 | stevenknight | 2007-09-17 23:15:45 -0500 (Mon, 17 Sep 2007) | 2 lines Fix syntax errors from failure to quote the package type. ................ r2440 | stevenknight | 2007-09-17 23:21:20 -0500 (Mon, 17 Sep 2007) | 2 lines Use AddOption() to support the --package-type option. ................ r2441 | stevenknight | 2007-09-17 23:31:40 -0500 (Mon, 17 Sep 2007) | 2 lines Skip the test if tar isn't available. ................ r2442 | stevenknight | 2007-09-18 06:35:04 -0500 (Tue, 18 Sep 2007) | 2 lines Remove Tool/packaging/packager.py from the manifest. ................ r2443 | garyo | 2007-09-18 08:13:15 -0500 (Tue, 18 Sep 2007) | 1 line SGI IRIX: use proper C++ compiler for SHCXX, don't hardcode CC. ................ r2444 | garyo | 2007-09-18 08:17:03 -0500 (Tue, 18 Sep 2007) | 1 line Avoid running MinGW tests on IRIX; they're irrelevant there and they fail anyway (they seem to pass on Linux, so left them in there.) ................ r2445 | garyo | 2007-09-18 08:20:52 -0500 (Tue, 18 Sep 2007) | 1 line Fixed wrong return type in test code; caused warnings on IRIX which made test fail. ................ r2446 | stevenknight | 2007-09-18 11:21:53 -0500 (Tue, 18 Sep 2007) | 2 lines Record Gary's change to the sgic++ tool. ................ r2451 | stevenknight | 2007-09-19 00:01:46 -0500 (Wed, 19 Sep 2007) | 2 lines Windows portability fix (when checking for path names in output). ................ r2452 | stevenknight | 2007-09-19 00:08:23 -0500 (Wed, 19 Sep 2007) | 2 lines Handle the ImportError if there's no threading module on Windows. ................ --- .svnt/conf | 2 + QMTest/TestCmd.py | 181 ++-- QMTest/TestCommon.py | 4 +- QMTest/TestSCons.py | 7 +- SConstruct | 19 +- bench/dependency-func.py | 98 +++ doc/man/scons.1 | 708 ++++++++++++++- doc/man/sconsign.1 | 23 +- runtest.py | 1 + src/CHANGES.txt | 76 ++ src/RELEASE.txt | 86 +- src/engine/MANIFEST.in | 6 +- src/engine/SCons/Action.py | 32 +- src/engine/SCons/Action.xml | 35 + src/engine/SCons/Builder.py | 28 +- src/engine/SCons/CacheDir.py | 26 +- src/engine/SCons/CacheDirTests.py | 31 +- src/engine/SCons/Debug.py | 1 + src/engine/SCons/Defaults.py | 39 +- src/engine/SCons/Environment.py | 304 +++++-- src/engine/SCons/EnvironmentTests.py | 147 +++- src/engine/SCons/Executor.py | 52 +- src/engine/SCons/ExecutorTests.py | 48 +- src/engine/SCons/JobTests.py | 14 +- src/engine/SCons/Node/Alias.py | 38 +- src/engine/SCons/Node/FS.py | 1097 +++++++++++++++--------- src/engine/SCons/Node/FSTests.py | 250 +++--- src/engine/SCons/Node/NodeTests.py | 182 ++-- src/engine/SCons/Node/Python.py | 34 +- src/engine/SCons/Node/PythonTests.py | 2 +- src/engine/SCons/Node/__init__.py | 483 ++++++----- src/engine/SCons/Options/__init__.py | 20 +- src/engine/SCons/SConf.py | 106 ++- src/engine/SCons/SConfTests.py | 21 +- src/engine/SCons/SConsign.py | 179 ++-- src/engine/SCons/SConsignTests.py | 198 +++-- src/engine/SCons/Scanner/ScannerTests.py | 19 +- src/engine/SCons/Scanner/__init__.py | 4 +- src/engine/SCons/Script/Main.py | 85 +- src/engine/SCons/Script/SConscript.py | 17 +- src/engine/SCons/Script/__init__.py | 4 +- src/engine/SCons/Sig.py | 57 ++ src/engine/SCons/Sig/.aeignore | 5 - src/engine/SCons/Sig/.cvsignore | 1 - src/engine/SCons/Sig/MD5.py | 104 --- src/engine/SCons/Sig/MD5Tests.py | 113 --- src/engine/SCons/Sig/SigTests.py | 49 -- src/engine/SCons/Sig/TimeStamp.py | 75 -- src/engine/SCons/Sig/TimeStampTests.py | 84 -- src/engine/SCons/Sig/__init__.py | 53 -- src/engine/SCons/Taskmaster.py | 142 ++- src/engine/SCons/TaskmasterTests.py | 51 +- src/engine/SCons/Tool/JavaCommon.py | 2 +- src/engine/SCons/Tool/JavaCommonTests.py | 15 + src/engine/SCons/Tool/__init__.py | 51 +- src/engine/SCons/Tool/install.py | 115 ++- src/engine/SCons/Tool/intelc.py | 22 +- src/engine/SCons/Tool/javac.py | 60 +- src/engine/SCons/Tool/javac.xml | 14 + src/engine/SCons/Tool/midl.py | 5 +- src/engine/SCons/Tool/msvs.py | 3 + src/engine/SCons/Tool/msvsTests.py | 1 + src/engine/SCons/Tool/packaging/__init__.py | 187 ++-- src/engine/SCons/Tool/packaging/ipk.py | 8 +- src/engine/SCons/Tool/packaging/msi.py | 28 +- src/engine/SCons/Tool/packaging/packager.py | 218 ----- src/engine/SCons/Tool/packaging/rpm.py | 35 +- src/engine/SCons/Tool/packaging/src_tarbz2.py | 4 +- src/engine/SCons/Tool/packaging/src_targz.py | 4 +- src/engine/SCons/Tool/packaging/src_zip.py | 4 +- src/engine/SCons/Tool/packaging/tarbz2.py | 6 +- src/engine/SCons/Tool/packaging/targz.py | 6 +- src/engine/SCons/Tool/packaging/zip.py | 6 +- src/engine/SCons/Tool/rpm.py | 1 - src/engine/SCons/Tool/sgic++.py | 2 +- src/engine/SCons/Tool/tex.py | 16 +- src/engine/SCons/Tool/wix.py | 8 +- src/engine/SCons/Util.py | 92 +- src/engine/SCons/UtilTests.py | 42 +- src/engine/SCons/compat/__init__.py | 34 +- src/engine/SCons/compat/_scons_hashlib.py | 85 ++ src/engine/SCons/compat/_scons_subprocess.py | 8 +- src/script/sconsign.py | 105 ++- src/setup.py | 1 - test/Actions/addpost-link.py | 22 +- test/Actions/exitstatfunc.py | 67 ++ test/Actions/timestamp.py | 56 ++ test/AddMethod.py | 12 +- test/Alias/Depends.py | 162 ++++ test/BuildDir/errors.py | 1 - test/Builder/ensure_suffix.py | 55 ++ test/CacheDir/multiple-targets.py | 66 ++ test/CacheDir/scanner-target.py | 80 ++ test/CacheDir/timestamp.py | 48 ++ test/Configure/clean.py | 96 +++ test/Configure/help.py | 109 +++ test/Copy.py | 13 +- test/Decider/Environment.py | 61 ++ test/Decider/MD5-timestamp.py | 81 ++ test/Decider/Node.py | 61 ++ test/Decider/default.py | 59 ++ test/Decider/mixed.py | 115 +++ test/Decider/timestamp.py | 113 +++ test/Decider/unknown.py | 46 + test/Delete.py | 20 +- test/Depends.py | 3 + test/Dir/source.py | 4 +- test/Errors/preparation.py | 11 +- test/Install/Install.py | 22 +- test/Install/tool.py | 51 ++ test/Java/JAVABOOTCLASSPATH.py | 108 +++ test/Java/multi-step.py | 22 +- test/Java/swig-dependencies.py | 19 +- test/LIBS.py | 2 +- test/MinGW/RCCOM.py | 4 +- test/MinGW/RCCOMSTR.py | 4 +- test/NodeOps.py | 10 +- test/Parallel/duplicate-target.py | 74 ++ test/Progress/TARGET.py | 66 ++ test/Progress/dots.py | 60 ++ test/Progress/file.py | 81 ++ test/Progress/function.py | 75 ++ test/Progress/interval.py | 68 ++ test/Progress/object.py | 78 ++ test/Progress/spinner.py | 66 ++ test/QT/installed.py | 9 +- test/QT/moc-from-header.py | 3 +- test/SConscript/Return.py | 93 ++ test/SWIG/build-dir.py | 8 +- test/Scanner/generated.py | 9 +- test/Sig.py | 62 ++ test/SourceCode.py | 2 +- test/SourceSignatures.py | 268 ------ test/SourceSignatures/basic.py | 124 +++ test/SourceSignatures/env.py | 96 +++ test/SourceSignatures/implicit-cache.py | 87 ++ test/SourceSignatures/no-csigs.py | 70 ++ test/SourceSignatures/overrides.py | 56 ++ test/SourceSignatures/switch-rebuild.py | 81 ++ test/TEX/auxiliaries.py | 13 +- test/TEX/clean.py | 94 ++ test/TargetSignatures.py | 161 ---- test/TargetSignatures/build-content.py | 125 +++ test/TargetSignatures/content.py | 81 ++ test/TargetSignatures/overrides.py | 52 ++ test/Value.py | 22 +- test/bad-drive.py | 2 +- test/chained-build.py | 29 +- test/changed-node.py | 142 --- test/exceptions.py | 63 +- test/explain/get_csig.py | 75 ++ test/implicit-cache/basic.py | 6 + test/implicit/IMPLICIT_COMMAND_DEPENDENCIES.py | 125 +++ test/implicit/asynchronous-modification.py | 89 ++ test/implicit/changed-node.py | 142 +++ test/option-q.py | 151 ---- test/option-u.py | 1 - test/option/debug-memoizer.py | 1 - test/option/debug-stree.py | 38 +- test/option/debug-time.py | 6 + test/option/debug-tree.py | 46 +- test/option/taskmastertrace.py | 65 +- test/option/tree-all.py | 89 +- test/option/tree-lib.py | 88 ++ test/packaging/convenience-functions.py | 76 ++ test/packaging/msi/explicit-target.py | 92 ++ test/packaging/multiple-packages-at-once.py | 82 ++ test/packaging/multiple-subdirs.py | 80 ++ test/packaging/option--package-type.py | 11 +- test/packaging/place-files-in-subdirectory.py | 2 +- test/packaging/rpm/cleanup.py | 8 +- test/packaging/rpm/explicit-target.py | 95 ++ test/packaging/rpm/internationalization.py | 2 - test/packaging/rpm/multipackage.py | 115 +++ test/packaging/strip-install-dir.py | 5 + test/question/Configure.py | 114 +++ test/question/basic.py | 75 ++ test/question/no-builder.py | 45 + test/runtest/fallback.py | 14 +- test/runtest/noqmtest.py | 14 +- test/runtest/python.py | 10 +- test/sconsign/script/Configure.py | 87 ++ test/sconsign/script/SConsignFile.py | 362 +++++--- test/sconsign/script/Signatures.py | 44 +- test/sconsign/script/dblite.py | 50 +- test/sconsign/script/no-SConsignFile.py | 210 +++-- test/timestamp-fallback.py | 14 + test/up-to-date.py | 33 +- 188 files changed, 9478 insertions(+), 3636 deletions(-) create mode 100644 bench/dependency-func.py create mode 100644 src/engine/SCons/Sig.py delete mode 100644 src/engine/SCons/Sig/.aeignore delete mode 100644 src/engine/SCons/Sig/.cvsignore delete mode 100644 src/engine/SCons/Sig/MD5.py delete mode 100644 src/engine/SCons/Sig/MD5Tests.py delete mode 100644 src/engine/SCons/Sig/SigTests.py delete mode 100644 src/engine/SCons/Sig/TimeStamp.py delete mode 100644 src/engine/SCons/Sig/TimeStampTests.py delete mode 100644 src/engine/SCons/Sig/__init__.py delete mode 100644 src/engine/SCons/Tool/packaging/packager.py create mode 100644 src/engine/SCons/compat/_scons_hashlib.py create mode 100644 test/Actions/exitstatfunc.py create mode 100644 test/Actions/timestamp.py create mode 100644 test/Alias/Depends.py create mode 100644 test/Builder/ensure_suffix.py create mode 100644 test/CacheDir/multiple-targets.py create mode 100644 test/CacheDir/scanner-target.py create mode 100644 test/CacheDir/timestamp.py create mode 100644 test/Configure/clean.py create mode 100644 test/Configure/help.py create mode 100644 test/Decider/Environment.py create mode 100644 test/Decider/MD5-timestamp.py create mode 100644 test/Decider/Node.py create mode 100644 test/Decider/default.py create mode 100644 test/Decider/mixed.py create mode 100644 test/Decider/timestamp.py create mode 100644 test/Decider/unknown.py create mode 100644 test/Install/tool.py create mode 100644 test/Java/JAVABOOTCLASSPATH.py create mode 100644 test/Parallel/duplicate-target.py create mode 100644 test/Progress/TARGET.py create mode 100644 test/Progress/dots.py create mode 100644 test/Progress/file.py create mode 100644 test/Progress/function.py create mode 100644 test/Progress/interval.py create mode 100644 test/Progress/object.py create mode 100644 test/Progress/spinner.py create mode 100644 test/SConscript/Return.py create mode 100644 test/Sig.py delete mode 100644 test/SourceSignatures.py create mode 100644 test/SourceSignatures/basic.py create mode 100644 test/SourceSignatures/env.py create mode 100644 test/SourceSignatures/implicit-cache.py create mode 100644 test/SourceSignatures/no-csigs.py create mode 100644 test/SourceSignatures/overrides.py create mode 100644 test/SourceSignatures/switch-rebuild.py create mode 100644 test/TEX/clean.py delete mode 100644 test/TargetSignatures.py create mode 100644 test/TargetSignatures/build-content.py create mode 100644 test/TargetSignatures/content.py create mode 100644 test/TargetSignatures/overrides.py delete mode 100644 test/changed-node.py create mode 100644 test/explain/get_csig.py create mode 100644 test/implicit/IMPLICIT_COMMAND_DEPENDENCIES.py create mode 100644 test/implicit/asynchronous-modification.py create mode 100644 test/implicit/changed-node.py delete mode 100644 test/option-q.py create mode 100644 test/option/tree-lib.py create mode 100644 test/packaging/convenience-functions.py create mode 100644 test/packaging/msi/explicit-target.py create mode 100644 test/packaging/multiple-packages-at-once.py create mode 100644 test/packaging/multiple-subdirs.py create mode 100644 test/packaging/rpm/explicit-target.py create mode 100644 test/packaging/rpm/multipackage.py create mode 100644 test/question/Configure.py create mode 100644 test/question/basic.py create mode 100644 test/question/no-builder.py create mode 100644 test/sconsign/script/Configure.py diff --git a/.svnt/conf b/.svnt/conf index dece324..d4ffcb7 100644 --- a/.svnt/conf +++ b/.svnt/conf @@ -7,6 +7,8 @@ build = [ '"%(python)s" bootstrap.py %%s' % locals() ] +build_test_baseline = [] + cmd = '"%(python)s" runtest.py -q --noqmtest %%s' % locals() test_inputs = [ diff --git a/QMTest/TestCmd.py b/QMTest/TestCmd.py index 7a668e8..08642cb 100644 --- a/QMTest/TestCmd.py +++ b/QMTest/TestCmd.py @@ -103,6 +103,9 @@ things. Here is an overview of them: test.match_re_dotall("actual 1\nactual 2\n", regex_string) test.match_re_dotall(["actual 1\n", "actual 2\n"], list_of_regexes) + test.tempdir() + test.tempdir('temporary-directory') + test.sleep() test.sleep(seconds) @@ -176,8 +179,8 @@ version. # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. __author__ = "Steven Knight " -__revision__ = "TestCmd.py 0.23.D001 2006/11/30 13:57:29 knight" -__version__ = "0.23" +__revision__ = "TestCmd.py 0.26.D001 2007/08/20 21:58:58 knight" +__version__ = "0.26" import os import os.path @@ -225,6 +228,10 @@ else: return type(e) is types.StringType or isinstance(e, UserString) tempfile.template = 'testcmd.' +if os.name in ('posix', 'nt'): + tempfile.template = 'testcmd.' + str(os.getpid()) + '.' +else: + tempfile.template = 'testcmd.' re_space = re.compile('\s') @@ -459,7 +466,8 @@ class TestCmd: subdir = None, verbose = None, match = None, - combine = 0): + combine = 0, + universal_newlines = 1): self._cwd = os.getcwd() self.description_set(description) self.program_set(program) @@ -471,6 +479,7 @@ class TestCmd: verbose = 0 self.verbose_set(verbose) self.combine = combine + self.universal_newlines = universal_newlines if not match is None: self.match_func = match else: @@ -685,7 +694,8 @@ class TestCmd: interpreter = None, arguments = None, chdir = None, - stdin = None): + stdin = None, + universal_newlines = None): """Runs a test of the program or script for the test environment. Standard output and error output are saved for future retrieval via the stdout() and stderr() methods. @@ -721,48 +731,67 @@ class TestCmd: cmd_string = string.join(map(self.escape, cmd), ' ') if self.verbose: sys.stderr.write(cmd_string + "\n") + if universal_newlines is None: + universal_newlines = self.universal_newlines + try: - p = popen2.Popen3(cmd, 1) - except AttributeError: - if sys.platform == 'win32' and cmd_string[0] == '"': - cmd_string = '"' + cmd_string + '"' - (tochild, fromchild, childerr) = os.popen3(' ' + cmd_string) - if stdin: - if is_List(stdin): - for line in stdin: - tochild.write(line) - else: - tochild.write(stdin) - tochild.close() - out = fromchild.read() - err = childerr.read() - if self.combine: - self._stdout.append(out + err) + import subprocess + except ImportError: + try: + Popen3 = popen2.Popen3 + except AttributeError: + class Popen3: + def __init__(self, command): + (stdin, stdout, stderr) = os.popen3(' ' + command) + self.stdin = stdin + self.stdout = stdout + self.stderr = stderr + def close_output(self): + self.stdout.close() + self.resultcode = self.stderr.close() + def wait(self): + return self.resultcode + if sys.platform == 'win32' and cmd_string[0] == '"': + cmd_string = '"' + cmd_string + '"' + p = Popen3(cmd_string) else: - self._stdout.append(out) - self._stderr.append(err) - fromchild.close() - self.status = childerr.close() - if not self.status: - self.status = 0 - except: - raise + p = Popen3(cmd, 1) + p.stdin = p.tochild + p.stdout = p.fromchild + p.stderr = p.childerr else: - if stdin: - if is_List(stdin): - for line in stdin: - p.tochild.write(line) - else: - p.tochild.write(stdin) - p.tochild.close() - out = p.fromchild.read() - err = p.childerr.read() - if self.combine: - self._stdout.append(out + err) + p = subprocess.Popen(cmd, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + universal_newlines=universal_newlines) + + if stdin: + if is_List(stdin): + for line in stdin: + p.stdin.write(line) else: - self._stdout.append(out) - self._stderr.append(err) - self.status = p.wait() + p.stdin.write(stdin) + p.stdin.close() + + out = p.stdout.read() + err = p.stderr.read() + try: + p.close_output() + except AttributeError: + p.stdout.close() + p.stderr.close() + + self.status = p.wait() + if not self.status: + self.status = 0 + + if self.combine: + self._stdout.append(out + err) + else: + self._stdout.append(out) + self._stderr.append(err) + if chdir: os.chdir(oldcwd) if self.verbose >= 2: @@ -852,6 +881,45 @@ class TestCmd: link = self.canonicalize(link) os.symlink(target, link) + def tempdir(self, path=None): + """Creates a temporary directory. + A unique directory name is generated if no path name is specified. + The directory is created, and will be removed when the TestCmd + object is destroyed. + """ + if path is None: + try: + path = tempfile.mktemp(prefix=tempfile.template) + except TypeError: + path = tempfile.mktemp() + os.mkdir(path) + + # Symlinks in the path will report things + # differently from os.getcwd(), so chdir there + # and back to fetch the canonical path. + cwd = os.getcwd() + try: + os.chdir(path) + path = os.getcwd() + finally: + os.chdir(cwd) + + # Uppercase the drive letter since the case of drive + # letters is pretty much random on win32: + drive,rest = os.path.splitdrive(path) + if drive: + path = string.upper(drive) + rest + + # + self._dirlist.append(path) + global _Cleanup + try: + _Cleanup.index(self) + except ValueError: + _Cleanup.append(self) + + return path + def touch(self, path, mtime=None): """Updates the modification time on the specified file or directory path name. The default is to update to the @@ -894,32 +962,9 @@ class TestCmd: """ if (path != None): if path == '': - path = tempfile.mktemp() - if path != None: - os.mkdir(path) - # We'd like to set self.workdir like this: - # self.workdir = path - # But symlinks in the path will report things - # differently from os.getcwd(), so chdir there - # and back to fetch the canonical path. - cwd = os.getcwd() - os.chdir(path) - self.workdir = os.getcwd() - os.chdir(cwd) - # Uppercase the drive letter since the case of drive - # letters is pretty much random on win32: - drive,rest = os.path.splitdrive(self.workdir) - if drive: - self.workdir = string.upper(drive) + rest - # - self._dirlist.append(self.workdir) - global _Cleanup - try: - _Cleanup.index(self) - except ValueError: - _Cleanup.append(self) - else: - self.workdir = None + path = None + path = self.tempdir(path) + self.workdir = path def workpath(self, *args): """Returns the absolute path name to a subdirectory or file diff --git a/QMTest/TestCommon.py b/QMTest/TestCommon.py index b8fb5cd..f4c7c54 100644 --- a/QMTest/TestCommon.py +++ b/QMTest/TestCommon.py @@ -80,8 +80,8 @@ The TestCommon module also provides the following variables # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. __author__ = "Steven Knight " -__revision__ = "TestCommon.py 0.23.D001 2006/11/30 13:57:29 knight" -__version__ = "0.23" +__revision__ = "TestCommon.py 0.26.D001 2007/08/20 21:58:58 knight" +__version__ = "0.26" import os import os.path diff --git a/QMTest/TestSCons.py b/QMTest/TestSCons.py index 9c270fa..b1fdbc1 100644 --- a/QMTest/TestSCons.py +++ b/QMTest/TestSCons.py @@ -207,7 +207,7 @@ class TestSCons(TestCommon): except (SCons.Errors.UserError, SCons.Errors.InternalError): return None - def detect(self, var, prog=None, ENV=None): + def detect(self, var, prog=None, ENV=None, norm=None): """ Detect a program named 'prog' by first checking the construction variable named 'var' and finally searching the path used by @@ -224,7 +224,10 @@ class TestSCons(TestCommon): prog = v if v != prog: return None - return env.WhereIs(prog) + result = env.WhereIs(prog) + if norm and os.sep != '/': + result = string.replace(result, os.sep, '/') + return result def detect_tool(self, tool, prog=None, ENV=None): """ diff --git a/SConstruct b/SConstruct index e00e109..b35e3b0 100644 --- a/SConstruct +++ b/SConstruct @@ -119,11 +119,12 @@ if checkpoint: checkpoint = 'r' + revision version = version + checkpoint +svn_status = None +svn_status_lines = [] + if svn: svn_status = os.popen("%s status --verbose 2> /dev/null" % svn, "r").read() svn_status_lines = svn_status[:-1].split('\n') -else: - svn_status_lines = [] build_id = ARGUMENTS.get('BUILD_ID') if build_id is None: @@ -158,14 +159,14 @@ command_line_variables = [ "The default is whatever hostname is returned " + "by socket.gethostname()."), - ("CHECKPOINT=", "The specific checkpoint release being packaged. " + - "This will be appended to the VERSION string. " + + ("CHECKPOINT=", "The specific checkpoint release being packaged, " + + "which will be appended to the VERSION string. " + "A value of CHECKPOINT=d will generate a string " + - "of 'd' plus today's date in the format YYYMMDD." + + "of 'd' plus today's date in the format YYYMMDD. " + "A value of CHECKPOINT=r will generate a " + - "string of 'r' plus the Subversion revision number. " + - "Any other CHECKPOINT= string will be used as is." + - "There is no default value."), + "string of 'r' plus the Subversion revision " + + "number. Any other CHECKPOINT= string will be " + + "used as is. There is no default value."), ("DATE=", "The date string representing when the packaging " + "build occurred. The default is the day and time " + @@ -238,7 +239,7 @@ import textwrap indent_fmt = ' %-26s ' -Help(""" +Help("""\ The following aliases build packages of various types, and unpack the contents into build/test-$PACKAGE subdirectories, which can be used by the runtest.py -p option to run tests against what's been actually packaged: diff --git a/bench/dependency-func.py b/bench/dependency-func.py new file mode 100644 index 0000000..0af411d --- /dev/null +++ b/bench/dependency-func.py @@ -0,0 +1,98 @@ +# __COPYRIGHT__ +# +# Benchmarks for testing the selection of dependency changed functions +# in src/engine/Environment.py. + + +def use_a_dict(env, dep, arg): + func = { + '1111' : dep.func1, + '2222' : dep.func2, + '3333' : dep.func3, + '4444' : dep.func4, + } + t = env.get_type() + return func[t](arg) + + +def use_if_tests(env, dep, arg): + t = env.get_type() + if t == '1111': + func = dep.func1 + elif t == '2222': + func = dep.func2 + elif t == '3333': + func = dep.func3 + elif t == '4444': + func = dep.func4 + else: + raise Exception, "bad key %s" % t + return func(arg) + + +class Environment(): + def __init__(self, t): + self.t = t + def get_type(self): + return self.t + +class Node(): + def func1(self, arg): + pass + def func2(self, arg): + pass + def func3(self, arg): + pass + def func4(self, arg): + pass + +node = Node() + +def Func01(t): + """use_a_dict""" + env = Environment(t) + for i in IterationList: + use_a_dict(env, node, None) + +def Func02(t): + """use_if_tests""" + env = Environment(t) + for i in IterationList: + use_if_tests(env, node, None) + + + +# Data to pass to the functions on each run. Each entry is a +# three-element tuple: +# +# ( +# "Label to print describing this data run", +# ('positional', 'arguments'), +# {'keyword' : 'arguments'}, +# ), + +class A: + pass + +Data = [ + ( + "1", + ('1111',), + {}, + ), + ( + "2", + ('2222',), + {}, + ), + ( + "3", + ('3333',), + {}, + ), + ( + "4", + ('4444',), + {}, + ), +] diff --git a/doc/man/scons.1 b/doc/man/scons.1 index a20a0f6..6f87b20 100644 --- a/doc/man/scons.1 +++ b/doc/man/scons.1 @@ -2013,6 +2013,8 @@ specified .I function itself is used for the method name. +Examples: + .ES # Note that the first argument to the function to # be attached as a method must be the object through @@ -2192,6 +2194,8 @@ can be called multiple times for the same alias to add additional targets to the alias, or additional actions to the list for this alias. +Examples: + .ES Alias('install') Alias('install', '/usr/bin') @@ -2225,6 +2229,7 @@ If is called multiple times, each call completely overwrites the previous list of allowed exceptions. + Example: .ES @@ -2276,6 +2281,8 @@ are both coerced to lists, and the lists are added together. (See also the Prepend method, below.) +Example: + .ES env.Append(CCFLAGS = ' -g', FOO = ['foo.yyy']) .EE @@ -2298,6 +2305,7 @@ and This can also handle the case where the given old path variable is a list instead of a string, in which case a list will be returned instead of a string. + Example: .ES @@ -2325,6 +2333,8 @@ construction variable will .I not be added again to the list. +Example: + .ES env.AppendUnique(CCFLAGS = '-g', FOO = ['foo.yyy']) .EE @@ -2341,6 +2351,8 @@ is intended to be passed to the .B SourceCode function. +Example: + .ES env.SourceCode('.', env.BitKeeper()) .EE @@ -2666,6 +2678,7 @@ or by a .B \- (hyphen) to ignore the exit status of the external command. + Examples: .ES @@ -2700,7 +2713,9 @@ by using the .BR Dir () or .BR env.Dir () -functions: +functions. + +Examples: .ES env.Command('ddd.list', Dir('ddd'), 'ls -l $SOURCE > $TARGET') @@ -2733,6 +2748,8 @@ they are added to the returned copy, overwriting any existing values for the keywords. +Example: + .ES env2 = env.Clone() env3 = env.Clone(CCFLAGS = '-g') @@ -2750,7 +2767,7 @@ env4 = env.Clone(tools = ['msvc', MyTool]) .TP .RI env.Copy([ key = val ", ...])" A synonym for -env.Clone(). +.BR env.Clone() . (This will probably be officially deprecated some day.) '\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" @@ -2777,7 +2794,9 @@ from the repository path names, so that you only have to replicate part of the repository directory hierarchy in your -local build directory: +local build directory. + +Examples: .ES # Will fetch foo/bar/src.c @@ -2795,6 +2814,163 @@ env.SourceCode('.', env.CVS('/usr/local/CVSROOT', 'foo/bar')) '\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .TP +.RI Decider( function ) +.TP +.RI env.Decider( function ) +Specifies that all up-to-date decisions for +targets built through this construction environment +will be handled by the specified +.IR function . +The +.I function +can be one of the following strings +that specify the type of decision function +to be performed: + +.RS 10 +.B timestamp-newer +Specifies that a target shall be considered out of date and rebuilt +if the dependency's timestamp is newer than the target file's timestamp. +This is the behavior of the classic Make utility, +and +.B make +can be used a synonym for +.BR timestamp-newer . + +.HP 6 +.B timestamp-match +Specifies that a target shall be considered out of date and rebuilt +if the dependency's timestamp is different than the +timestamp recorded the last time the target was built. +This provides behavior very similar to the classic Make utility +(in particular, files are not opened up so that their +contents can be checksummed) +except that the target will also be rebuilt if a +dependency file has been restored to a version with an +.I earlier +timestamp, such as can happen when restoring files from backup archives. + +.HP 6 +.B MD5 +Specifies that a target shall be considered out of date and rebuilt +if the dependency's content has changed sine the last time +the target was built, +as determined be performing an MD5 checksum +on the dependency's contents +and comparing it to the checksum recorded the +last time the target was built. +.B content +can be used as a synonym for +.BR MD5 . + +.HP 6 +.B MD5-timestamp +Specifies that a target shall be considered out of date and rebuilt +if the dependency's content has changed sine the last time +the target was built, +except that dependencies with a timestamp that matches +the last time the target was rebuilt will be +assumed to be up-to-date and +.I not +rebuilt. +This provides behavior very similar +to the +.B MD5 +behavior of always checksumming file contents, +with an optimization of not checking +the contents of files whose timestamps haven't changed. +The drawback is that SCons will +.I not +detect if a file's content has changed +but its timestamp is the same, +as might happen in an automated script +that runs a build, +updates a file, +and runs the build again, +all within a single second. +.RE + +Examples: + +.ES +# Use exact timestamp matches by default. +Decider('timestamp-match') + +# Use MD5 content signatures for any targets built +# with the attached construction environment. +env.Decider('content') +.EE + +In addition to the above already-available functions, +the +.I function +argument may be an actual Python function +that takes the following three arguments: + +.IP dependency +The Node (file) which +should cause the +.I target +to be rebuilt +if it has "changed" since the last tme +.I target was built. + +.IP target +The Node (file) being built. +In the normal case, +this is what should get rebuilt +if the +.I dependency +has "changed." + +.IP prev_ni +Stored information about the state of the +.I dependency +the last time the +.I target +was built. +This can be consulted to match various +file characteristics +such as the timestamp, +size, or content signature. + +The +.I function +should return a +.B True +(non-zero) +value if the +.I dependency +has "changed" since the last time +the +.I target +was built +(indicating that the target +.I should +be rebuilt), +and +.B False +(zero) +otherwise +(indicating that the target should +.I not +be rebuilt). +Note that the decision can be made +using whatever criteria are appopriate. +Ignoring some or all of the function arguments +is perfectly normal. + +Example: + +.ES +def my_decider(dependency, target, prev_ni): + return not os.path.exists(str(target)) + +env.Decider(my_decider) +.EE + +'\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.TP .RI Default( targets ) .TP .RI env.Default( targets ) @@ -2815,6 +2991,7 @@ method, or as a list. will also accept the Node returned by any of a construction environment's builder methods. + Examples: .ES @@ -2863,6 +3040,8 @@ for cases where the dependency is not caught by a Scanner for the file. +Example: + .ES env.Depends('foo', 'other-input-file-for-foo') .EE @@ -2877,6 +3056,8 @@ If there are any variable names specified, only the specified construction variables are returned in the dictionary. +Example: + .ES dict = env.Dictionary() cc_dict = env.Dictionary('CC', 'CCFLAGS', 'CCCOM') @@ -2952,6 +3133,8 @@ This function will print out an error message and exit SCons with a non-zero exit code if the actual Python version is not late enough. +Example: + .ES EnsurePythonVersion(2,2) .EE @@ -2972,6 +3155,8 @@ This function will print out an error message and exit SCons with a non-zero exit code if the actual SCons version is not late enough. +Examples: + .ES EnsureSConsVersion(0,14) @@ -3042,6 +3227,7 @@ Multiple variable names can be passed to as separate arguments or as a list. A dictionary can be used to map variables to a different name when exported. Both local variables and global variables can be exported. + Examples: .ES @@ -3106,12 +3292,78 @@ may be a list of file names or a single file name. In addition to searching for files that exist in the filesytem, this function also searches for derived files that have not yet been built. +Example: + .ES foo = env.FindFile('foo', ['dir1', 'dir2']) .EE '\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .TP +.RI FindInstalledFiles( ) +.TP +.RI env.FindInstalledFiles( ) +Returns the list of targets setup by the +.B Install() +or +.B InstallAs() +builders. + +This function serves as a convenient method to select the contents of +a Binary Package. + +Example: + +.ES +Install( '/bin', [ 'executable_a', 'executable_b' ] ) + +# will return the file node list +# [ '/bin/executable_a', '/bin/executable_b' ] +FindInstalledFiles() + +Install( '/lib', [ 'some_library' ] ) + +# will return the file node list +# [ '/bin/executable_a', '/bin/executable_b', '/lib/some_library' ] +FindInstalledFiles() +.EE + +'\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.TP +.RI FindSourceFiles( node = '"."' ) +.TP +.RI env.FindSourceFiles( node = '"."' ) + +Returns the list of nodes which serve as the source of the built files. +It does so by inspecting the dependency tree starting at the optional +argument +.B node +which defaults to the '"."'-node. It will then return all leafs of +.B node. +These are all children which have no further children. + +This function is a convenient method to select the contents of a Source +Package. + +Example: + +.ES +Program( 'src/main_a.c' ) +Program( 'src/main_b.c' ) +Program( 'main_c.c' ) + +# returns ['main_c.c', 'src/main_a.c', 'SConstruct', 'src/main_b.c'] +FindSourceFiles() + +# returns ['src/main_b.c', 'src/main_a.c' ] +FindSourceFiles( 'src' ) +.EE + +As you can see build support files (SConstruct in the above example) +will also be returned by this function. + +'\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.TP .RI FindPathDirs( variable ) Returns a function (actually a callable Python object) @@ -3178,7 +3430,9 @@ the lists returned by calls to Builders; other Builders will automatically flatten lists specified as input, but direct Python manipulation of -these lists does not: +these lists does not. + +Examples: .ES foo = Object('foo.c') @@ -3288,6 +3542,8 @@ The specified dependency file(s) will be ignored when deciding if the target file(s) need to be rebuilt. +Examples: + .ES env.Ignore('foo', 'foo.c') env.Ignore('bar', ['bar1.h', 'bar2.h']) @@ -3314,6 +3570,7 @@ Multiple variable names can be passed to .BR Import () as separate arguments or as a list. The variable "*" can be used to import all variables. + Examples: .ES @@ -3644,7 +3901,9 @@ from the Perforce source code management system. The returned Builder is intended to be passed to the .B SourceCode -function: +function. + +Example: .ES env.SourceCode('.', env.Perforce()) @@ -3673,7 +3932,9 @@ USERNAME. Returns a callable object that can be used to initialize a construction environment using the -platform keyword of the Environment() method: +platform keyword of the Environment() method. + +Example: .ES env = Environment(platform = Platform('win32')) @@ -3707,6 +3968,124 @@ will work on Windows systems. '\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .TP +.RI Progress( callable ", [" interval ]) +.TP +.RI Progress( string ", [" interval ", " file ", " overwrite ]) +.TP +.RI Progress( list_of_strings ", [" interval ", " file ", " overwrite ]) +Allows SCons to show progress made during the build +by displaying a string or calling a function while +evaluating Nodes (e.g. files). + +If the first specified argument is a Python callable +(a function or an object that has a +.BR __call__ () +method), +the function will be called +once every +.I interval +times a Node is evaluated. +The callable will be passed the evaluated Node +as its only argument. +(For future compatibility, +it's a good idea to also add +.B *args +and +.B **kw +as arguments to your function or method. +This will prevent the code from breaking +if SCons ever changes the interface +to call the function with additional arguments in the future.) + +An example of a simple custom progress function +that prints a string containing the Node name +every 10 Nodes: + +.ES +def my_progress_function(node, *args, **kw): + print 'Evaluating node %s!' % node +Progress(my_progress_function, interval=10) +.EE +.IP +A more complicated example of a custom progress display object +that prints a string containing a count +every 100 evaluated Nodes. +Note the use of +.B \\\\r +(a carriage return) +at the end so that the string +will overwrite itself on a display: + +.ES +import sys +class ProgressCounter: + count = 0 + def __call__(self, node, *args, **kw): + self.count += 100 + sys.stderr.write('Evaluated %s nodes\\r' % self.count) +Progress(ProgressCounter(), interval=100) +.EE +.IP +If the first argument +.BR Progress () +is a string, +the string will be displayed +every +.I interval +evaluated Nodes. +The default is to print the string on standard output; +an alternate output stream +may be specified with the +.B file= +argument. +The following will print a series of dots +on the error output, +one dot for every 100 evaluated Nodes: + +.ES +import sys +Progress('.', interval=100, file=sys.stderr) +.EE +.IP +If the string contains the verbatim substring +.B $TARGET, +it will be replaced with the Node. +Note that, for performance reasons, this is +.I not +a regular SCons variable substition, +so you can not use other variables +or use curly braces. +The following example will print the name of +every evaluated Node, +using a +.B \\\\r +(carriage return) to cause each line to overwritten by the next line, +and the +.B overwrite= +keyword argument to make sure the previously-printed +file name is overwritten with blank spaces: + +.ES +import sys +Progress('$TARGET\\r', overwrite=True) +.EE +.IP +If the first argument to +.BR Progress () +is a list of strings, +then each string in the list will be displayed +in rotating fashion every +.I interval +evaluated Nodes. +This can be used to implement a "spinner" +on the user's screen as follows: + +.ES +Progress(['-\\r', '\\\\\\r', '|\\r', '/\\r'], interval=5) +.EE + +'\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.TP .RI Precious( target ", ...)" .TP .RI env.Precious( target ", ...)" @@ -3735,6 +4114,8 @@ are both coerced to lists, and the lists are added together. (See also the Append method, above.) +Example: + .ES env.Prepend(CCFLAGS = '-g ', FOO = ['foo.yyy']) .EE @@ -3757,6 +4138,7 @@ and This can also handle the case where the given old path variable is a list instead of a string, in which case a list will be returned instead of a string. + Example: .ES @@ -3764,8 +4146,11 @@ print 'before:',env['ENV']['INCLUDE'] include_path = '/foo/bar:/foo' env.PrependENVPath('INCLUDE', include_path) print 'after:',env['ENV']['INCLUDE'] +.EE -yields: +The above exmaple will print: + +.ES before: /biz:/foo after: /foo/bar:/foo:/biz .EE @@ -3784,6 +4169,8 @@ construction variable will .I not be added again to the list. +Example: + .ES env.PrependUnique(CCFLAGS = '-g', FOO = ['foo.yyy']) .EE @@ -3800,6 +4187,8 @@ is intended to be passed to the .B SourceCode function: +Examples: + .ES env.SourceCode('.', env.RCS()) .EE @@ -3824,6 +4213,8 @@ for a specific subdirectory. Replaces construction variables in the Environment with the specified keyword arguments. +Example: + .ES env.Replace(CCFLAGS = '-g', FOO = 'foo.xxx') .EE @@ -3876,20 +4267,46 @@ method. '\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .TP -.RI Return( vars ) -This tells -.B scons -what variable(s) to use as the return value(s) of the current SConscript -file. These variables will be returned to the "calling" SConscript file -as the return value(s) of -.BR SConscript (). -Multiple variable names should be passed to +.RI Return([ vars "... , " stop= ]) +By default, +this stops processing the current SConscript +file and returns to the calling SConscript file +the values of the variables named in the +.I vars +string arguments. +Multiple strings contaning variable names may be passed to +.BR Return (). +Any strings that contain white space + +The optional +.B stop= +keyword argument may be set to a false value +to continue processing the rest of the SConscript +file after the .BR Return () -as a list. Example: +call. +This was the default behavior prior to SCons 0.98. +However, the values returned +are still the values of the variables in the named +.I vars +at the point +.BR Return () +is called. + +Examples: .ES +# Returns without returning a value. +Return() + +# Returns the value of the 'foo' Python variable. Return("foo") -Return(["foo", "bar"]) + +# Returns the values of the Python variables 'foo' and 'bar'. +Return("foo", "bar") + +# Returns the values of Python variables 'val1' and 'val2'. +Return('val1 val2') .EE '\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" @@ -3913,7 +4330,9 @@ from SCCS. The returned Builder is intended to be passed to the .B SourceCode -function: +function. + +Example: .ES env.SourceCode('.', env.SCCS()) @@ -4090,11 +4509,12 @@ while reading all SConscript files. (This may be necessary when building from repositories, when all the directories in which SConscript files may be found don't necessarily exist locally.) - You may enable and disable this ability by calling SConscriptChdir() -multiple times: +multiple times. + +Example: .ES env = Environment() @@ -4212,7 +4632,9 @@ which corresponds to -j and --jobs. which corresponds to --random. See the documentation for the corresponding command line object for information about each specific -option. Example: +option. + +Example: .ES SetOption('max_drift', 1) @@ -4393,6 +4815,8 @@ you can use the Python idiom to pass in an unnamed function that simply returns its unconverted argument. +Example: + .ES print env.subst("The C compiler is: $CC") @@ -4428,7 +4852,9 @@ source_nodes = env.subst('$EXPAND_TO_NODELIST', '\"so that you only have to '\"replicate part of the repository '\"directory hierarchy in your -'\"local build directory: +'\"local build directory. +'\" +'\"Example: '\" '\".ES '\"# Will fetch foo/bar/src.c @@ -4449,10 +4875,17 @@ source_nodes = env.subst('$EXPAND_TO_NODELIST', .RI SourceSignatures( type ) .TP .RI env.SourceSignatures( type ) -This function tells SCons what type of signature to use for source files: +This function tells +.B scons +how to decide if a source file +(a file that is not built from any other files) +has changed since the last time it +was used to build a particular target file. +Legal values are .B "MD5" or .BR "timestamp" . + If the environment method is used, the specified type of source signature is only used when deciding whether targets @@ -4462,17 +4895,48 @@ the specified type of source signature becomes the default used for all decisions about whether targets are up-to-date. -"MD5" means the signature of a source file -is the MD5 checksum of its contents. -"timestamp" means the signature of a source file -is its timestamp (modification time). +.B "MD5" +means +.B scons +decides that a source file has changed +if the MD5 checksum of its contents has changed since +the last time it was used to rebuild a particular target file. + +.B "timestamp" +means +.B scons +decides that a source file has changed +if its timestamp (modification time) is newer than +the last time it was used to rebuild a particular target file. + There is no different between the two behaviors for Python .BR Value () node objects. -"MD5" signatures take longer to compute, -but are more accurate than "timestamp" signatures. -The default is "MD5". + +.B "MD5" +signatures take longer to compute, +but are more accurate than +.B "timestamp" +signatures. +The default value is +.BR "MD5" . + +Note that the default +.BR TargetSignatures () +setting (see below) +is to use this +.BR SourceSignatures () +setting for any target files that are used +to build other target files. +Consequently, changing the value of +.BR SourceSignatures () +will, by default, +affect the up-to-date decision for all files in the build +(or all files built with a specific construction environment +when +.BR env.SourceSignatures () +is used). '\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .TP @@ -4490,6 +4954,8 @@ If arg is any other type of object, it will be returned as a list containing just the object. +Example: + .ES files = Split("f1.c f2.c f3.c") files = env.Split("f4.c f5.c f6.c") @@ -4509,6 +4975,8 @@ information about how the Builder should package those files or directories. All tags are optional. +Examples: + .ES # makes sure the built library will be installed with 0644 file # access mode @@ -4525,13 +4993,25 @@ Tag( 'file2.txt', DOC ) .RI TargetSignatures( type ) .TP .RI env.TargetSignatures( type ) -This function tells SCons what type of signatures to use -for target files: -.B "build" +This function tells +.B scons +how to decide if a target file +(a file that +.I is +built from any other files) +has changed since the last time it +was used to build some other target file. +Legal values are +.BR "build" ; +.BR "content" +(or its synonym +.BR "MD5" ); +.BR "timestamp" ; or -.BR "content" . +.BR "source" . + If the environment method is used, -the specified type of signature is only used +the specified type of target signature is only used for targets built with that environment. If the global function is used, the specified type of signature becomes the default @@ -4539,16 +5019,94 @@ used for all target files that don't have an explicit target signature type specified for their environments. -"build" means the signature of a target file -is made by concatenating all of the -signatures of all its source files. -"content" means the signature of a target -file is an MD5 checksum of its contents. -"build" signatures are usually faster to compute, -but "content" signatures can prevent unnecessary rebuilds +.B "content" +(or its synonym +.BR "MD5" ) +means +.B scons +decides that a target file has changed +if the MD5 checksum of its contents has changed since +the last time it was used to rebuild some other target file. +This means +.B scons +will open up +MD5 sum the contents +of target files after they're built, +and may decide that it does not need to rebuild +"downstream" target files if a file was +rebuilt with exactly the same contents as the last time. + +.B "timestamp" +means +.B scons +decides that a target file has changed +if its timestamp (modification time) is newer than +the last time it was used to rebuild some other target file. + +.B "source" +means +.B scons +decides that a target file has changed +as specified by the corresponding +.BR SourceSignatures () +setting +.BR "" ( "MD5" +or +.BR "timestamp" ). +This means that +.B scons +will treat all input files to a target the same way, +regardless of whether they are source files +or have been built from other files. + +.B "build" +means +.B scons +decides that a target file has changed +if it has been rebuilt in this invocation +or if its content or timestamp have changed +as specified by the corresponding +.BR SourceSignatures () +setting. +This "propagates" the status of a rebuilt file +so that other "downstream" target files +will always be rebuilt, +even if the contents or the timestamp +have not changed. + +.B "build" +signatures are fastest because +.B "content" +(or +.BR "MD5" ) +signatures take longer to compute, +but are more accurate than +.B "timestamp" +signatures, +and can prevent unnecessary "downstream" rebuilds when a target file is rebuilt to the exact same contents as the previous build. -The default is "build". +The +.B "source" +setting provides the most consistent behavior +when other target files may be rebuilt from +both source and target input files. +The default value is +.BR "source" . + +Because the default setting is +.BR "source" , +using +.BR SourceSignatures () +is generally preferable to +.BR TargetSignatures () , +so that the up-to-date decision +will be consistent for all files +(or all files built with a specific construction environment). +Use of +.BR TargetSignatures () +provides specific control for how built target files +affect their "downstream" dependencies. '\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .TP @@ -4570,6 +5128,8 @@ Additional keyword arguments are passed to the tool's .B generate() method. +Examples: + .ES env = Environment(tools = [ Tool('msvc') ]) @@ -4605,7 +5165,10 @@ calling .BR str( value ) changes between SCons runs, any targets depending on .BR Value( value ) -will be rebuilt. When using timestamp source signatures, Value Nodes' +will be rebuilt. +(This is true even when using timestamps to decide if +files are up-to-date.) +When using timestamp source signatures, Value Nodes' timestamps are equal to the system time when the Node is created. The returned Value Node object has a @@ -4622,22 +5185,38 @@ There is a corresponding .BR read () method that will return the built value of the Node. +Examples: + .ES +env = Environment() + def create(target, source, env): + # A function that will write a 'prefix=$SOURCE' + # string into the file name specified as the + # $TARGET. f = open(str(target[0]), 'wb') f.write('prefix=' + source[0].get_contents()) +# Fetch the prefix= argument, if any, from the command +# line, and use /usr/local as the default. prefix = ARGUMENTS.get('prefix', '/usr/local') -env = Environment() + +# Attach a .Config() builder for the above function action +# to the construction environment. env['BUILDERS']['Config'] = Builder(action = create) env.Config(target = 'package-config', source = Value(prefix)) def build_value(target, source, env): + # A function that "builds" a Python Value by updating + # the the Python value with the contents of the file + # specified as the source of the Builder call ($SOURCE). target[0].write(source[0].get_contents()) output = env.Value('before') input = env.Value('after') +# Attach a .UpdateValue() builder for the above function +# action to the construction environment. env['BUILDERS']['UpdateValue'] = Builder(action = build_value) env.UpdateValue(target = Value(output), source = Value(input)) .EE @@ -4711,6 +5290,8 @@ and .B [1] of the tuple, respectively. +Example: + .ES print "first keyword, value =", ARGLIST[0][0], ARGLIST[0][1] print "second keyword, value =", ARGLIST[1][0], ARGLIST[1][1] @@ -4735,6 +5316,8 @@ the one in the .B ARGUMENTS dictionary. +Example: + .ES if ARGUMENTS.get('debug', 0): env = Environment(CCFLAGS = '-g') @@ -4771,6 +5354,8 @@ See the list, below, for additional information. +Example: + .ES if 'foo' in BUILD_TARGETS: print "Don't forget to test the `foo' program!" @@ -4800,7 +5385,9 @@ the list is empty. This can be used, for example, to take specific actions only when a certain target or targets -is explicitly being built: +is explicitly being built. + +Example: .ES if 'foo' in COMMAND_LINE_TARGETS: @@ -4822,6 +5409,8 @@ so you need to run them through the Python .B str function to get at the path name for each Node. +Example: + .ES print str(DEFAULT_TARGETS[0]) if 'foo' in map(str, DEFAULT_TARGETS): @@ -6007,6 +6596,33 @@ b = Builder("build_it < $SOURCE > $TARGET", "$SRC_SFX_A": gen_suffix }) .EE +.IP ensure_suffix +When set to any true value, causes +.B scons +to add the target suffix specified by the +.I suffix +keyword to any target strings +that have a different suffix. +(The default behavior is to leave untouched +any target file name that looks like it already has any suffix.) + +.ES +b1 = Builder("build_it < $SOURCE > $TARGET" + suffix = ".out") +b2 = Builder("build_it < $SOURCE > $TARGET" + suffix = ".out", + ensure_suffix) +env = Environment() +env['BUILDERS']['B1'] = b1 +env['BUILDERS']['B2'] = b2 + +# Builds "foo.txt" because ensure_suffix is not set. +env.B1('foo.txt', 'foo.in') + +# Builds "bar.txt.out" because ensure_suffix is set. +env.B2('bar.txt', 'bar.in') +.EE + .IP src_suffix The expected source file name suffix. This may be a string or a list of strings. diff --git a/doc/man/sconsign.1 b/doc/man/sconsign.1 index 3d01cf4..7c80327 100644 --- a/doc/man/sconsign.1 +++ b/doc/man/sconsign.1 @@ -56,14 +56,19 @@ dumps the entire contents of the specified file(s). Each entry is printed in the following format: - file: timestamp bsig csig - implicit_dependency_1 - implicit_dependency_2 + file: signature timestamp length + implicit_dependency_1: signature timestamp length + implicit_dependency_2: signature timestamp length + action_signature [action string] -If the entry has no timestamp, bsig, or csig, a dash .B None -is printed. +is printed +in place of any missing timestamp, bsig, or csig +values for +any entry +or any of its dependencies. If the entry has no implicit dependencies, +or no build action, the lines are simply omitted. By default, @@ -100,8 +105,8 @@ Various options control what information is printed and the format: .TP --b, --bsig -Prints the build signature (bsig) information +-a, --act, --action +Prints the build action information for all entries or the specified entries. .TP @@ -165,7 +170,9 @@ for all entries or the the specified entries. --raw Prints a pretty-printed representation of the raw Python dictionary that holds -build information about an entry. +build information about individual entry +(both the entry itself or its implicit dependencies). +An entry's build action is still printed in its usual format. .TP -r, --readable diff --git a/runtest.py b/runtest.py index f99f5a1..a3cf016 100644 --- a/runtest.py +++ b/runtest.py @@ -302,6 +302,7 @@ _ws = re.compile('\s') def escape(s): if _ws.search(s): s = '"' + s + '"' + s = string.replace(s, '\\', '\\\\') return s # Set up lowest-common-denominator spawning of a process on both Windows diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 3699e95..8886204 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -21,6 +21,82 @@ RELEASE 0.XX - XXX - Allow env.CacheDir() to be set per construction environment. The global CacheDir() function now sets an overridable global default. + - Add an env.Decider() method and a Node.Decider() method that allow + flexible specification of an arbitrary function to decide if a given + dependency has changed since the last time a target was built. + + - Don't execute Configure actions (while reading SConscript files) + when cleaning (-c) or getting help (-h or -H). + + - Add to each target an implicit dependency on the external command(s) + used to build the target, as found by searching env['ENV']['PATH'] + for the first argument on each executed command line. + + - Add support for a $IMPLICIT_COMMAND_DEPENDENCIES construction + variabe that can be used to disable the automatic implicit + dependency on executed commands. + + - Add an "ensure_suffix" keyword to Builder() definitions that, when + true, will add the configured suffix to the targets even if it looks + like they already have a different suffix. + + - Add a Progress() function that allows for calling a function or string + (or list of strings) to display progress while walking the DAG. + + - Allow ParseConfig(), MergeFlags() and ParseFlags() to handle output + from a *config command with quoted path names that contain spaces. + + - Make the Return() function stop processing the SConscript file and + return immediately. Add a "stop=" keyword argument that can be set + to False to preserve the old behavior. + + - Fix use of exitstatfunc on an Action. + + - Introduce all man page function examples with "Example:" or "Examples:". + + - When a file gets added to a directory, make sure the directory gets + re-scanned for the new implicit dependency. + + - Fix handling a file that's specified multiple times in a target + list so that it doesn't cause dependent Nodes to "disappear" from + the dependency graph walk. + + From Carsten Koch: + + - Avoid race conditions with same-named files and directory creation + when pushing copies of files to CacheDir(). + + From Tzvetan Mikov: + + - Handle $ in Java class names. + + From Gary Oberbrunner: + + - Add support for the Intel C compiler on Windows64. + + - On SGI IRIX, have $SHCXX use $CXX by default (like other platforms). + + From Sohail Somani: + + - When Cloning a construction environment, set any variables before + applying tools (so the tool module can access the configured settings) + and re-set them after (so they end up matching what the user set). + + From Matthias Troffaes: + + - Make sure extra auxiliary files generated by some LaTeX packages + and not ending in .aux also get deleted by scons -c. + + From Greg Ward: + + - Add a $JAVABOOTCLASSPATH variable for directories to be passed to the + javac -bootclasspath option. + + From Christoph Wiedemann: + + - Add implicit dependencies on the commands used to build a target. + + RELEASE 0.97.0d20070809 - Fri, 10 Aug 2007 10:51:27 -0500 diff --git a/src/RELEASE.txt b/src/RELEASE.txt index 195697e..23c5638 100644 --- a/src/RELEASE.txt +++ b/src/RELEASE.txt @@ -20,11 +20,93 @@ more effectively, please sign up for the scons-users mailing list at: -RELEASE 0.97.0d20070809 - Fri, 10 Aug 2007 10:51:27 -0500 +RELEASE 0.97.0d200709XX - XXX This is the eighth beta release of SCons. Please consult the CHANGES.txt file for a list of specific changes since last release. + Please note the following important changes since release 0.97.0d20070809: + + -- "content" SIGNATURES ARE NOW THE DEFAULT BEHAVIOR + + The default behavior of SCons is now to use the MD5 checksum of + all file contents to decide if any files have changed and should + cause rebuilds of their source files. This means that SCons may + decide not to rebuild "downstream" targets if a a given input + file is rebuilt to the exact same contents as the last time. + The old behavior may preserved by explicity specifying: + + TargetSignatures("build") + + In any of your SConscript files. + + -- TARGETS NOW IMPLICITLY DEPEND ON THE COMMAND THAT BUILDS THEM + + For all targets built by calling external commands (such as a + compiler or other utility), SCons now adds an implicit dependency + on the command(s) used to build the target. + + This will cause rebuilds of all targets built by external commands + when running SCons in a tree built by previous version of SCons, + in order to update the recorded signatures. + + The old behavior of not having targets depend on the external + commands that build them can be preserved by setting a new + $IMPLICIT_COMMAND_DEPENDENCIES construction variable to a + non-True value: + + env = Environment(IMPLICIT_COMMAND_DEPENDENCIES = 0) + + or by adding Ignore() calls for any targets where the behavior + is desired: + + Ignore('/usr/bin/gcc', 'foo.o') + + Both of these settings are compatible with older versions + of SCons. + + -- CHANGING SourceSignature() MAY CAUSE "UNECESSARY" REBUILDS + + If you change the SourceSignature() value from 'timestamp' to + 'MD5', SCons will now rebuild targets that were already up-to-date + with respect to their source files. + + This will happen because SCons did not record the content + signatures of the input source files when the target was last + built--it only recorded the timestamps--and it must record them + to make sure the signature information is correct. However, + the content of source files may have changed since the last + timestamp build was performed, and SCons would not have any way to + verify that. (It would have had to open up the file and record + a content signature, which is one of the things you're trying to + avoid by specifying use of timestamps....) So in order to make + sure the built targets reflect the contents of the source files, + the targets must be rebuilt. + + Change the SourceSignature() value from 'MD5' to 'timestamp' + should correctly not rebuild target files, because the timestamp + of the files is always recorded. + + In previous versions of SCons, changing the SourceSignature() + value would lead to unpredictable behavior, usually including + rebuilding targets. + + -- THE Return() FUNCTION NOW ACTUALLY RETURNS IMMEDIATELY + + The Return() function now immediately stops processing the + SConscript file in which it appears and returns the values of the + variables named in its arguments. It used to continue processing + the rest of the SConscript file, and then return the values of the + specified variables at the point the Return() function was called. + + The old behavior may be requested by adding a "stop=False" + keyword argument to the Return() call: + + Return('value', stop=False) + + The "stop=" keyword argument is *not* compatible with SCons + versions 0.97.0d20070809 or earlier. + Please note the following important changes since release 0.97: -- env.CacheDir() NOW ONLY AFFECTS CONSTRUCTION ENVIRONMENT TARGETS @@ -112,7 +194,7 @@ RELEASE 0.97.0d20070809 - Fri, 10 Aug 2007 10:51:27 -0500 This should not cause any problems in the normal use of "#ifdef HAVE_{FEATURE}" statements interpreted by a C preprocessor, but might cause a compatibility issue if a script or other utility - was looking for an exact match of the previous text. + looks for an exact match of the previous text. Please note the following important changes since release 0.96.93: diff --git a/src/eng