mirror of
https://github.com/Relintai/scons_gd.git
synced 2025-02-06 16:25:59 +01:00
550 lines
15 KiB
XML
550 lines
15 KiB
XML
|
<?xml version='1.0'?>
|
||
|
<!DOCTYPE sconsdoc [
|
||
|
<!ENTITY % scons SYSTEM "../scons.mod">
|
||
|
%scons;
|
||
|
|
||
|
<!ENTITY % builders-mod SYSTEM "../generated/builders.mod">
|
||
|
%builders-mod;
|
||
|
<!ENTITY % functions-mod SYSTEM "../generated/functions.mod">
|
||
|
%functions-mod;
|
||
|
<!ENTITY % tools-mod SYSTEM "../generated/tools.mod">
|
||
|
%tools-mod;
|
||
|
<!ENTITY % variables-mod SYSTEM "../generated/variables.mod">
|
||
|
%variables-mod;
|
||
|
]>
|
||
|
|
||
|
<chapter id="chap-simple"
|
||
|
xmlns="http://www.scons.org/dbxsd/v1.0"
|
||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||
|
xsi:schemaLocation="http://www.scons.org/dbxsd/v1.0 http://www.scons.org/dbxsd/v1.0/scons.xsd">
|
||
|
<title>Simple Builds</title>
|
||
|
|
||
|
<!--
|
||
|
|
||
|
__COPYRIGHT__
|
||
|
|
||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||
|
a copy of this software and associated documentation files (the
|
||
|
"Software"), to deal in the Software without restriction, including
|
||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||
|
permit persons to whom the Software is furnished to do so, subject to
|
||
|
the following conditions:
|
||
|
|
||
|
The above copyright notice and this permission notice shall be included
|
||
|
in all copies or substantial portions of the Software.
|
||
|
|
||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||
|
KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||
|
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||
|
|
||
|
-->
|
||
|
|
||
|
<para>
|
||
|
|
||
|
In this chapter,
|
||
|
you will see several examples of
|
||
|
very simple build configurations using &SCons;,
|
||
|
which will demonstrate how easy
|
||
|
it is to use &SCons; to
|
||
|
build programs from several different programming languages
|
||
|
on different types of systems.
|
||
|
|
||
|
</para>
|
||
|
|
||
|
<section>
|
||
|
<title>Building Simple C / C++ Programs</title>
|
||
|
|
||
|
<para>
|
||
|
|
||
|
Here's the famous "Hello, World!" program in C:
|
||
|
|
||
|
</para>
|
||
|
|
||
|
<programlisting>
|
||
|
int
|
||
|
main()
|
||
|
{
|
||
|
printf("Hello, world!\n");
|
||
|
}
|
||
|
</programlisting>
|
||
|
|
||
|
<para>
|
||
|
|
||
|
And here's how to build it using &SCons;.
|
||
|
Save the code above into <filename>hello.c</filename>,
|
||
|
and enter the following into a file named &SConstruct;:
|
||
|
|
||
|
</para>
|
||
|
|
||
|
<scons_example name="simple_ex1">
|
||
|
<file name="SConstruct" printme="1">
|
||
|
Program('hello.c')
|
||
|
</file>
|
||
|
<file name="hello.c">
|
||
|
int main() { printf("Hello, world!\n"); }
|
||
|
</file>
|
||
|
</scons_example>
|
||
|
|
||
|
<para>
|
||
|
|
||
|
This minimal configuration file gives
|
||
|
&SCons; two pieces of information:
|
||
|
what you want to build
|
||
|
(an executable program),
|
||
|
and the input file from
|
||
|
which you want it built
|
||
|
(the <filename>hello.c</filename> file).
|
||
|
&b-link-Program; is a <firstterm>&builder_method;</firstterm>,
|
||
|
a Python call that tells &SCons; that you want to build an
|
||
|
executable program.
|
||
|
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
|
||
|
That's it. Now run the &scons; command to build the program.
|
||
|
On a POSIX-compliant system like Linux or UNIX,
|
||
|
you'll see something like:
|
||
|
|
||
|
</para>
|
||
|
|
||
|
<scons_output example="simple_ex1" os="posix" suffix="1">
|
||
|
<scons_output_command>scons</scons_output_command>
|
||
|
</scons_output>
|
||
|
|
||
|
<para>
|
||
|
|
||
|
On a Windows system with the Microsoft Visual C++ compiler,
|
||
|
you'll see something like:
|
||
|
|
||
|
</para>
|
||
|
|
||
|
<scons_output example="simple_ex1" os="win32" suffix="2">
|
||
|
<scons_output_command>scons</scons_output_command>
|
||
|
</scons_output>
|
||
|
|
||
|
<para>
|
||
|
|
||
|
First, notice that you only need
|
||
|
to specify the name of the source file,
|
||
|
and that &SCons; correctly deduces the names of
|
||
|
the object and executable files to be built
|
||
|
from the base of the source file name.
|
||
|
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
|
||
|
Second, notice that the same input &SConstruct; file,
|
||
|
without any changes,
|
||
|
generates the correct output file names on both systems:
|
||
|
&hello_o; and &hello; on POSIX systems,
|
||
|
&hello_obj; and &hello_exe; on Windows systems.
|
||
|
This is a simple example of how &SCons;
|
||
|
makes it extremely easy to
|
||
|
write portable software builds.
|
||
|
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
|
||
|
(Note that we won't provide duplicate side-by-side
|
||
|
POSIX and Windows output for all of the examples in this guide;
|
||
|
just keep in mind that, unless otherwise specified,
|
||
|
any of the examples should work equally well on both types of systems.)
|
||
|
|
||
|
</para>
|
||
|
|
||
|
</section>
|
||
|
|
||
|
<section>
|
||
|
<title>Building Object Files</title>
|
||
|
|
||
|
<para>
|
||
|
|
||
|
The &b-link-Program; builder method is only one of
|
||
|
many builder methods that &SCons; provides
|
||
|
to build different types of files.
|
||
|
Another is the &b-link-Object; builder method,
|
||
|
which tells &SCons; to build an object file
|
||
|
from the specified source file:
|
||
|
|
||
|
</para>
|
||
|
|
||
|
<scons_example name="simple_Object">
|
||
|
<file name="SConstruct" printme="1">
|
||
|
Object('hello.c')
|
||
|
</file>
|
||
|
<file name="hello.c">
|
||
|
int main() { printf("Hello, world!\n"); }
|
||
|
</file>
|
||
|
</scons_example>
|
||
|
|
||
|
<para>
|
||
|
|
||
|
Now when you run the &scons; command to build the program,
|
||
|
it will build just the &hello_o; object file on a POSIX system:
|
||
|
|
||
|
</para>
|
||
|
|
||
|
<scons_output example="simple_Object" os="posix" suffix="1">
|
||
|
<scons_output_command>scons</scons_output_command>
|
||
|
</scons_output>
|
||
|
|
||
|
<para>
|
||
|
|
||
|
And just the &hello_obj; object file
|
||
|
on a Windows system (with the Microsoft Visual C++ compiler):
|
||
|
|
||
|
</para>
|
||
|
|
||
|
<scons_output example="simple_Object" os="win32" suffix="2">
|
||
|
<scons_output_command>scons</scons_output_command>
|
||
|
</scons_output>
|
||
|
|
||
|
</section>
|
||
|
|
||
|
<section>
|
||
|
<title>Simple Java Builds</title>
|
||
|
|
||
|
<para>
|
||
|
|
||
|
&SCons; also makes building with Java extremely easy.
|
||
|
Unlike the &b-link-Program; and &b-link-Object; builder methods,
|
||
|
however, the &b-link-Java; builder method
|
||
|
requires that you specify
|
||
|
the name of a destination directory in which
|
||
|
you want the class files placed,
|
||
|
followed by the source directory
|
||
|
in which the <filename>.java</filename> files live:
|
||
|
|
||
|
</para>
|
||
|
|
||
|
<scons_example name="simple_java">
|
||
|
<file name="SConstruct" printme="1">
|
||
|
Java('classes', 'src')
|
||
|
</file>
|
||
|
<file name="src/hello.java">
|
||
|
public class Example1
|
||
|
{
|
||
|
public static void main(String[] args)
|
||
|
{
|
||
|
System.out.println("Hello Java world!\n");
|
||
|
}
|
||
|
}
|
||
|
</file>
|
||
|
</scons_example>
|
||
|
|
||
|
<para>
|
||
|
|
||
|
If the <filename>src</filename> directory
|
||
|
contains a single <filename>hello.java</filename> file,
|
||
|
then the output from running the &scons; command
|
||
|
would look something like this
|
||
|
(on a POSIX system):
|
||
|
|
||
|
</para>
|
||
|
|
||
|
<scons_output example="simple_java" os="posix" suffix="1">
|
||
|
<scons_output_command>scons</scons_output_command>
|
||
|
</scons_output>
|
||
|
|
||
|
<para>
|
||
|
|
||
|
We'll cover Java builds in more detail,
|
||
|
including building Java archive (<filename>.jar</filename>)
|
||
|
and other types of file,
|
||
|
in <xref linkend="chap-java"></xref>.
|
||
|
|
||
|
</para>
|
||
|
|
||
|
</section>
|
||
|
|
||
|
<section>
|
||
|
<title>Cleaning Up After a Build</title>
|
||
|
|
||
|
<para>
|
||
|
|
||
|
When using &SCons;, it is unnecessary to add special
|
||
|
commands or target names to clean up after a build.
|
||
|
Instead, you simply use the
|
||
|
<option>-c</option> or <option>--clean</option>
|
||
|
option when you invoke &SCons;,
|
||
|
and &SCons; removes the appropriate built files.
|
||
|
So if we build our example above
|
||
|
and then invoke <literal>scons -c</literal>
|
||
|
afterwards, the output on POSIX looks like:
|
||
|
|
||
|
</para>
|
||
|
|
||
|
<scons_example name="simple_clean">
|
||
|
<file name="SConstruct">
|
||
|
Program('hello.c')
|
||
|
</file>
|
||
|
<file name="hello.c">
|
||
|
int main() { printf("Hello, world!\n"); }
|
||
|
</file>
|
||
|
</scons_example>
|
||
|
|
||
|
<scons_output example="simple_clean" os="posix" suffix="1">
|
||
|
<scons_output_command>scons</scons_output_command>
|
||
|
<scons_output_command>scons -c</scons_output_command>
|
||
|
</scons_output>
|
||
|
|
||
|
<para>
|
||
|
|
||
|
And the output on Windows looks like:
|
||
|
|
||
|
</para>
|
||
|
|
||
|
<scons_output example="simple_clean" os="win32" suffix="2">
|
||
|
<scons_output_command>scons</scons_output_command>
|
||
|
<scons_output_command>scons -c</scons_output_command>
|
||
|
</scons_output>
|
||
|
|
||
|
<para>
|
||
|
|
||
|
Notice that &SCons; changes its output to tell you that it
|
||
|
is <literal>Cleaning targets ...</literal> and
|
||
|
<literal>done cleaning targets.</literal>
|
||
|
|
||
|
</para>
|
||
|
|
||
|
</section>
|
||
|
|
||
|
<section>
|
||
|
<title>The &SConstruct; File</title>
|
||
|
|
||
|
<para>
|
||
|
|
||
|
If you're used to build systems like &Make;
|
||
|
you've already figured out that the &SConstruct; file
|
||
|
is the &SCons; equivalent of a &Makefile;.
|
||
|
That is, the &SConstruct; file is the input file
|
||
|
that &SCons; reads to control the build.
|
||
|
|
||
|
</para>
|
||
|
|
||
|
<section>
|
||
|
<title>&SConstruct; Files Are Python Scripts</title>
|
||
|
|
||
|
<para>
|
||
|
|
||
|
There is, however, an important difference between
|
||
|
an &SConstruct; file and a &Makefile;:
|
||
|
the &SConstruct; file is actually a Python script.
|
||
|
If you're not already familiar with Python, don't worry.
|
||
|
This User's Guide will introduce you step-by-step
|
||
|
to the relatively small amount of Python you'll
|
||
|
need to know to be able to use &SCons; effectively.
|
||
|
And Python is very easy to learn.
|
||
|
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
|
||
|
One aspect of using Python as the
|
||
|
scripting language is that you can put comments
|
||
|
in your &SConstruct; file using Python's commenting convention;
|
||
|
that is, everything between a '#' and the end of the line
|
||
|
will be ignored:
|
||
|
|
||
|
</para>
|
||
|
|
||
|
<programlisting>
|
||
|
# Arrange to build the "hello" program.
|
||
|
Program('hello.c') # "hello.c" is the source file.
|
||
|
</programlisting>
|
||
|
|
||
|
<para>
|
||
|
|
||
|
You'll see throughout the remainder of this Guide
|
||
|
that being able to use the power of a
|
||
|
real scripting language
|
||
|
can greatly simplify the solutions
|
||
|
to complex requirements of real-world builds.
|
||
|
|
||
|
</para>
|
||
|
|
||
|
</section>
|
||
|
|
||
|
<section>
|
||
|
<title>&SCons; Functions Are Order-Independent</title>
|
||
|
|
||
|
<para>
|
||
|
|
||
|
One important way in which the &SConstruct;
|
||
|
file is not exactly like a normal Python script,
|
||
|
and is more like a &Makefile;,
|
||
|
is that the order in which
|
||
|
the &SCons; functions are called in
|
||
|
the &SConstruct; file
|
||
|
does <emphasis>not</emphasis>
|
||
|
affect the order in which &SCons;
|
||
|
actually builds the programs and object files
|
||
|
you want it to build
|
||
|
<footnote><para>In programming parlance,
|
||
|
the &SConstruct; file is
|
||
|
<emphasis>declarative</emphasis>,
|
||
|
meaning you tell &SCons; what you want done
|
||
|
and let it figure out the order in which to do it,
|
||
|
rather than strictly <emphasis>imperative</emphasis>,
|
||
|
where you specify explicitly the order in
|
||
|
which to do things.
|
||
|
</para>
|
||
|
</footnote>.
|
||
|
In other words, when you call the &b-link-Program; builder
|
||
|
(or any other builder method),
|
||
|
you're not telling &SCons; to build
|
||
|
the program at that moment.
|
||
|
Instead, you're telling &SCons; what you want accomplished,
|
||
|
and it's up to &SCons; to figure out how to do that, and to
|
||
|
take those steps if/when it's necessary.
|
||
|
We'll learn more about how
|
||
|
&SCons; decides when building or rebuilding a target
|
||
|
is necessary in <xref linkend="chap-depends"></xref>, below.
|
||
|
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
|
||
|
&SCons; reflects this distinction between
|
||
|
<emphasis>calling a builder method like</emphasis> &b-Program;
|
||
|
and <emphasis>actually building the program</emphasis>
|
||
|
by printing the status messages that indicate
|
||
|
when it's "just reading" the &SConstruct; file,
|
||
|
and when it's actually building the target files.
|
||
|
This is to make it clear when &SCons; is
|
||
|
executing the Python statements that make up the &SConstruct; file,
|
||
|
and when &SCons; is actually executing the
|
||
|
commands or other actions to
|
||
|
build the necessary files.
|
||
|
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
|
||
|
Let's clarify this with an example.
|
||
|
Python has a <function>print</function> function that
|
||
|
prints a string of characters to the screen.
|
||
|
If we put <function>print</function> calls around
|
||
|
our calls to the &b-Program; builder method:
|
||
|
|
||
|
</para>
|
||
|
|
||
|
<scons_example name="simple_declarative">
|
||
|
<file name="SConstruct" printme="1">
|
||
|
print("Calling Program('hello.c')")
|
||
|
Program('hello.c')
|
||
|
print("Calling Program('goodbye.c')")
|
||
|
Program('goodbye.c')
|
||
|
print("Finished calling Program()")
|
||
|
</file>
|
||
|
<file name="hello.c">
|
||
|
int main() { printf("Hello, world!\n"); }
|
||
|
</file>
|
||
|
<file name="goodbye.c">
|
||
|
int main() { printf("Goodbye, world!\n"); }
|
||
|
</file>
|
||
|
</scons_example>
|
||
|
|
||
|
<para>
|
||
|
|
||
|
Then when we execute &SCons;,
|
||
|
we see the output from calling the <function>print</function>
|
||
|
function in between the messages about
|
||
|
reading the &SConscript; files,
|
||
|
indicating that is when the
|
||
|
Python statements are being executed:
|
||
|
|
||
|
</para>
|
||
|
|
||
|
<scons_output example="simple_declarative" os="posix" suffix="1">
|
||
|
<scons_output_command>scons</scons_output_command>
|
||
|
</scons_output>
|
||
|
|
||
|
<para>
|
||
|
|
||
|
Notice that &SCons; built the &goodbye; program first,
|
||
|
even though the "reading &SConscript;" output
|
||
|
shows that we called <function>Program('hello.c')</function>
|
||
|
first in the &SConstruct; file.
|
||
|
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
|
||
|
Notice also that &SCons; was able to infer a lot of information
|
||
|
from the two &Program; calls. Because
|
||
|
&hello_c; and <filename>goodbye.c</filename>
|
||
|
were recognized as C-language source files, it knew to build
|
||
|
the intermediate target files &hello_o; and &goodbye_o;
|
||
|
and the final files &hello; and &goodbye;
|
||
|
It was not necessary to program &scons; beyond just calling &Program;.
|
||
|
|
||
|
</para>
|
||
|
|
||
|
</section>
|
||
|
|
||
|
</section>
|
||
|
|
||
|
<section>
|
||
|
<title>Making the &SCons; Output Less Verbose</title>
|
||
|
|
||
|
<para>
|
||
|
|
||
|
You've already seen how &SCons; prints
|
||
|
some messages about what it's doing,
|
||
|
surrounding the actual commands used to build the software:
|
||
|
|
||
|
</para>
|
||
|
|
||
|
<scons_output example="simple_ex1" os="win32" suffix="3">
|
||
|
<scons_output_command>scons</scons_output_command>
|
||
|
</scons_output>
|
||
|
|
||
|
<para>
|
||
|
|
||
|
These messages emphasize the
|
||
|
order in which &SCons; does its work:
|
||
|
all of the configuration files
|
||
|
(generically referred to as &SConscript; files)
|
||
|
are read and executed first,
|
||
|
and only then are the target files built.
|
||
|
Among other benefits, these messages help to distinguish between
|
||
|
errors that occur while the configuration files are read,
|
||
|
and errors that occur while targets are being built.
|
||
|
|
||
|
</para>
|
||
|
|
||
|
<para>
|
||
|
|
||
|
One drawback, of course, is that these messages clutter the output.
|
||
|
Fortunately, they're easily disabled by using
|
||
|
the &Q; option when invoking &SCons;:
|
||
|
|
||
|
</para>
|
||
|
|
||
|
<scons_output example="simple_ex1" os="win32" suffix="4">
|
||
|
<scons_output_command>scons -Q</scons_output_command>
|
||
|
</scons_output>
|
||
|
|
||
|
<para>
|
||
|
|
||
|
Because we want this User's Guide to focus
|
||
|
on what &SCons; is actually doing,
|
||
|
we're going to use the &Q; option
|
||
|
to remove these messages from the
|
||
|
output of all the remaining examples in this Guide.
|
||
|
|
||
|
</para>
|
||
|
|
||
|
</section>
|
||
|
|
||
|
</chapter>
|