Skip to content

Commit 1898eb0

Browse files
committed
Update manpage on variable substitution [skip appveyor]
Signed-off-by: Mats Wichmann <[email protected]>
1 parent 77dd793 commit 1898eb0

File tree

1 file changed

+93
-61
lines changed

1 file changed

+93
-61
lines changed

doc/man/scons.xml

Lines changed: 93 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -2918,16 +2918,22 @@ target file's directory.</para>
29182918
<programlisting language="python">
29192919
# scons will change to the "sub" subdirectory
29202920
# before executing the "cp" command.
2921-
env.Command('sub/dir/foo.out', 'sub/dir/foo.in',
2922-
"cp dir/foo.in dir/foo.out",
2923-
chdir='sub')
2921+
env.Command(
2922+
target='sub/dir/foo.out',
2923+
source='sub/dir/foo.in',
2924+
action="cp dir/foo.in dir/foo.out",
2925+
chdir='sub',
2926+
)
29242927

29252928
# Because chdir is not a string, scons will change to the
29262929
# target's directory ("sub/dir") before executing the
29272930
# "cp" command.
2928-
env.Command('sub/dir/foo.out', 'sub/dir/foo.in',
2929-
"cp foo.in foo.out",
2930-
chdir=1)
2931+
env.Command(
2932+
target='sub/dir/foo.out',
2933+
source='sub/dir/foo.in',
2934+
action="cp foo.in foo.out",
2935+
chdir=True,
2936+
)
29312937
</programlisting>
29322938

29332939
<para>Note that &SCons; will
@@ -6182,14 +6188,25 @@ env.Command('marker', 'input_file', action=[MyBuildAction, Touch('$TARGET')])
61826188

61836189
<para>Before executing a command,
61846190
&scons;
6185-
performs &consvar; substitution on the string that makes up
6186-
the command line of the builder.
6187-
&Consvars; to be interpolated are indicated in the
6191+
performs variable substitution on the string that makes up
6192+
the action part of the builder.
6193+
Variables to be interpolated are indicated in the
61886194
string with a leading
61896195
<literal>$</literal>, to distinguish them from plain text
61906196
which is not to be substituted.
6197+
The name may be surrounded by curly braces
6198+
(<literal>${}</literal>)
6199+
to separate the name from surrounding characters if necessary.
6200+
Curly braces are required when you use
6201+
Python list subscripting/slicing notation on a variable
6202+
to select one or more items from a list,
6203+
or access a variable's special attributes,
6204+
or use Python expression substitution.
6205+
</para>
6206+
6207+
<para>
61916208
Besides regular &consvars;, scons provides the following
6192-
special variables for each command execution:</para>
6209+
special variables for use in expanding commands:</para>
61936210

61946211
<variablelist>
61956212
<varlistentry>
@@ -6261,45 +6278,39 @@ changed since the target was last built.</para>
62616278
</varlistentry>
62626279
</variablelist>
62636280

6264-
<para>Note that the above variables are reserved
6265-
and may not be assigned to in the &consenv;.</para>
6281+
<para>These names are reserved
6282+
and may not be assigned to or used as &consvars;.</para>
62666283

6267-
<para>For example, given the &consvars;
6268-
<literal>CC='cc'</literal>,
6269-
<literal>targets=['foo']</literal>
6270-
and
6271-
<literal>sources=['foo.c', 'bar.c']</literal>:
6284+
<para>For example, the following builder call:
62726285
</para>
62736286

62746287
<programlisting language="python">
6275-
action='$CC -c -o $TARGET $SOURCES'
6288+
env = Environment(CC='cc')
6289+
env.Command(
6290+
target=['foo'],
6291+
source=['foo.c', 'bar.c'],
6292+
action='@echo $CC -c -o $TARGET $SOURCES'
6293+
)
62766294
</programlisting>
62776295

6278-
<para>would produce the command line:</para>
6296+
<para>would produce the following output:</para>
62796297

62806298
<screen>
62816299
cc -c -o foo foo.c bar.c
62826300
</screen>
62836301

6284-
<para>Variable names may be surrounded by curly braces
6285-
(<emphasis role="bold">{}</emphasis>)
6286-
to separate the name from surrounding characters which
6287-
are not part of the name.
6288-
Within the curly braces, a variable name may use
6289-
Python list subscripting/slicing notation to select one
6290-
or more items from a list.
6291-
In the previous example, the string:
6302+
<para>
6303+
In the previous example, a string
62926304
<code>${SOURCES[1]}</code>
6293-
would produce:</para>
6294-
6295-
<screen>
6296-
bar.c
6297-
</screen>
6305+
would expand to: <computeroutput>bar.c</computeroutput>.
6306+
</para>
62986307

6299-
<para>Additionally, a variable name may
6308+
<para>A variable name may
63006309
have the following
63016310
modifiers appended within the enclosing curly braces
6302-
to access properties of the interpolated string:</para>
6311+
to access properties of the interpolated string.
6312+
These are known as <firstterm>special attributes</firstterm>.
6313+
</para>
63036314

63046315
<simplelist>
63056316
<member><parameter>base</parameter> -
@@ -6378,23 +6389,18 @@ ${SOURCE.rsrcdir} =&gt; /usr/repository/src
63786389
</literallayout>
63796390

63806391
<para>
6381-
Modifiers can be combined, like
6382-
<literal>${TARGET.base.windows}</literal>,
6392+
Some modifiers can be combined, like
63836393
<literal>${TARGET.srcpath.base)</literal>,
63846394
<literal>${TARGET.file.suffix}</literal>, etc.
63856395
</para>
63866396

