<!ENTITY ranlib "<application>ranlib</application>">
<!ENTITY rmic "<application>rmic</application>">
<!ENTITY SCons "<application>SCons</application>">
-<!ENTITY scons "<application>scons</application>">
<!ENTITY ScCons "<application>ScCons</application>">
<!ENTITY swig "<application>swig</application>">
<!ENTITY tar "<application>tar</application>">
<!ENTITY build "<filename>build</filename>">
<!ENTITY Makefile "<filename>Makefile</filename>">
<!ENTITY Makefiles "<filename>Makefiles</filename>">
+<!ENTITY scons "<filename>scons</filename>">
<!ENTITY SConscript "<filename>SConscript</filename>">
<!ENTITY SConstruct "<filename>SConstruct</filename>">
<!ENTITY Sconstruct "<filename>Sconstruct</filename>">
-->
-<!ENTITY bar "<application>bar</application>">
+<!ENTITY bar "<filename>bar</filename>">
<!ENTITY common1_c "<filename>common1.c</filename>">
<!ENTITY common2_c "<filename>common2.c</filename>">
<!ENTITY custom_py "<filename>custom.py</filename>">
-<!ENTITY goodbye "<application>goodbye</application>">
+<!ENTITY goodbye "<filename>goodbye</filename>">
<!ENTITY goodbye_o "<filename>goodbye.o</filename>">
<!ENTITY goodbye_obj "<filename>goodbye.obj</filename>">
<!ENTITY file_dll "<filename>file.dll</filename>">
<!ENTITY file_o "<filename>file.o</filename>">
<!ENTITY file_obj "<filename>file.obj</filename>">
<!ENTITY file_out "<filename>file.out</filename>">
-<!ENTITY foo "<application>foo</application>">
+<!ENTITY foo "<filename>foo</filename>">
<!ENTITY foo_o "<filename>foo.o</filename>">
<!ENTITY foo_obj "<filename>foo.obj</filename>">
-<!ENTITY hello "<application>hello</application>">
+<!ENTITY hello "<filename>hello</filename>">
<!ENTITY hello_c "<filename>hello.c</filename>">
<!ENTITY hello_exe "<filename>hello.exe</filename>">
<!ENTITY hello_h "<filename>hello.h</filename>">
<!ENTITY hello_obj "<filename>hello.obj</filename>">
<!ENTITY libfile_a "<filename>libfile_a</filename>">
<!ENTITY libfile_so "<filename>libfile_so</filename>">
-<!ENTITY new_hello "<application>new_hello</application>">
-<!ENTITY new_hello_exe "<application>new_hello.exe</application>">
+<!ENTITY new_hello "<filename>new_hello</filename>">
+<!ENTITY new_hello_exe "<filename>new_hello.exe</filename>">
<!ENTITY prog "<filename>prog</filename>">
<!ENTITY prog1 "<filename>prog1</filename>">
<!ENTITY prog2 "<filename>prog2</filename>">
If you need to install Python and have a choice,
we recommend using the most recent Python 2.5 version available.
Python 2.5 has significant improvements
- the help speed up the performance of &SCons;.
+ that help speed up the performance of &SCons;.
</para>
<para>
- Or, you can use a graphical RPM package manager
- like <application>gnorpm</application>.
+ Or, you can use a graphical RPM package manager.
See your package manager application's documention
for specific instructions about
how to use it to install a downloaded RPM.
<para>
This will build &SCons;,
- install the <application>scons</application> script
+ install the &scons; script
in the default system scripts directory
(<filename>/usr/local/bin</filename> or
<filename>C:\Python25\Scripts</filename>),
For example,
to install &SCons; in appropriate locations
relative to the user's <literal>$HOME</literal> directory,
- the <application>scons</application> script in
+ the &scons; script in
<filename>$HOME/bin</filename>
and the build engine in
<filename>$HOME/lib/scons</filename>,
</para>
+ <para>
+
+ This can also be used to experiment with a newer
+ version of &SCons; than the one installed
+ in your system locations.
+ Of course, the location in which you install the
+ newer version of the &scons; script
+ (<filename>$HOME/bin</filename> in the above example)
+ must be configured in your &PATH; variable
+ before the directory containing
+ the system-installed version
+ of the &scons; script.
+
+ </para>
+
</section>
</section>
If you need to install Python and have a choice,
we recommend using the most recent Python 2.5 version available.
Python 2.5 has significant improvements
- the help speed up the performance of &SCons;.
+ that help speed up the performance of &SCons;.
</para>
<para>
- Or, you can use a graphical RPM package manager
- like <application>gnorpm</application>.
+ Or, you can use a graphical RPM package manager.
See your package manager application's documention
for specific instructions about
how to use it to install a downloaded RPM.
<para>
This will build &SCons;,
- install the <application>scons</application> script
+ install the &scons; script
in the default system scripts directory
(<filename>/usr/local/bin</filename> or
<filename>C:\Python25\Scripts</filename>),
For example,
to install &SCons; in appropriate locations
relative to the user's <literal>$HOME</literal> directory,
- the <application>scons</application> script in
+ the &scons; script in
<filename>$HOME/bin</filename>
and the build engine in
<filename>$HOME/lib/scons</filename>,
</para>
+ <para>
+
+ This can also be used to experiment with a newer
+ version of &SCons; than the one installed
+ in your system locations.
+ Of course, the location in which you install the
+ newer version of the &scons; script
+ (<filename>$HOME/bin</filename> in the above example)
+ must be configured in your &PATH; variable
+ before the directory containing
+ the system-installed version
+ of the &scons; script.
+
+ </para>
+
</section>
</section>
So far we've seen how &SCons; handles one-time builds.
But one of the main functions of a build tool like &SCons;
- is to rebuild only the necessary things
+ is to rebuild only what is necessary
when source files change--or, put another way,
&SCons; should <emphasis>not</emphasis>
- waste time rebuilding things that have already been built.
+ waste time rebuilding things that don't need to be rebuilt.
You can see this at work simply by re-invoking &SCons;
after building our simple &hello; example:
<para>
- Using MD5 Signatures to decide if an input file has changed
+ Using MD5 signatures to decide if an input file has changed
has one surprising benefit:
if a source file has been changed
in such a way that the contents of the
The most familiar way to use time stamps
is the way &Make; does:
that is, have &SCons; decide
- and target must be rebuilt if
+ that a target must be rebuilt
if a source file's modification time is
<emphasis>newer</emphasis>
than the target file.
As a performance enhancement,
&SCons; provides a way to use
MD5 checksums of file contents
- but to only read the contents
- whenever the file's timestamp has changed.
+ but to read those contents
+ only when the file's timestamp has changed.
To do this, call the &Decider;
function with <literal>'MD5-timestamp'</literal>
argument as follows:
While most developers are programming,
this isn't a problem in practice,
since it's unlikely that someone will have built
- and then thought quickly enought to make a substantive
+ and then thought quickly enough to make a substantive
change to a source file within one second.
Certain build scripts or
continuous integration tools may, however,
- rely on the ability to applying changes to files
+ rely on the ability to apply changes to files
automatically and then rebuild as quickly as possible,
in which case use of
<literal>Decider('MD5-timestamp')</literal>
We'd like to have each target file depend on
only its section of the input file.
However, since the input file may contain a lot of data,
- we only want to open the input file if its timestamp has changed.
+ we want to open the input file only if its timestamp has changed.
This could done with a custom
&Decider; function that might look something like this:
For example, if we arbitrarily want to build
one program using MD5 checkums
- and another use file modification times
+ and another using file modification times
from the same source
we might configure it this way:
So far we've seen how &SCons; handles one-time builds.
But one of the main functions of a build tool like &SCons;
- is to rebuild only the necessary things
+ is to rebuild only what is necessary
when source files change--or, put another way,
&SCons; should <emphasis>not</emphasis>
- waste time rebuilding things that have already been built.
+ waste time rebuilding things that don't need to be rebuilt.
You can see this at work simply by re-invoking &SCons;
after building our simple &hello; example:
<para>
- Using MD5 Signatures to decide if an input file has changed
+ Using MD5 signatures to decide if an input file has changed
has one surprising benefit:
if a source file has been changed
in such a way that the contents of the
The most familiar way to use time stamps
is the way &Make; does:
that is, have &SCons; decide
- and target must be rebuilt if
+ that a target must be rebuilt
if a source file's modification time is
<emphasis>newer</emphasis>
than the target file.
% <userinput>touch -t 198901010000 hello.c</userinput>
% <userinput>scons -Q hello</userinput>
cc -o hello.o -c hello.c
- scons: `hello' is up to date.
+ cc -o hello hello.o
</screen>
<para>
As a performance enhancement,
&SCons; provides a way to use
MD5 checksums of file contents
- but to only read the contents
- whenever the file's timestamp has changed.
+ but to read those contents
+ only when the file's timestamp has changed.
To do this, call the &Decider;
function with <literal>'MD5-timestamp'</literal>
argument as follows:
While most developers are programming,
this isn't a problem in practice,
since it's unlikely that someone will have built
- and then thought quickly enought to make a substantive
+ and then thought quickly enough to make a substantive
change to a source file within one second.
Certain build scripts or
continuous integration tools may, however,
- rely on the ability to applying changes to files
+ rely on the ability to apply changes to files
automatically and then rebuild as quickly as possible,
in which case use of
<literal>Decider('MD5-timestamp')</literal>
We'd like to have each target file depend on
only its section of the input file.
However, since the input file may contain a lot of data,
- we only want to open the input file if its timestamp has changed.
+ we want to open the input file only if its timestamp has changed.
This could done with a custom
&Decider; function that might look something like this:
For example, if we arbitrarily want to build
one program using MD5 checkums
- and another use file modification times
+ and another using file modification times
from the same source
we might configure it this way:
<para>
- The SCons man page has more details on using &Glob; with Variant
- directories and Repositories, and returning strings rather than Nodes.
+ The SCons man page has more details on using &Glob;
+ with variant directories
+ (see <xref linkend="chap-variants"></xref>, below)
+ and repositories
+ (see <xref linkend="chap-repositories"></xref>, below),
+ and returning strings rather than Nodes.
</para>
&SCons; recognizes that the object files for
the &common1_c; and &common2_c; source files
- each only need to be built once,
+ each need to be built only once,
even though the resulting object files are
each linked in to both of the resulting executable programs:
<para>
- The SCons man page has more details on using &Glob; with Variant
- directories and Repositories, and returning strings rather than Nodes.
+ The SCons man page has more details on using &Glob;
+ with variant directories
+ (see <xref linkend="chap-variants"></xref>, below)
+ and repositories
+ (see <xref linkend="chap-repositories"></xref>, below),
+ and returning strings rather than Nodes.
</para>
&SCons; recognizes that the object files for
the &common1_c; and &common2_c; source files
- each only need to be built once,
+ each need to be built only once,
even though the resulting object files are
each linked in to both of the resulting executable programs:
&SCons; uses the appropriate library prefix and suffix for your system.
So on POSIX or Linux systems,
the above example would build as follows
- (although &ranlib may not be called on all systems):
+ (although &ranlib; may not be called on all systems):
</para>
&Node; objects that identify the
target file or files that will be built.
These returned &Nodes; can be passed
- as source files to other builder methods,
+ as arguments to other builder methods.
</para>
<para>
- The problem with listing the names as strings
+ The problem with specifying the names as strings
is that our &SConstruct; file is no longer portable
across operating systems.
It won't, for example, work on Windows
between Nodes that represent files
and Nodes that represent directories.
&SCons; supports &File; and &Dir;
- functions that, repectively,
+ functions that, respectively,
return a file or directory Node:
</para>
One of the most common things you can do
with a Node is use it to print the
file name that the node represents.
+ Keep in mind, though, that because the object
+ returned by a builder call
+ is a <emphasis>list</emphasis> of Nodes,
+ you must use Python subscripts
+ to fetch individual Nodes from the list.
For example, the following &SConstruct; file:
</para>
<scons_output_command>scons -Q</scons_output_command>
</scons_output>
+ <para>
+
+ Note that in the above example,
+ the <literal>object_list[0]</literal>
+ extracts an actual Node <emphasis>object</emphasis>
+ from the list,
+ and the Python <literal>print</literal> statement
+ converts the object to a string for printing.
+
+ </para>
+
</section>
<section>
Printing a &Node;'s name
as described in the previous section
- works because the string representation of a &Node;
+ works because the string representation of a &Node; object
is the name of the file.
If you want to do something other than
print the name of the file,
&Node; objects that identify the
target file or files that will be built.
These returned &Nodes; can be passed
- as source files to other builder methods,
+ as arguments to other builder methods.
</para>
<para>
- The problem with listing the names as strings
+ The problem with specifying the names as strings
is that our &SConstruct; file is no longer portable
across operating systems.
It won't, for example, work on Windows
between Nodes that represent files
and Nodes that represent directories.
&SCons; supports &File; and &Dir;
- functions that, repectively,
+ functions that, respectively,
return a file or directory Node:
</para>
One of the most common things you can do
with a Node is use it to print the
file name that the node represents.
+ Keep in mind, though, that because the object
+ returned by a builder call
+ is a <emphasis>list</emphasis> of Nodes,
+ you must use Python subscripts
+ to fetch individual Nodes from the list.
For example, the following &SConstruct; file:
</para>
link /nologo /OUT:hello.exe hello.obj
</screen>
+ <para>
+
+ Note that in the above example,
+ the <literal>object_list[0]</literal>
+ extracts an actual Node <emphasis>object</emphasis>
+ from the list,
+ and the Python <literal>print</literal> statement
+ converts the object to a string for printing.
+
+ </para>
+
</section>
<section>
Printing a &Node;'s name
as described in the previous section
- works because the string representation of a &Node;
+ works because the string representation of a &Node; object
is the name of the file.
If you want to do something other than
print the name of the file,