summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--HOWTO/new-script.txt73
-rw-r--r--SConstruct14
-rw-r--r--debian/rules6
-rw-r--r--doc/SConscript40
-rw-r--r--doc/man/sconsign.1131
-rw-r--r--gentoo/scons.ebuild.in1
-rw-r--r--rpm/scons.spec.in2
-rw-r--r--src/CHANGES.txt13
-rw-r--r--src/engine/SCons/SConfTests.py8
-rw-r--r--src/engine/SCons/Sig/SigTests.py36
-rw-r--r--src/engine/SCons/Sig/__init__.py41
-rw-r--r--src/engine/SCons/Tool/g++.py11
-rw-r--r--src/engine/SCons/Tool/gcc.py4
-rw-r--r--src/engine/SCons/Tool/gnulink.py32
-rw-r--r--src/script/MANIFEST.in1
-rw-r--r--src/script/scons.py17
-rw-r--r--src/script/sconsign.py223
-rw-r--r--src/setup.py2
-rw-r--r--test/LINK.py2
-rw-r--r--test/LINKFLAGS.py2
-rw-r--r--test/sconsign-script.py170
21 files changed, 772 insertions, 57 deletions
diff --git a/HOWTO/new-script.txt b/HOWTO/new-script.txt
new file mode 100644
index 0000000..8bb5222
--- /dev/null
+++ b/HOWTO/new-script.txt
@@ -0,0 +1,73 @@
+Steps for adding a new script/utility to the SCons packages. Assume
+that you're creating a new man page, too. In the template steps
+below, "newscript" is the name of the new script/utility being added.
+
+ New files:
+
+ doc/man/newscript.1
+
+ New man page; use an existing one as a template.
+
+ src/script/newscript.py
+
+ The new script itself.
+
+ test/*.py
+
+ Appropriate tests for the new script.
+
+ Modified files:
+
+ SConstruct
+
+ In the "scons_script" package description:
+
+ Add "newscript" : "newscript.py" to the "filemap"
+ dictionary.
+
+ In the "scons" package description:
+
+ Add "newscript.1" to the "files" list.
+
+ Add "newscript.1" : "../doc/man/newscript.1" to the
+ "filemap" dictionary.
+
+ Add "newscript" to the scripts[] list
+
+ debian/rules
+
+ Add:
+
+ rm -f debian/scons/usr/bin/newscript
+ cp build/scripts/newscript debian/scons/user/bin/newscript
+ sed '1s|.*|#!/usr/bin/python2.1|' build/scripts/newscript > debian/scons/user/bin/newscript
+ chmod +x debian/scons/user/bin/newscript
+
+ rm -f debian/scons/usr/share/man/man1/newscript.1
+ cp newscript.1 debian/scons/user/share/man/man1/
+
+ doc/SConscript
+
+ Add "newscript" to man_page_list[]
+
+ gentoo/scons.ebuild.in
+
+ Add "doman newscript.1"
+
+ rpm/scons.spec.in
+
+ Add "gzip -c newscript.1" > $RPM_BUILD_ROOT/usr/man/man1/newscript.1.gz
+
+ Add "%doc /usr/man/man1/newscript.1.gz"
+
+ src/CHANGES.txt
+
+ Document the addition of the new script.
+
+ src/script/MANIFEST.in
+
+ Add a line: "newscript"
+
+ src/setup.py
+
+ Add "script/newscript" to the 'scripts' list.
diff --git a/SConstruct b/SConstruct
index 59d8963..0c05859 100644
--- a/SConstruct
+++ b/SConstruct
@@ -395,6 +395,7 @@ scons_script = {
'filemap' : {
'LICENSE.txt' : '../LICENSE.txt',
'scons' : 'scons.py',
+ 'sconsign' : 'sconsign.py',
}
}
@@ -419,6 +420,7 @@ scons = {
'RELEASE.txt',
'os_spawnv_fix.diff',
'scons.1',
+ 'sconsign.1',
'script/scons.bat',
'setup.cfg',
'setup.py',
@@ -426,6 +428,7 @@ scons = {
'filemap' : {
'scons.1' : '../doc/man/scons.1',
+ 'sconsign.1' : '../doc/man/sconsign.1',
},
'subpkgs' : [ python_scons, scons_script ],
@@ -436,6 +439,8 @@ scons = {
},
}
+scripts = ['scons', 'sconsign']
+
src_deps = []
src_files = []
@@ -806,12 +811,15 @@ for p in [ scons ]:
"rm -rf %s" % local,
"$PYTHON $SETUP_PY install --install-script=%s --install-lib=%s --no-compile" % \
(cwd_local, cwd_local_slv),
- "mv %s/scons %s/scons.py" % (local, local),
]
- rf = filter(lambda x: x != "scons", raw_files)
+ for script in scripts:
+ commands.append("mv %s/%s %s/%s.py" % (local, script, local, script))
+
+ rf = filter(lambda x: not x in scripts, raw_files)
rf = map(lambda x, slv=s_l_v: os.path.join(slv, x), rf)
- rf.append("scons.py")
+ for script in scripts:
+ rf.append("%s.py" % script)
local_targets = map(lambda x, s=local: os.path.join(s, x), rf)
env.Command(local_targets, build_src_files, commands)
diff --git a/debian/rules b/debian/rules
index 200536f..e9e6421 100644
--- a/debian/rules
+++ b/debian/rules
@@ -57,16 +57,22 @@ install: build
mkdir -p debian/scons/usr/bin/
rm -f debian/scons/usr/bin/scons
+ rm -f debian/scons/usr/bin/sconsign
ifeq ($(PYTHON),python)
cp build/scripts/scons debian/scons/usr/bin/scons
+ cp build/scripts/sconsign debian/scons/usr/bin/sconsign
else
sed '1s|.*|#!/usr/bin/python2.1|' build/scripts/scons > debian/scons/usr/bin/scons
+ sed '1s|.*|#!/usr/bin/python2.1|' build/scripts/sconsign > debian/scons/usr/bin/sconsign
endif
chmod +x debian/scons/usr/bin/scons
+ chmod +x debian/scons/usr/bin/sconsign
mkdir -p debian/scons/usr/share/man/man1/
rm -f debian/scons/usr/share/man/man1/scons.1
+ rm -f debian/scons/usr/share/man/man1/sconsign.1
cp scons.1 debian/scons/usr/share/man/man1/
+ cp sconsign.1 debian/scons/usr/share/man/man1/
mkdir -p debian/scons/usr/share/doc/scons
rm -f debian/scons/usr/share/doc/scons/changelog
diff --git a/doc/SConscript b/doc/SConscript
index d5fe171..25ad6bf 100644
--- a/doc/SConscript
+++ b/doc/SConscript
@@ -254,6 +254,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT.
if docs[doc].get('text') and jade and lynx:
env.Command(text, html, "lynx -dump ${SOURCE.abspath} > $TARGET")
+ Local(text)
env.Ignore(text, "version.sgml")
@@ -263,29 +264,35 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT.
#
# Man page(s), in good ol' troff format.
#
-scons_1 = os.path.join('man', 'scons.1')
+man_page_list = ['scons', 'sconsign']
-if groff:
- ps = os.path.join('PS', 'scons-man.ps')
- text = os.path.join('TEXT', 'scons-man.txt')
+for man in man_page_list:
+ man_1 = os.path.join('man', '%s.1' % man)
- env.Command(ps, scons_1, "groff -man -Tps $SOURCES > $TARGET")
+ if groff:
+ ps = os.path.join('PS', '%s-man.ps' % man)
+ text = os.path.join('TEXT', '%s-man.txt' % man)
- env.Command(text, scons_1, "groff -man -Tascii $SOURCES > $TARGET")
+ env.Command(ps, man_1, "groff -man -Tps $SOURCES > $TARGET")
+ Local(ps)
- tar_deps.extend([ps, text])
- tar_list = string.join([tar_list, ps, text], " ")
+ env.Command(text, man_1, "groff -man -Tascii $SOURCES > $TARGET")
+ Local(text)
-if man2html:
- html = os.path.join('HTML' , 'scons-man.html')
+ tar_deps.extend([ps, text])
+ tar_list = string.join([tar_list, ps, text], " ")
- cmds = [ "man2html $SOURCES > $TARGET" ]
- if tidy:
- cmds.append("tidy -m -q $TARGET || true")
- env.Command(html, scons_1, cmds)
+ if man2html:
+ html = os.path.join('HTML' , '%s-man.html' % man)
- tar_deps.append(html)
- tar_list = tar_list + " " + html
+ cmds = [ "man2html $SOURCES > $TARGET" ]
+ if tidy:
+ cmds.append("tidy -m -q $TARGET || true")
+ env.Command(html, man_1, cmds)
+ Local(html)
+
+ tar_deps.append(html)
+ tar_list = tar_list + " " + html
#
# Now actually create the tar file of the documentation,
@@ -294,3 +301,4 @@ if man2html:
if tar_deps:
env.Command(doc_tar_gz, tar_deps,
"tar cf${TAR_HFLAG} - -C build/doc %s | gzip > $TARGET" % tar_list)
+ Local(doc_tar_gz)
diff --git a/doc/man/sconsign.1 b/doc/man/sconsign.1
new file mode 100644
index 0000000..cb0e38e
--- /dev/null
+++ b/doc/man/sconsign.1
@@ -0,0 +1,131 @@
+.\" Copyright (c) 2001, 2002, 2003 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.
+.\"
+.\" doc/man/scons.1 0.90.D006 2003/07/02 09:02:19 knight
+.\"
+.\" ES - Example Start - indents and turns off line fill
+.de ES
+.RS
+.nf
+..
+.\" EE - Example End - ends indent and turns line fill back on
+.de EE
+.RE
+.fi
+..
+.TH SCONSIGN 1 "July 2003"
+.SH NAME
+sconsign \- print SCons .sconsign file information
+.SH SYNOPSIS
+.B sconsign
+[
+.IR options ...
+]
+.IR file
+[ ... ]
+.SH DESCRIPTION
+
+The
+.B sconsign
+command
+displays the contents of one or more
+.B .sconsign
+files specified by the user.
+
+By default,
+.B sconsign
+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
+
+If the entry has no timestamp, bsig, or csig, a dash
+(\fR\-\fP) is printed instead.
+If the entry has no implicit dependencies,
+the lines are simply omitted.
+
+.SH OPTIONS
+
+Various options control what information is printed
+and the format:
+
+.TP
+-b
+Ignored for compatibility with non-GNU versions of
+.BR make.
+
+.TP
+-b, --bsig
+Prints the build signature (bsig) information
+for all entries or the specified entries.
+
+.TP
+-c, --csig
+Prints the content signature (csig) information
+for all entries or the specified entries.
+
+.TP
+-e entry, --entry=entry
+Prints information about only the specified entry.
+Multiple -e options may be used,
+in which case information about each
+entry is printed in the order in which the
+options are specified on the command line.
+
+.TP
+-h, --help
+Prints a help message and exits.
+
+.TP
+-i, --implicit
+Prints the list of cached implicit dependencies
+for all entries or the the specified entries.
+
+.TP
+-t, --timestamp
+Prints the timestamp information
+for all entries or the specified entries.
+
+.TP
+-v, --verbose
+Prints labels identifying each field being printed.
+
+.SH ENVIRONMENT
+
+.IP SCONS_LIB_DIR
+Specifies the directory that contains the SCons Python module directory
+(e.g. /home/aroach/scons-src-0.01/src/engine).
+on the command line.
+
+.SH "SEE ALSO"
+.BR scons ,
+.B scons
+User Manual,
+.B scons
+Design Document,
+.B scons
+source code.
+
+.SH AUTHORS
+Steven Knight <knight at baldmt dot com>
diff --git a/gentoo/scons.ebuild.in b/gentoo/scons.ebuild.in
index 36f83db..91e38a8 100644
--- a/gentoo/scons.ebuild.in
+++ b/gentoo/scons.ebuild.in
@@ -22,4 +22,5 @@ src_install () {
python setup.py install --root=${D}
dodoc *.txt PKG-INFO MANIFEST
doman scons.1
+ doman sconsign.1
}
diff --git a/rpm/scons.spec.in b/rpm/scons.spec.in
index de34305..a276af7 100644
--- a/rpm/scons.spec.in
+++ b/rpm/scons.spec.in
@@ -43,6 +43,7 @@ python setup.py build
python setup.py install --root=$RPM_BUILD_ROOT --record=INSTALLED_FILES
mkdir -p $RPM_BUILD_ROOT/usr/man/man1
gzip -c scons.1 > $RPM_BUILD_ROOT/usr/man/man1/scons.1.gz
+gzip -c sconsign.1 > $RPM_BUILD_ROOT/usr/man/man1/sconsign.1.gz
%clean
rm -rf $RPM_BUILD_ROOT
@@ -51,3 +52,4 @@ rm -rf $RPM_BUILD_ROOT
%defattr(-,root,root)
__RPM_FILES__
%doc /usr/man/man1/scons.1.gz
+%doc /usr/man/man1/sconsign.1.gz
diff --git a/src/CHANGES.txt b/src/CHANGES.txt
index 8426798..a066689 100644
--- a/src/CHANGES.txt
+++ b/src/CHANGES.txt
@@ -26,6 +26,8 @@ RELEASE 0.XX - XXX
from CVS with a specified module name. This avoids zero-length
files when there is a checkout error.
+ - Add an "sconsign" script to print the contents of .sconsign files.
+
From Gary Oberbrunner:
- Report the target being built in error messages when building
@@ -36,6 +38,17 @@ RELEASE 0.XX - XXX
- Provide helpful error messages when the arguments to env.Install()
are incorrect.
+ From Christoph Wiedemann
+
+ - Have the g++ Tool actually use g++ in preference to c++.
+
+ - Have the gcc Tool actually use gcc in preference to cc.
+
+ - Add a gnutools.py test of the GNU tool chain.
+
+ - Be smarter about linking: use $CC by default and $CXX only if we're
+ linking with any C++ objects.
+
RELEASE 0.90 - Wed, 25 Jun 2003 14:24:52 -0500
diff --git a/src/engine/SCons/SConfTests.py b/src/engine/SCons/SConfTests.py
index 65c84b9..3240aa4 100644
--- a/src/engine/SCons/SConfTests.py
+++ b/src/engine/SCons/SConfTests.py
@@ -76,17 +76,11 @@ class SConfTestCase(unittest.TestCase):
# - cygwin on win32 (using cmd.exe, not bash)
# - posix
# - msvc on win32 (hopefully)
- if self.scons_env.subst('$CXX') == 'c++':
- # better use g++ (which is normally no symbolic link
- # --> the c++ call fails on cygwin
- self.scons_env['CXX'] = 'g++'
- if self.scons_env.subst('$LINK') == 'c++':
- self.scons_env['LINK'] = 'g++'
if (not self.scons_env.Detect( self.scons_env.subst('$CXX') ) or
not self.scons_env.Detect( self.scons_env.subst('$CC') ) or
not self.scons_env.Detect( self.scons_env.subst('$LINK') )):
raise Exception, "This test needs an installed compiler!"
- if self.scons_env['LINK'] == 'g++':
+ if self.scons_env['CXX'] == 'g++':
global existing_lib
existing_lib = 'm'
diff --git a/src/engine/SCons/Sig/SigTests.py b/src/engine/SCons/Sig/SigTests.py
index 3010396..af2ebab 100644
--- a/src/engine/SCons/Sig/SigTests.py
+++ b/src/engine/SCons/Sig/SigTests.py
@@ -400,6 +400,41 @@ class SConsignEntryTestCase(unittest.TestCase):
assert e.bsig == None
assert e.implicit == None
+class _SConsignTestCase(unittest.TestCase):
+
+ def runTest(self):
+ class DummyModule:
+ def to_string(self, sig):
+ return str(sig)
+
+ def from_string(self, sig):
+ return int(sig)
+
+ class DummyNode:
+ path = 'not_a_valid_path'
+
+ f = SCons.Sig._SConsign()
+ f.set_bsig('foo', 1)
+ assert f.get('foo') == (None, 1, None)
+ f.set_csig('foo', 2)
+ assert f.get('foo') == (None, 1, 2)
+ f.set_timestamp('foo', 3)
+ assert f.get('foo') == (3, 1, 2)
+ f.set_implicit('foo', ['bar'])
+ assert f.get('foo') == (3, 1, 2)
+ assert f.get_implicit('foo') == ['bar']
+
+ f = SCons.Sig._SConsign(None, DummyModule())
+ f.set_bsig('foo', 1)
+ assert f.get('foo') == (None, 1, None)
+ f.set_csig('foo', 2)
+ assert f.get('foo') == (None, 1, 2)
+ f.set_timestamp('foo', 3)
+ assert f.get('foo') == (3, 1, 2)
+ f.set_implicit('foo', ['bar'])
+ assert f.get('foo') == (3, 1, 2)
+ assert f.get_implicit('foo') == ['bar']
+
class SConsignFileTestCase(unittest.TestCase):
def runTest(self):
@@ -431,6 +466,7 @@ def suite():
suite.addTest(TimeStampTestCase())
suite.addTest(CalcTestCase())
suite.addTest(SConsignEntryTestCase())
+ suite.addTest(_SConsignTestCase())
suite.addTest(SConsignFileTestCase())
return suite
diff --git a/src/engine/SCons/Sig/__init__.py b/src/engine/SCons/Sig/__init__.py
index 65fe807..36145cb 100644
--- a/src/engine/SCons/Sig/__init__.py
+++ b/src/engine/SCons/Sig/__init__.py
@@ -76,34 +76,24 @@ class SConsignEntry:
csig = None
implicit = None
-class SConsignFile:
- """
- Encapsulates reading and writing a .sconsign file.
- """
+class _SConsign:
- def __init__(self, dir, module=None):
+ def __init__(self, fp=None, module=None):
"""
- dir - the directory for the file
+ fp - file pointer to read entries from
module - the signature module being used
"""
- self.dir = dir
-
if module is None:
self.module = default_calc.module
else:
self.module = module
- self.sconsign = os.path.join(dir.path, '.sconsign')
self.entries = {}
self.dirty = 0
- try:
- file = open(self.sconsign, 'rb')
- except:
- pass
- else:
+ if fp:
try:
- self.entries = cPickle.load(file)
+ self.entries = cPickle.load(fp)
if type(self.entries) is not type({}):
self.entries = {}
raise TypeError
@@ -190,6 +180,27 @@ class SConsignFile:
entry.implicit = implicit
self.set_entry(filename, entry)
+class SConsignFile(_SConsign):
+ """
+ Encapsulates reading and writing a .sconsign file.
+ """
+
+ def __init__(self, dir, module=None):
+ """
+ dir - the directory for the file
+ module - the signature module being used
+ """
+
+ self.dir = dir
+ self.sconsign = os.path.join(dir.path, '.sconsign')
+
+ try:
+ fp = open(self.sconsign, 'rb')
+ except:
+ fp = None
+
+ _SConsign.__init__(self, fp, module)
+
def write(self):
"""
Write the .sconsign file to disk.
diff --git a/src/engine/SCons/Tool/g++.py b/src/engine/SCons/Tool/g++.py
index 6beca1c..6497fe2 100644
--- a/src/engine/SCons/Tool/g++.py
+++ b/src/engine/SCons/Tool/g++.py
@@ -35,25 +35,22 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import os.path
+import cc
import SCons.Defaults
import SCons.Tool
import SCons.Util
-compilers = ['c++', 'g++']
-
-CXXSuffixes = ['.cc', '.cpp', '.cxx', '.c++', '.C++']
-if os.path.normcase('.c') != os.path.normcase('.C'):
- CXXSuffixes.append('.C')
+compilers = ['g++', 'c++']
def generate(env):
"""Add Builders and construction variables for g++ to an Environment."""
static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
- for suffix in CXXSuffixes:
+ for suffix in cc.CXXSuffixes:
static_obj.add_action(suffix, SCons.Defaults.CXXAction)
shared_obj.add_action(suffix, SCons.Defaults.ShCXXAction)
- env['CXX'] = env.Detect(compilers) or 'c++'
+ env['CXX'] = env.Detect(compilers) or 'g++'
env['CXXFLAGS'] = '$CCFLAGS'
env['CXXCOM'] = '$CXX $CXXFLAGS $CPPFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES'
env['SHCXX'] = '$CXX'
diff --git a/src/engine/SCons/Tool/gcc.py b/src/engine/SCons/Tool/gcc.py
index bf81ba8..a9f8ee1 100644
--- a/src/engine/SCons/Tool/gcc.py
+++ b/src/engine/SCons/Tool/gcc.py
@@ -35,13 +35,13 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import cc
-compilers = ['cc', 'gcc']
+compilers = ['gcc', 'cc']
def generate(env):
"""Add Builders and construction variables for gcc to an Environment."""
cc.generate(env)
- env['CC'] = env.Detect(compilers) or 'cc'
+ env['CC'] = env.Detect(compilers) or 'gcc'
if env['PLATFORM'] == 'cygwin':
env['SHCCFLAGS'] = '$CCFLAGS'
else:
diff --git a/src/engine/SCons/Tool/gnulink.py b/src/engine/SCons/Tool/gnulink.py
index 1928b58..4c14383 100644
--- a/src/engine/SCons/Tool/gnulink.py
+++ b/src/engine/SCons/Tool/gnulink.py
@@ -33,13 +33,41 @@ selection method.
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+import cc
import link
+import os.path
+import SCons.Action
+import SCons.Builder
+import SCons.Errors
+import SCons.Util
-linkers = ['c++', 'cc', 'g++', 'gcc']
+linkers = ['g++', 'gcc', 'c++', 'cc']
+def cxxSource(sources):
+ for s in sources:
+ if os.path.splitext(str(s))[1] in cc.CXXSuffixes:
+ return 1
+ if cxxSource(s.sources):
+ return 1
+ return 0
+
+def smart_link(source, target, env, for_signature):
+ cppSource = 0
+ if source is None:
+ # may occur, when env.subst('$LINK') is called
+ return '$CXX'
+ if not SCons.Util.is_List(source):
+ source = [source]
+
+ if cxxSource(source):
+ return '$CXX'
+ else:
+ return '$CC'
+
def generate(env):
"""Add Builders and construction variables for gnulink to an Environment."""
link.generate(env)
-
+ env['LINK'] = smart_link
+
def exists(env):
return env.Detect(linkers)
diff --git a/src/script/MANIFEST.in b/src/script/MANIFEST.in
index ebff829..9783f23 100644
--- a/src/script/MANIFEST.in
+++ b/src/script/MANIFEST.in
@@ -1 +1,2 @@
scons
+sconsign
diff --git a/src/script/scons.py b/src/script/scons.py
index f128d1d..501f071 100644
--- a/src/script/scons.py
+++ b/src/script/scons.py
@@ -36,9 +36,18 @@ __date__ = "__DATE__"
__developer__ = "__DEVELOPER__"
-import sys
-import os.path
import os
+import os.path
+import sys
+
+##############################################################################
+# BEGIN STANDARD SCons SCRIPT HEADER
+#
+# This is the cut-and-paste logic so that a self-contained script can
+# interoperate correctly with different SCons versions and installation
+# locations for the engine. If you modify anything in this section, you
+# should also change other scripts that use this same header.
+##############################################################################
# Strip the script directory from sys.path() so on case-insensitive
# (WIN32) systems Python doesn't think that the "scons" script is the
@@ -120,5 +129,9 @@ libs.extend(map(lambda x: os.path.join(x, 'scons'), prefs))
sys.path = libs + sys.path
+##############################################################################
+# END STANDARD SCons SCRIPT HEADER
+##############################################################################
+
import SCons.Script
SCons.Script.main()
diff --git a/src/script/sconsign.py b/src/script/sconsign.py
new file mode 100644
index 0000000..7b5daf8
--- /dev/null
+++ b/src/script/sconsign.py
@@ -0,0 +1,223 @@
+#! /usr/bin/env python
+#
+# SCons - a Software Constructor
+#
+# Copyright (c) 2001, 2002, 2003 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__ = "__REVISION__"
+
+__version__ = "__VERSION__"
+
+__build__ = "__BUILD__"
+
+__buildsys__ = "__BUILDSYS__"
+
+__date__ = "__DATE__"
+
+__developer__ = "__DEVELOPER__"
+
+import os
+import os.path
+import sys
+
+##############################################################################
+# BEGIN STANDARD SCons SCRIPT HEADER
+#
+# This is the cut-and-paste logic so that a self-contained script can
+# interoperate correctly with different SCons versions and installation
+# locations for the engine. If you modify anything in this section, you
+# should also change other scripts that use this same header.
+##############################################################################
+
+# Strip the script directory from sys.path() so on case-insensitive
+# (WIN32) systems Python doesn't think that the "scons" script is the
+# "SCons" package. Replace it with our own library directories
+# (version-specific first, in case they installed by hand there,
+# followed by generic) so we pick up the right version of the build
+# engine modules if they're in either directory.
+
+script_dir = sys.path[0]
+
+if script_dir in sys.path:
+ sys.path.remove(script_dir)
+
+libs = []
+
+if os.environ.has_key("SCONS_LIB_DIR"):
+ libs.append(os.environ["SCONS_LIB_DIR"])
+
+local = 'scons-local-' + __version__
+if script_dir:
+ local = os.path.join(script_dir, local)
+libs.append(local)
+
+scons_version = 'scons-%s' % __version__
+
+prefs = []
+
+if sys.platform == 'win32':
+ # sys.prefix is (likely) C:\Python*;
+ # check only C:\Python*.
+ prefs.append(sys.prefix)
+else:
+ # On other (POSIX) platforms, things are more complicated due to
+ # the variety of path names and library locations. Try to be smart
+ # about it.
+ if script_dir == 'bin':
+ # script_dir is `pwd`/bin;
+ # check `pwd`/lib/scons*.
+ prefs.append(os.getcwd())
+ else:
+ if script_dir == '.' or script_dir == '':
+ script_dir = os.getcwd()
+ head, tail = os.path.split(script_dir)
+ if tail == "bin":
+ # script_dir is /foo/bin;
+ # check /foo/lib/scons*.
+ prefs.append(head)
+
+ head, tail = os.path.split(sys.prefix)
+ if tail == "usr":
+ # sys.prefix is /foo/usr;
+ # check /foo/usr/lib/scons* first,
+ # then /foo/usr/local/lib/scons*.
+ prefs.append(sys.prefix)
+ prefs.append(os.path.join(sys.prefix, "local"))
+ elif tail == "local":
+ h, t = os.path.split(head)
+ if t == "usr":
+ # sys.prefix is /foo/usr/local;
+ # check /foo/usr/local/lib/scons* first,
+ # then /foo/usr/lib/scons*.
+ prefs.append(sys.prefix)
+ prefs.append(head)
+ else:
+ # sys.prefix is /foo/local;
+ # check only /foo/local/lib/scons*.
+ prefs.append(sys.prefix)
+ else:
+ # sys.prefix is /foo (ends in neither /usr or /local);
+ # check only /foo/lib/scons*.
+ prefs.append(sys.prefix)
+
+ prefs = map(lambda x: os.path.join(x, 'lib'), prefs)
+
+# Look first for 'scons-__version__' in all of our preference libs,
+# then for 'scons'.
+libs.extend(map(lambda x: os.path.join(x, scons_version), prefs))
+libs.extend(map(lambda x: os.path.join(x, 'scons'), prefs))
+
+sys.path = libs + sys.path
+
+##############################################################################
+# END STANDARD SCons SCRIPT HEADER
+##############################################################################
+
+import getopt
+
+helpstr = """\
+Usage: sconsign [OPTIONS] FILE [...]
+Options:
+ -b, --bsig Print build signature information.
+ -c, --csig Print content signature information.
+ -e, --entry ENTRY Print only info about ENTRY.
+ -h, --help Print this message and exit.
+ -i, --implicit Print implicit dependency information.
+ -t, --timestamp Print timestamp information.
+ -v, --verbose Verbose, describe each field.
+"""
+
+opts, args = getopt.getopt(sys.argv[1:], "bce:hitv",
+ ['bsig', 'csig', 'entry=', 'help', 'implicit',
+ 'timestamp', 'verbose'])
+
+pf_bsig = 0x1
+pf_csig = 0x2
+pf_timestamp = 0x4
+pf_implicit = 0x8
+pf_all = pf_bsig | pf_csig | pf_timestamp | pf_implicit
+
+entries = []
+printflags = 0
+verbose = 0
+
+for o, a in opts:
+ if o in ('-b', '--bsig'):
+ printflags = printflags | pf_bsig
+ elif o in ('-c', '--csig'):
+ printflags = printflags | pf_csig
+ elif o in ('-e', '--entry'):
+ entries.append(a)
+ elif o in ('-h', o == '--help'):
+ print helpstr
+ sys.exit(0)
+ elif o in ('-i', '--implicit'):
+ printflags = printflags | pf_implicit
+ elif o in ('-t', '--timestamp'):
+ printflags = printflags | pf_timestamp
+ elif o in ('-v', '--verbose'):
+ verbose = 1
+
+if printflags == 0:
+ printflags = pf_all
+
+def field(name, pf, val):
+ if printflags & pf:
+ if verbose:
+ sep = "\n " + name + ": "
+ else:
+ sep = " "
+ return sep + (val or '-')
+ else:
+ return ""
+
+def printfield(name, entry):
+ timestamp = field("timestamp", pf_timestamp, entry.timestamp)
+ bsig = field("bsig", pf_bsig, entry.bsig)
+ csig = field("csig", pf_csig, entry.csig)
+ print name + ":" + timestamp + bsig + csig
+ if printflags & pf_implicit and entry.implicit:
+ if verbose:
+ print " implicit:"
+ for i in entry.implicit:
+ print " %s" % i
+
+import SCons.Sig
+
+def do_sconsign(fp):
+ sconsign = SCons.Sig._SConsign(fp)
+ if entries:
+ for name in entries:
+ try:
+ entry = sconsign.entries[name]
+ except KeyError:
+ sys.stderr.write("sconsign: no entry `%s' in `%s'\n" % (name, args[0]))
+ else:
+ printfield(name, entry)
+ else:
+ for name, e in sconsign.entries.items():
+ printfield(name, e)
+
+
+for a in args:
+ do_sconsign(open(a, 'rb'))
diff --git a/src/setup.py b/src/setup.py
index bb6f0ab..a4cb17f 100644
--- a/src/setup.py
+++ b/src/setup.py
@@ -195,7 +195,7 @@ arguments = {
"SCons.Sig",
"SCons.Tool"],
'package_dir' : {'' : 'engine'},
- 'scripts' : ["script/scons"],
+ 'scripts' : ['script/scons', 'script/sconsign'],
'cmdclass' : {'install' : install,
'install_lib' : install_lib,
'install_scripts' : install_scripts}
diff --git a/test/LINK.py b/test/LINK.py
index e3c21bc..5333290 100644
--- a/test/LINK.py
+++ b/test/LINK.py
@@ -44,7 +44,7 @@ os.system(string.join(sys.argv[1:], " "))
test.write('SConstruct', """
foo = Environment()
-link = foo.Dictionary('LINK')
+link = foo.subst("$LINK")
bar = Environment(LINK = r'%s wrapper.py ' + link)
foo.Program(target = 'foo', source = 'foo.c')
bar.Program(target = 'bar', source = 'bar.c')
diff --git a/test/LINKFLAGS.py b/test/LINKFLAGS.py
index 58efcf3..047ddc7 100644
--- a/test/LINKFLAGS.py
+++ b/test/LINKFLAGS.py
@@ -44,7 +44,7 @@ os.system(string.join(sys.argv[1:], " "))
test.write('SConstruct', """
foo = Environment()
-link = foo.Dictionary('LINK')
+link = foo.subst("$LINK")
bar = Environment(LINK = '', LINKFLAGS = r'%s wrapper.py ' + link)
foo.Program(target = 'foo', source = 'foo.c')
bar.Program(target = 'bar', source = 'bar.c')
diff --git a/test/sconsign-script.py b/test/sconsign-script.py
new file mode 100644
index 0000000..006f414
--- /dev/null
+++ b/test/sconsign-script.py
@@ -0,0 +1,170 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2001, 2002, 2003 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__ = "/home/scons/scons/branch.0/baseline/test/sconsign.py 0.90.D001 2003/06/25 15:32:24 knight"
+
+import os.path
+import string
+
+import TestCmd
+import TestSCons
+
+test = TestSCons.TestSCons(match = TestCmd.match_re)
+
+test.subdir('sub1', 'sub2')
+
+test.write('SConstruct', """
+env1 = Environment(PROGSUFFIX = '.exe', OBJSUFFIX = '.obj')
+env1.Program('sub1/hello.c')
+env2 = env1.Copy(CPPPATH = ['sub2'])
+env2.Program('sub2/hello.c')
+""")
+
+test.write(['sub1', 'hello.c'], r"""\
+int
+main(int argc, char *argv[])
+{
+ argv[argc++] = "--";
+ printf("sub1/hello.c\n");
+ exit (0);
+}
+""")
+
+test.write(['sub2', 'hello.c'], r"""\
+#include <inc1.h>
+#include <inc2.h>
+int
+main(int argc, char *argv[])
+{
+ argv[argc++] = "--";
+ printf("sub2/goodbye.c\n");
+ exit (0);
+}
+""")
+
+test.write(['sub2', 'inc1.h'], r"""\
+#define STRING1 "inc1.h"
+""")
+
+test.write(['sub2', 'inc2.h'], r"""\
+#define STRING2 "inc2.h"
+""")
+
+test.run(arguments = '--implicit-cache .')
+
+test.run(interpreter = TestSCons.python,
+ program = "sconsign",
+ arguments = "sub1/.sconsign",
+ stdout = """\
+hello.exe: - \S+ -
+hello.obj: - \S+ -
+""")
+
+test.run(interpreter = TestSCons.python,
+ program = "sconsign",
+ arguments = "-v sub1/.sconsign",
+ stdout = """\
+hello.exe:
+ timestamp: -
+ bsig: \S+
+ csig: -
+hello.obj:
+ timestamp: -
+ bsig: \S+
+ csig: -
+""")
+
+test.run(interpreter = TestSCons.python,
+ program = "sconsign",
+ arguments = "-b -v sub1/.sconsign",
+ stdout = """\
+hello.exe:
+ bsig: \S+
+hello.obj:
+ bsig: \S+
+""")
+
+test.run(interpreter = TestSCons.python,
+ program = "sconsign",
+ arguments = "-c -v sub1/.sconsign",
+ stdout = """\
+hello.exe:
+ csig: -
+hello.obj:
+ csig: -
+""")
+
+test.run(interpreter = TestSCons.python,
+ program = "sconsign",
+ arguments = "-e hello.obj sub1/.sconsign",
+ stdout = """\
+hello.obj: - \S+ -
+""")
+
+test.run(interpreter = TestSCons.python,
+ program = "sconsign",
+ arguments = "-e hello.obj -e hello.exe -e hello.obj sub1/.sconsign",
+ stdout = """\
+hello.obj: - \S+ -
+hello.exe: - \S+ -
+hello.obj: - \S+ -
+""")
+
+test.run(interpreter = TestSCons.python,
+ program = "sconsign",
+ arguments = "sub2/.sconsign",
+ stdout = """\
+hello.exe: - \S+ -
+hello.obj: - \S+ -
+ %s
+ %s
+""" % (string.replace(os.path.join('sub2', 'inc1.h'), '\\', '\\\\'),
+ string.replace(os.path.join('sub2', 'inc2.h'), '\\', '\\\\')))
+
+test.run(interpreter = TestSCons.python,
+ program = "sconsign",
+ arguments = "-i -v sub2/.sconsign",
+ stdout = """\
+hello.exe:
+hello.obj:
+ implicit:
+ %s
+ %s
+""" % (string.replace(os.path.join('sub2', 'inc1.h'), '\\', '\\\\'),
+ string.replace(os.path.join('sub2', 'inc2.h'), '\\', '\\\\')))
+
+test.pass_test()
+
+test.run(interpreter = TestSCons.python,
+ program = "sconsign",
+ arguments = "-e hello.obj sub2/.sconsign sub1/.sconsign",
+ stdout = """\
+hello.obj: - \S+ -
+ %s
+ %s
+hello.obj: - \S+ -
+""" % (string.replace(os.path.join('sub2', 'inc1.h'), '\\', '\\\\'),
+ string.replace(os.path.join('sub2', 'inc2.h'), '\\', '\\\\')))
+
+test.pass_test()