From: stevenknight Date: Wed, 21 Sep 2005 13:02:57 +0000 (+0000) Subject: Document the necessity of passing in "target" to and "source" to env.subst() calls... X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=762c760e4b2a1bd03a55b4e2b4c137f0b400c6d6;p=scons.git Document the necessity of passing in "target" to and "source" to env.subst() calls that want to expand ${TARGET,TARGETS,SOURCE,SOURCES}. Also, speed up the Variable_Method_Caller class. git-svn-id: http://scons.tigris.org/svn/scons/trunk@1347 fdb21ef1-2011-0410-befe-b5e4ea1792b1 --- diff --git a/doc/man/scons.1 b/doc/man/scons.1 index 14a0bf2e..cf60e6c7 100644 --- a/doc/man/scons.1 +++ b/doc/man/scons.1 @@ -4283,15 +4283,71 @@ env.SourceCode('no_source.c', None) '\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .TP -.RI env.subst( string ) +.RI env.subst( string ", [" raw ", " target ", " source ", " conv ]) Performs construction variable interpolation on the specified string argument. +By default, +any +.B $( +and +.B $) +will be stripped from the returned string. +The optional +.I raw +target may be set to +.B 1 +if you want to preserve these, +although there is usually +no reason to do this. + +The optional +.I target +and +.I source +keyword arguments +must be set to lists of +target and source nodes, respectively, +if you want the +.BR $TARGET , +.BR $TARGETS , +.BR $SOURCE +and +.BR $SOURCES +to be available for expansion. +This is usually necessary if you are +calling +.BR env.subst () +from within a Python function used +as an SCons action. + +By default, +all returned values are converted +to their string representation. +The optional +.I conv +argument +may specify a conversion function +that will be used in place of +the default. +For example, if you want Python objects +(including SCons Nodes) +to be returned as Python objects, +you can use the Python +.B lambda +idiom to pass in an unnamed function +that simply returns its unconverted argument. + .ES print env.subst("The C compiler is: $CC") def compile(target, source, env): - sourceDir = env.subst("${SOURCE.srcdir}") + sourceDir = env.subst("${SOURCE.srcdir}", + target=target, + source=source) + +source_nodes = env.subst('$EXPAND_TO_NODELIST', + conv=lambda x: x) .EE '\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" diff --git a/src/RELEASE.txt b/src/RELEASE.txt index a6b10c3c..7e61b616 100644 --- a/src/RELEASE.txt +++ b/src/RELEASE.txt @@ -31,12 +31,12 @@ RELEASE 0.97 - XXX -- DIRECTORY TREES ARE NO LONGER AUTOMATICALLY SCANNED FOR CHANGES Custom builders and Command() calls that accept directories as - source arguments no longer scan entire on-disk directory trees - by default. This means that their targets will not be - automatically rebuilt if a file changes on disk, and SCons does - *not* already know about. Note that the targets will still be - rebuilt correctly if a file changes that SCons already knows - about due to a Builder or other call. + source arguments no longer scan entire on-disk directory trees by + default. This means that their targets will not be automatically + rebuilt if a file changes on disk *unless* SCons already knows + about the file from a specific Builder or File() call. Note that + the targets will still be rebuilt correctly if a file changes + that SCons already knows about due to a Builder or other call. The existing behavior of scanning on-disk directory trees for any changed file can be maintained by passing the new DirScanner @@ -77,12 +77,12 @@ RELEASE 0.97 - XXX in any SConscript file. - If you are using the Repository feature, are not already using - the SConsignFile() function in your build, you *must* add - SConsignFile(None) to your build to keep interoperating with an - existing Repository that uses the old behavior of a .sconsign - file in each directory. Alternatively, you can rebuild the - Repository with the new default behavior. + If you are using the Repository feature, and are not already + using the SConsignFile() function in your build, you *must* + add "SConsignFile(None)" to your build configuration to keep + interoperating with an existing Repository that uses the old + behavior of a .sconsign file in each directory. Alternatively, + you can rebuild the Repository with the new default behavior. -- OTHER SIGNATURE CHANGES WILL CAUSE LIKELY REBUILDS AFTER UPGRADE @@ -186,6 +186,26 @@ RELEASE 0.97 - XXX "sconsign.1" man pages on UNIX and Linux systems. A new --no-install-man + -- env.subst() NO LONGER EXPANDS $TARGET, $SOURCES, etc. BY DEFAULT + + Calls to the env.subst() method to interpolate construction + variables in strings no longer automatically expand the special + variables $TARGET, $TARGETS, $SOURCE and $SOURCES. The keyword + variables "target" and "source" must now be set to the lists + of target and source files to be used in expansion of those + variables, when desired. + + This is most likely necessary for any env.subst() calls within + a Python function being used as an SCons action for a Builder: + + def build_it(env, target, source): + env.subst('$STRING', target=targets, source=sources) + MyBuilder = Builder(action=build_it) + + The "target" and "source" keyword arguments are backwards + compatible and can be added to SConscript files without breaking + builds on systems using older SCons releases. + -- ParseConfig() METHOD ADDS LIBRARY FILE NAMES TO THE $LIBS VARIABLE The ParseConfig() method now adds library file names returned @@ -218,20 +238,21 @@ RELEASE 0.97 - XXX -- BUILDERS RETURN A LIST-LIKE OBJECT, NOT A REGULAR LIST - Builders calls now return an object that behaves like a list + Builder calls now return an object that behaves like a list (and which provides some other functionality), not an underlying Python list. In general, this should not cause any problems, although it introduces a subtle change in the following behavior: obj += env.Object('foo.c') - If "obj" is a list, Python will no longer update the "obj" in - place, because the return value from env.Object() is no longer - the same type. Python will instead allocate a new object and - assign the local variable "obj" to it. If "obj" is defined in - an SConscript file that calls another SConscript file containing - the above code, "obj" in the first SConscript file will not - contain the objects. + If "obj" is a regular Python list, Python will no longer update + the "obj" in place, because the return value from env.Object() + is no longer the same type. Python will instead allocate a + new object and assign the local variable "obj" to it. If "obj" + is defined in an SConscript file that calls another SConscript + file containing the above code, "obj" in the first SConscript + file will not contain the object file nodes created by the + env.Object() call. You can guarantee that a list will be updated in place regardless of which SConscript file defines it and which adds to it by diff --git a/src/engine/SCons/Defaults.py b/src/engine/SCons/Defaults.py index c1b9d3f4..5c9d5e7e 100644 --- a/src/engine/SCons/Defaults.py +++ b/src/engine/SCons/Defaults.py @@ -332,17 +332,15 @@ class Variable_Method_Caller: def __call__(self, *args, **kw): try: 1/0 except ZeroDivisionError: frame = sys.exc_info()[2].tb_frame - variable = None + variable = self.variable while frame: - try: - variable = frame.f_locals[self.variable] - except KeyError: - pass + if frame.f_locals.has_key(variable): + v = frame.f_locals[variable] + if v: + method = getattr(v, self.method) + return apply(method, args, kw) frame = frame.f_back - if variable is None: - return None - method = getattr(variable, self.method) - return apply(method, args, kw) + return None ConstructionEnvironment = { 'BUILDERS' : {},