summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteven Knight <knight@baldmt.com>2002-05-02 12:16:24 +0000
committerSteven Knight <knight@baldmt.com>2002-05-02 12:16:24 +0000
commit14b0749ef9a6232ad1375f750baf00e0fea14e56 (patch)
treed8ee5ca620e66bb2cd782cb22bbc7cca0731a09d
parent35a9fe7b3a3575367b74fbaf84f5336ee4ca5573 (diff)
downloadscons-14b0749ef9a6232ad1375f750baf00e0fea14e56.tar.gz
Fix for long-line LINKCOM signatures on WIN32; add a for_signature argument to command generators. (Charles Crain)
-rw-r--r--doc/man/scons.112
-rw-r--r--src/CHANGES.txt4
-rw-r--r--src/RELEASE.txt4
-rw-r--r--src/engine/SCons/Action.py7
-rw-r--r--src/engine/SCons/ActionTests.py7
-rw-r--r--src/engine/SCons/Defaults.py16
-rw-r--r--test/CommandGenerator.py2
-rw-r--r--test/long-lines.py8
8 files changed, 41 insertions, 19 deletions
diff --git a/doc/man/scons.1 b/doc/man/scons.1
index afd4c166..3fcfc805 100644
--- a/doc/man/scons.1
+++ b/doc/man/scons.1
@@ -1737,16 +1737,22 @@ can be converted into an Action object
(see the next section).
The generator function
-takes 3 arguments:
+takes four arguments:
.I source
- a list of source nodes,
.I target
- a list of target nodes,
.I env
-- the construction environment. Example:
+- the construction environment.
+.I for_signature
+- a Boolean value that specifies
+whether the generator is being called
+for generating a build signature
+(as opposed to actually executing the command).
+Example:
.ES
-def g(source, target, env):
+def g(source, target, env, for_signature):
return [["gcc", "-c", "-o"] + target + source]
b = Builder(name="Object", generator=g)
diff --git a/src/CHANGES.txt b/src/CHANGES.txt
index 28375d24..f152670b 100644
--- a/src/CHANGES.txt
+++ b/src/CHANGES.txt
@@ -78,6 +78,10 @@ RELEASE 0.07 - Thu, 25 Apr 2002 06:24:50 -0500
- Fix for relative CPPPATH directories in subsidiary SConscript files
(broken in 0.06).
+ - Add a for_signature argument to command generators, so that
+ generators that need to can return distinct values for the
+ command signature and for executing the command.
+
From Alex Jacques:
- Create a better scons.bat file from a py2bat.py script on the Python
diff --git a/src/RELEASE.txt b/src/RELEASE.txt
index 8a79ffcf..1d0a5a92 100644
--- a/src/RELEASE.txt
+++ b/src/RELEASE.txt
@@ -50,6 +50,10 @@ RELEASE 0.07 - Thu, 25 Apr 2002 06:24:50 -0500
is an optional SCons.Node.FS.FS object. You will need to update
the interfaces of any local Scanner functions you have defined.
+ - Command generator functions now take a fourth argument,
+ for_signature. You will need to add this argument to any
+ generator functions you have defined.
+
Please note the following important changes since release 0.05:
- Python functions as Builder actions now take Node objects, not
diff --git a/src/engine/SCons/Action.py b/src/engine/SCons/Action.py
index 1941e1a3..94af6bdf 100644
--- a/src/engine/SCons/Action.py
+++ b/src/engine/SCons/Action.py
@@ -395,13 +395,14 @@ class CommandGeneratorAction(ActionBase):
def __init__(self, generator):
self.generator = generator
- def __generate(self, kw):
+ def __generate(self, kw, for_signature):
import SCons.Util
# Wrap the environment dictionary in an EnvDictProxy
# object to make variable interpolation easier for the
# client.
args = copy.copy(kw)
+ args['for_signature'] = for_signature
if args.has_key("env") and not isinstance(args["env"], EnvDictProxy):
args["env"] = EnvDictProxy(args["env"])
@@ -417,7 +418,7 @@ class CommandGeneratorAction(ActionBase):
return gen_cmd
def execute(self, **kw):
- return apply(self.__generate(kw).execute, (), kw)
+ return apply(self.__generate(kw, 0).execute, (), kw)
def get_contents(self, **kw):
"""Return the signature contents of this action's command line.
@@ -425,7 +426,7 @@ class CommandGeneratorAction(ActionBase):
This strips $(-$) and everything in between the string,
since those parts don't affect signatures.
"""
- return apply(self.__generate(kw).get_contents, (), kw)
+ return apply(self.__generate(kw, 1).get_contents, (), kw)
class LazyCmdGenerator:
"""This is a simple callable class that acts as a command generator.
diff --git a/src/engine/SCons/ActionTests.py b/src/engine/SCons/ActionTests.py
index cda565d3..1a0ec182 100644
--- a/src/engine/SCons/ActionTests.py
+++ b/src/engine/SCons/ActionTests.py
@@ -176,7 +176,7 @@ class CommandGeneratorActionTestCase(unittest.TestCase):
"""Test executing a command generator Action
"""
- def f(dummy, env, self=self):
+ def f(dummy, env, for_signature, self=self):
self.dummy = dummy
assert env.subst("$FOO $( bar $) baz") == 'foo baz\nbar ack bar baz', env.subst("$FOO $( bar $) baz")
assert env.subst("$FOO $( bar $) baz", raw=1) == 'foo baz\nbar ack $( bar $) baz', env.subst("$FOO $( bar $) baz", raw=1)
@@ -194,7 +194,7 @@ class CommandGeneratorActionTestCase(unittest.TestCase):
assert env.subst_list([ '$foo', '$(', 'bar', '$)' ],
raw=1) == [[ 'bar', '$(', 'bar', '$)' ]], env.subst_list([ '$foo', '$(', 'bar', '$)' ], raw=1)
self.dummy=dummy
- def f2(dummy, env, f=func_action):
+ def f2(dummy, env, for_signature, f=func_action):
return f
def ch(cmd, args, env, self=self):
self.cmd.append(cmd)
@@ -223,7 +223,8 @@ class CommandGeneratorActionTestCase(unittest.TestCase):
def test_get_contents(self):
"""Test fetching the contents of a command generator Action
"""
- def f(target, source, foo, bar):
+ def f(target, source, foo, bar, for_signature):
+ assert for_signature, for_signature
return [["guux", foo, "$(", "ignore", "$)", bar]]
a = SCons.Action.CommandGeneratorAction(f)
diff --git a/src/engine/SCons/Defaults.py b/src/engine/SCons/Defaults.py
index 11daa393..db93a670 100644
--- a/src/engine/SCons/Defaults.py
+++ b/src/engine/SCons/Defaults.py
@@ -64,7 +64,7 @@ class SharedCmdGenerator:
self.action_static = static
self.action_shared = shared
- def __call__(self, target, source, env, shared=0):
+ def __call__(self, target, source, env, shared=0, for_signature=0):
for src in source:
try:
if src.attributes.shared != shared:
@@ -165,15 +165,15 @@ Object = SCons.Builder.Builder(name = 'Object',
src_suffix = static_obj.src_suffixes(),
src_builder = [CFile, CXXFile])
-def win32TempFileMunge(env, cmd_list):
+def win32TempFileMunge(env, cmd_list, for_signature):
"""Given a list of command line arguments, see if it is too
long to pass to the win32 command line interpreter. If so,
create a temp file, then pass "@tempfile" as the sole argument
to the supplied command (which is the first element of cmd_list).
Otherwise, just return [cmd_list]."""
cmd = env.subst_list(cmd_list)[0]
- cmdlen = reduce(lambda x, y: x + len(y), cmd, 0) + len(cmd)
- if cmdlen <= 2048:
+ if for_signature or \
+ (reduce(lambda x, y: x + len(y), cmd, 0) + len(cmd)) <= 2048:
return [cmd_list]
else:
import tempfile
@@ -187,11 +187,11 @@ def win32TempFileMunge(env, cmd_list):
return [ [cmd[0], '@' + tmp],
['del', tmp] ]
-def win32LinkGenerator(env, target, source, **kw):
+def win32LinkGenerator(env, target, source, for_signature, **kw):
args = [ '$LINK', '$LINKFLAGS', '/OUT:%s' % target[0],
'$(', '$_LIBDIRFLAGS', '$)', '$_LIBFLAGS' ]
args.extend(map(SCons.Util.to_String, source))
- return win32TempFileMunge(env, args)
+ return win32TempFileMunge(env, args, for_signature)
Program = SCons.Builder.Builder(name='Program',
action='$LINKCOM',
@@ -211,7 +211,7 @@ class LibAffixGenerator:
return self.shared_affix
return self.static_affix
-def win32LibGenerator(target, source, env, shared=1):
+def win32LibGenerator(target, source, env, for_signature, shared=1):
listCmd = [ "$SHLINK", "$SHLINKFLAGS" ]
for tgt in target:
@@ -231,7 +231,7 @@ def win32LibGenerator(target, source, env, shared=1):
else:
# Just treat it as a generic source file.
listCmd.append(str(src))
- return win32TempFileMunge(env, listCmd)
+ return win32TempFileMunge(env, listCmd, for_signature)
def win32LibEmitter(target, source, env, shared=0):
if shared:
diff --git a/test/CommandGenerator.py b/test/CommandGenerator.py
index a85b07a8..9a2a7c79 100644
--- a/test/CommandGenerator.py
+++ b/test/CommandGenerator.py
@@ -42,7 +42,7 @@ sys.exit(0)
""")
test.write('SConstruct', """
-def g(source, target, env):
+def g(source, target, for_signature, env):
import sys
python = sys.executable
return [[python, "build.py", "$TEMPFILE"] + source,
diff --git a/test/long-lines.py b/test/long-lines.py
index 9cf24d87..521ed2c4 100644
--- a/test/long-lines.py
+++ b/test/long-lines.py
@@ -35,10 +35,12 @@ test = TestSCons.TestSCons()
if sys.platform == 'win32':
lib_=''
_dll = '.dll'
+ _export = '__declspec(dllexport) '
linkflag = '/LIBPATH:' + test.workpath()
else:
lib_='lib'
_dll='.so'
+ _export=''
linkflag = '-L' + test.workpath()
test.write('SConstruct', """
@@ -52,6 +54,8 @@ env.Library(target = 'bar', source = 'foo.c', shared=1)
""" % (linkflag, linkflag))
test.write('foo.c', r"""
+%svoid foo() { }
+
int
main(int argc, char *argv[])
{
@@ -59,10 +63,12 @@ main(int argc, char *argv[])
printf("foo.c\n");
exit (0);
}
-""")
+""" % _export)
test.run(arguments = '.')
+test.up_to_date(arguments = '.')
+
test.run(program = test.workpath('foo'), stdout = "foo.c\n")
test.fail_test(not os.path.exists(lib_+'bar'+_dll))