summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMats Wichmann <mats@linux.com>2024-12-13 14:20:23 (GMT)
committerMats Wichmann <mats@linux.com>2024-12-16 17:04:36 (GMT)
commit3ee18c08c72fe8a6ce6cc2c39c355a880472213e (patch)
tree1cba5ff89e4a15f1195664f17f9b6d35d341f7f9
parent0c21de9c4bd366eeec88e93f1323c1e5dc6a9825 (diff)
downloadSCons-3ee18c08c72fe8a6ce6cc2c39c355a880472213e.zip
SCons-3ee18c08c72fe8a6ce6cc2c39c355a880472213e.tar.gz
SCons-3ee18c08c72fe8a6ce6cc2c39c355a880472213e.tar.bz2
Update docs on special method evaluation
The User Guide uses an example (in the Command chapter) of making a target name out of the source name, a special attribute, and concatenation with a new suffix. The special attribute part is not something that has been introduced. Some searching suggests it's never actually described in the User Guide, though .file, .abspath and .srcdir are used in examples. The attribute used, .basename, doesn't actually exist - there's a .base and a .filebase. Furthermore, the substitution suggested doesn't work. Expansion of special variables like $SOURCE into nodes is deferred - see the docstring of SCons.Subst.NLWrapper - so the internal expansion ends up trying to lookup the attribute on a string, which fails with an AttributeError. The way the user guide entry is written, it was not actually evaluated: it was described as an <scons_example>, but an incomplete one, and since there was no corresponding <scons_output> the problem was not detected. The changes fix up the example to have it use an existing attribute (.base) and do File() on the source, and add a sidebar to provide a bit of an explanation so this isn't just "magic". A subsequent example (ex4, which I added) is dropped as it doesn't add enough value by itself, and the final example (formerly ex5, renamed to ex3) now includes this substitution so it's actually run by the doc machinery, and can be seen to be working correctly. This finally fixes #2905, which was closed in 2018 as having been addressed, though the non-working example actually remained. The issue is also mentioned in #4660, which is not resolved by changing the docs - leaving that open, at least for the time being. Signed-off-by: Mats Wichmann <mats@linux.com>
-rw-r--r--CHANGES.txt3
-rw-r--r--RELEASE.txt4
-rw-r--r--doc/generated/examples/builderscommands_ex3_1.xml (renamed from doc/generated/examples/builderscommands_ex5_1.xml)0
-rw-r--r--doc/user/builders-commands.xml64
-rw-r--r--doc/user/environments.xml2
-rw-r--r--doc/user/nodes.xml14
6 files changed, 54 insertions, 33 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index 5383cb7..285dcda 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -186,6 +186,9 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER
and other attributes rather than indexing into stat return.
- The update-release-info test is adapted to accept changed help output
introduced in Python 3.12.8/3.13.1.
+ - Update the User Guide Command() example which now shows a target name
+ being created from '${SOURCE.base}.out' to use a valid special
+ attribute and to explain what's being done in the example.
RELEASE 4.8.1 - Tue, 03 Sep 2024 17:22:20 -0700
diff --git a/RELEASE.txt b/RELEASE.txt
index d386cb3..25d4862 100644
--- a/RELEASE.txt
+++ b/RELEASE.txt
@@ -211,6 +211,10 @@ DOCUMENTATION
- Improved Variables documentation.
+- Update the User Guide Command() example which now shows a target name
+ being created from '${SOURCE.base}.out' to use a valid special
+ attribute and to explain what's being done in the example.
+
DEVELOPMENT
-----------
diff --git a/doc/generated/examples/builderscommands_ex5_1.xml b/doc/generated/examples/builderscommands_ex3_1.xml
index 67659c1..67659c1 100644
--- a/doc/generated/examples/builderscommands_ex5_1.xml
+++ b/doc/generated/examples/builderscommands_ex3_1.xml
diff --git a/doc/user/builders-commands.xml b/doc/user/builders-commands.xml
index d7e8c34..697193c 100644
--- a/doc/user/builders-commands.xml
+++ b/doc/user/builders-commands.xml
@@ -142,37 +142,49 @@ foo.in
<para>
- Note that &cv-link-SOURCE; and &cv-link-TARGET; are expanded
- in the source and target as well, so you can write:
+ &cv-link-SOURCE; and &cv-link-TARGET; are expanded
+ in the source and target as well:
</para>
- <scons_example name="builderscommands_ex3">
- <file name="SConstruct" printme="1">
-env.Command('${SOURCE.basename}.out', 'foo.in', build)
- </file>
- </scons_example>
-
- <para>
-
- which does the same thing as the previous example, but allows you
- to avoid repeating yourself.
-
- </para>
+ <!-- NOTE: this used to be an scons_example, but was not complete and
+ didn't have a matching scons_output, which meant problems were not
+ detected. The style of this line is now reused in the last example
+ of the section to make sure it's actually tested
+ (see issue #2905 - which was closed prematurely).
+ -->
+ <sconstruct>
+env.Command('${SOURCE.base}.out', File('foo.in'), build)
+ </sconstruct>
<para>
- It may be helpful to use the <parameter>action</parameter>
- keyword to specify the action, is this makes things more clear
- to the reader:
+ Which does the same thing as the previous example, but allows you
+ to write a more generic rule for transforming the source filename
+ to the target filename, since unlike regular Builders,
+ &Command; does not have any built-in rules for that.
</para>
- <scons_example name="builderscommands_ex4">
- <file name="SConstruct" printme="1">
-env.Command('${SOURCE.basename}.out', 'foo.in', action=build)
- </file>
- </scons_example>
+ <tip><para>
+
+ The example uses a <firstterm>Node special attribute</firstterm>
+ (<literal>.base</literal>, the file without its suffix),
+ a concept which has not been introduced yet,
+ but will appear in several subsequent examples
+ (see details in the Reference Manual section
+ <emphasis>Substitution: Special Attributes</emphasis>).
+ Due to the quirks of &SCons;' deferred evaluation scheme,
+ node special attribues do not currently work
+ in source and target arguments <emphasis>if</emphasis> the
+ replacement is a string (like <literal>'foo.in'</literal>).
+ They do work fine in strings describing actions.
+ You can give &SCons; a little help by
+ manually converting the filename string to a Node
+ (see <xref linkend="sect-creating-nodes"/>),
+ which is the approach used in the example.
+
+ </para></tip>
<para>
@@ -187,11 +199,13 @@ env.Command('${SOURCE.basename}.out', 'foo.in', action=build)
which include a message based on the type of action.
However, you can also construct the &Action; object yourself
to pass to &f-Command;, which gives you much more control.
+ Using the <parameter>action</parameter> keyword can also help
+ make such lines easier to read.
Here's an evolution of the example from above showing this approach:
</para>
- <scons_example name="builderscommands_ex5">
+ <scons_example name="builderscommands_ex3">
<file name="SConstruct" printme="1">
env = Environment()
@@ -200,7 +214,7 @@ def build(target, source, env):
return None
act = Action(build, cmdstr="Building ${TARGET}")
-env.Command('foo.out', 'foo.in', action=act)
+env.Command('${SOURCE.base}.out', File('foo.in'), action=act)
</file>
<file name="foo.in">
foo.in
@@ -213,7 +227,7 @@ foo.in
</para>
- <scons_output example="builderscommands_ex5" suffix="1">
+ <scons_output example="builderscommands_ex3" suffix="1">
<scons_output_command>scons -Q</scons_output_command>
</scons_output>
diff --git a/doc/user/environments.xml b/doc/user/environments.xml
index 6807694..ac99608 100644
--- a/doc/user/environments.xml
+++ b/doc/user/environments.xml
@@ -1876,9 +1876,9 @@ env = Environment()
env.Command('foo', [], '__ROOT__/usr/bin/printenv.py')
</file>
<file name="__ROOT__/usr/bin/printenv.py" chmod="0o755">
-#!/usr/bin/env python
import os
import sys
+
if len(sys.argv) &gt; 1:
keys = sys.argv[1:]
else:
diff --git a/doc/user/nodes.xml b/doc/user/nodes.xml
index a652e79..eba6014 100644
--- a/doc/user/nodes.xml
+++ b/doc/user/nodes.xml
@@ -40,7 +40,7 @@ This file is processed by the bin/SConsDoc.py module.
</para>
- <section>
+ <section id="sect-builder-nodelists">
<title>Builder Methods Return Lists of Target Nodes</title>
<para>
@@ -150,7 +150,7 @@ int main() { printf("Goodbye, world!\n"); }
</section>
- <section>
+ <section id="sect-creating-nodes">
<title>Explicitly Creating File and Directory Nodes</title>
<para>
@@ -228,7 +228,7 @@ xyzzy = Entry('xyzzy')
</section>
- <section>
+ <section id="sect-printing-nodes">
<title>Printing &Node; File Names</title>
<para>
@@ -290,7 +290,7 @@ int main() { printf("Hello, world!\n"); }
</section>
- <section>
+ <section id="sect-node-names">
<title>Using a &Node;'s File Name as a String</title>
<para>
@@ -337,7 +337,7 @@ int main() { printf("Hello, world!\n"); }
</section>
- <section>
+ <section id="sect-node-paths">
<title>&GetBuildPath;: Getting the Path From a &Node; or String</title>
<para>
@@ -384,7 +384,7 @@ print(env.GetBuildPath([n, "sub/dir/$VAR"]))
<!--
- <section>
+ <section id="sect-node-contents">
<title>Fetching the Contents of a &Node;</title>
<para>
@@ -422,7 +422,7 @@ int main() { printf("Hello, world!\n"); }
<!--
- <section>
+ <section id="sect-value-nodes">
<title>Python Value &Node;</title>
<para>