6387-
<para>Note that curly braces braces may also be used
6388-
to enclose arbitrary Python code to be evaluated.
6389-
(In fact, this is how the above modifiers are substituted,
6390-
they are simply attributes of the Python objects
6391-
that represent &cv-TARGET;, &cv-SOURCES;, etc.)
6397+
<para>The curly brace notation may also be used
6398+
to enclose a Python expression to be evaluated.
63926399
See <xref linkend='python_code_substitution'/> below
6393-
for more thorough examples of
6394-
how this can be used.</para>
6400+
for a description.</para>
63956401

6396-
<para>Lastly, a variable name
6397-
may be a callable Python function
6402+
<para>A variable name
6403+
may also be a Python function
63986404
associated with a
63996405
&consvar; in the environment.
64006406
The function should
@@ -6425,6 +6431,12 @@ def foo(target, source, env, for_signature):
64256431
env=Environment(FOO=foo, BAR="$FOO baz")
64266432
</programlisting>
64276433

6434+
<para>As a reminder, this evaluation happens when
6435+
<literal>$BAR</literal> is actually used in a
6436+
builder action. The value of <literal>env['BAR']</literal>
6437+
will be exactly as it was set: <literal>"$FOO baz"</literal>.
6438+
</para>
6439+
64286440
<para>You can use this feature to pass arguments to a
64296441
Python function by creating a callable class
64306442
that stores one or more arguments in an object,
@@ -6496,17 +6508,17 @@ echo Last build occurred . &gt; $TARGET
64966508
<title>Python Code Substitution</title>
64976509

64986510
<para>
6499-
Any Python code within curly braces
6500-
(<emphasis role="bold">{}</emphasis>)
6501-
and introduced by the variable prefix <literal>$</literal>
6502-
will be evaluated using the Python <function>eval</function> statement,
6503-
with the Python globals set to
6504-
the current environment's set of &consvars;, and the result
6505-
substituted in.
6511+
If a substitutable expression using the notation
6512+
<literal>${something}</literal> does not appear to match one of
6513+
the other substitution patterns,
6514+
it is evaluated as a Python expression.
6515+
This uses Python's <function>eval</function> function,
6516+
with the <parameter>globals</parameter> parameter set to
6517+
the current environment's set of &consvars;,
6518+
and the result substituted in.
65066519
So in the following case:</para>
65076520

65086521
<programlisting language="python">
6509-
env['COND'] = 0
65106522
env.Command('foo.out', 'foo.in',
65116523
'''echo ${COND==1 and 'FOO' or 'BAR'} &gt; $TARGET''')
65126524
</programlisting>
@@ -6530,7 +6542,7 @@ built, not when the SConscript is being read. So if
65306542
<literal>env['COND']</literal> is changed
65316543
later in the SConscript, the final value will be used.</para>
65326544

6533-
<para>Here's a more interesting example. Note that all of
6545+
<para>Here's a more complete example. Note that all of
65346546
<envar>COND</envar>,
65356547
<envar>FOO</envar>,
65366548
and
@@ -6541,17 +6553,28 @@ separated by spaces.</para>
65416553

65426554
<programlisting language="python">
65436555
env=Environment()
6544-
env['COND'] = 0
6556+
env['COND'] = 1
65456557
env['FOO'] = ['foo1', 'foo2']
65466558
env['BAR'] = 'barbar'
65476559
env.Command('foo.out', 'foo.in',
65486560
'echo ${COND==1 and FOO or BAR} &gt; $TARGET')
6549-
6550-
# Will execute this:
6551-
# echo foo1 foo2 &gt; foo.out
65526561
</programlisting>
65536562

6554-
<para>SCons uses the following rules when converting &consvars; into
6563+
<para>will execute:</para>
6564+
<screen>
6565+
echo foo1 foo2 &gt; foo.out
6566+
</screen>
6567+
6568+
<para>
6569+
In point of fact, Python expression evaluation is
6570+
how the special attributes are substituted:
6571+
they are simply attributes of the Python objects
6572+
that represent &cv-TARGET;, &cv-SOURCES;, etc.,
6573+
which &SCons; passes to <function>eval</function> which
6574+
returns the value.
6575+
</para>
6576+
6577+
<para>&SCons; uses the following rules when converting &consvars; into
65556578
command lines:</para>
65566579

65576580
<variablelist>
@@ -6589,6 +6612,16 @@ contain embedded newline characters.</para>
65896612
</listitem>
65906613
</varlistentry>
65916614
</variablelist>
6615+
6616+
<note><para>
6617+
Use of the Python <function>eval</function> function
6618+
is considered to have security implications, since,
6619+
depending on input sources,
6620+
arbitrary unchecked strings of code can be executed by the Python interpreter.
6621+
Although &SCons; makes use of it in a somewhat restricted context,
6622+
you should be aware of this issue when using the
6623+
<literal>${python-expression-for-subst}</literal> form.
6624+
</para></note>
65926625
</refsect2>
65936626

65946627
<refsect2 id='scanner_objects'>
@@ -6613,8 +6646,7 @@ a Python function that will process
66136646
the Node (file)
66146647
and return a list of File Nodes
66156648
representing the implicit
6616-
dependencies (file names) found in the contents;
6617-
or:
6649+
dependencies (file names) found in the contents.
66186650
</para></listitem>
66196651
<listitem><para>
66206652
a dictionary that maps keys

0 commit comments

Comments
 (0)