summaryrefslogtreecommitdiff
path: root/doc/user/less-simple.in
diff options
context:
space:
mode:
Diffstat (limited to 'doc/user/less-simple.in')
-rw-r--r--doc/user/less-simple.in623
1 files changed, 0 insertions, 623 deletions
diff --git a/doc/user/less-simple.in b/doc/user/less-simple.in
deleted file mode 100644
index f3c251f..0000000
--- a/doc/user/less-simple.in
+++ /dev/null
@@ -1,623 +0,0 @@
-<!--
-
- Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 The SCons Foundation
-
- 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>Specifying the Name of the Target (Output) File</title>
-
- <para>
-
- You've seen that when you call the &b-link-Program; builder method,
- it builds the resulting program with the same
- base name as the source file.
- That is, the following call to build an
- executable program from the &hello_c; source file
- will build an executable program named &hello; on POSIX systems,
- and an executable program named &hello_exe; on Windows systems:
-
- </para>
-
- <programlisting>
- Program('hello.c')
- </programlisting>
-
- <para>
-
- If you want to build a program with
- a different name than the base of the source file name,
- you simply put the target file name
- to the left of the source file name:
-
- </para>
-
- <scons_example name="target">
- <file name="SConstruct" printme="1">
- Program('new_hello', 'hello.c')
- </file>
- <file name="hello.c">
- int main() { printf("Hello, world!\n"); }
- </file>
- </scons_example>
-
- <para>
-
- (&SCons; requires the target file name first,
- followed by the source file name,
- so that the order mimics that of an
- assignment statement in most programming languages,
- including Python:
- <literal>"program = source files"</literal>.)
-
- </para>
-
- <para>
-
- Now &SCons; will build an executable program
- named &new_hello; when run on a POSIX system:
-
- </para>
-
- <scons_output example="target" os="posix">
- <scons_output_command>scons -Q</scons_output_command>
- </scons_output>
-
- <para>
-
- And &SCons; will build an executable program
- named &new_hello_exe; when run on a Windows system:
-
- </para>
-
- <scons_output example="target" os="win32">
- <scons_output_command>scons -Q</scons_output_command>
- </scons_output>
-
- </section>
-
- <section>
- <title>Compiling Multiple Source Files</title>
-
- <para>
-
- You've just seen how to configure &SCons;
- to compile a program from a single source file.
- It's more common, of course,
- that you'll need to build a program from
- many input source files, not just one.
- To do this, you need to put the
- source files in a Python list
- (enclosed in square brackets),
- like so:
-
- </para>
-
- <scons_example name="ex2">
- <file name="SConstruct" printme="1">
- Program(['prog.c', 'file1.c', 'file2.c'])
- </file>
- <file name="prog.c">
- int main() { printf("prog.c\n"); }
- </file>
- <file name="file1.c">
- void file1() { printf("file1.c\n"); }
- </file>
- <file name="file2.c">
- void file2() { printf("file2.c\n"); }
- </file>
- </scons_example>
-
- <para>
-
- A build of the above example would look like:
-
- </para>
-
- <scons_output example="ex2">
- <scons_output_command>scons -Q</scons_output_command>
- </scons_output>
-
- <para>
-
- Notice that &SCons;
- deduces the output program name
- from the first source file specified
- in the list--that is,
- because the first source file was &prog_c;,
- &SCons; will name the resulting program &prog;
- (or &prog_exe; on a Windows system).
- If you want to specify a different program name,
- then (as we've seen in the previous section)
- you slide the list of source files
- over to the right
- to make room for the output program file name.
- (&SCons; puts the output file name to the left
- of the source file names
- so that the order mimics that of an
- assignment statement: "program = source files".)
- This makes our example:
-
- </para>
-
- <scons_example name="ex3">
- <file name="SConstruct" printme="1">
- Program('program', ['prog.c', 'file1.c', 'file2.c'])
- </file>
- <file name="prog.c">
- int main() { printf("prog.c\n"); }
- </file>
- <file name="file1.c">
- void file1() { printf("file1.c\n"); }
- </file>
- <file name="file2.c">
- void file2() { printf("file2.c\n"); }
- </file>
- </scons_example>
-
- <para>
-
- On Linux, a build of this example would look like:
-
- </para>
-
- <scons_output example="ex3" os="posix">
- <scons_output_command>scons -Q</scons_output_command>
- </scons_output>
-
- <para>
-
- Or on Windows:
-
- </para>
-
- <scons_output example="ex3" os="win32">
- <scons_output_command>scons -Q</scons_output_command>
- </scons_output>
-
- </section>
-
- <section>
- <title>Making a list of files with &Glob;</title>
-
- <para>
-
- You can also use the &Glob; function to find all files matching a
- certain template, using the standard shell pattern matching
- characters <literal>*</literal>, <literal>?</literal>
- and <literal>[abc]</literal> to match any of
- <literal>a</literal>, <literal>b</literal> or <literal>c</literal>.
- <literal>[!abc]</literal> is also supported,
- to match any character <emphasis>except</emphasis>
- <literal>a</literal>, <literal>b</literal> or <literal>c</literal>.
- This makes many multi-source-file builds quite easy:
-
- </para>
-
- <sconstruct>
- Program('program', Glob('*.c'))
- </sconstruct>
-
- <para>
-
- 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>
-
- </section>
-
- <section>
- <title>Specifying Single Files Vs. Lists of Files</title>
-
- <para>
-
- We've now shown you two ways to specify
- the source for a program,
- one with a list of files:
-
- </para>
-
- <sconstruct>
- Program('hello', ['file1.c', 'file2.c'])
- </sconstruct>
-
- <para>
-
- And one with a single file:
-
- </para>
-
- <sconstruct>
- Program('hello', 'hello.c')
- </sconstruct>
-
- <para>
-
- You could actually put a single file name in a list, too,
- which you might prefer just for the sake of consistency:
-
- </para>
-
- <sconstruct>
- Program('hello', ['hello.c'])
- </sconstruct>
-
- <para>
-
- &SCons; functions will accept a single file name in either form.
- In fact, internally, &SCons; treats all input as lists of files,
- but allows you to omit the square brackets
- to cut down a little on the typing
- when there's only a single file name.
-
- </para>
-
- <important>
-
- <para>
-
- Although &SCons; functions
- are forgiving about whether or not you
- use a string vs. a list for a single file name,
- Python itself is more strict about
- treating lists and strings differently.
- So where &SCons; allows either
- a string or list:
-
- </para>
-
- <sconstruct>
- # The following two calls both work correctly:
- Program('program1', 'program1.c')
- Program('program2', ['program2.c'])
- </sconstruct>
-
- <para>
-
- Trying to do "Python things" that mix strings and
- lists will cause errors or lead to incorrect results:
-
- </para>
-
- <sconstruct>
- common_sources = ['file1.c', 'file2.c']
-
- # THE FOLLOWING IS INCORRECT AND GENERATES A PYTHON ERROR
- # BECAUSE IT TRIES TO ADD A STRING TO A LIST:
- Program('program1', common_sources + 'program1.c')
-
- # The following works correctly, because it's adding two
- # lists together to make another list.
- Program('program2', common_sources + ['program2.c'])
- </sconstruct>
-
- </important>
-
- </section>
-
- <section>
- <title>Making Lists of Files Easier to Read</title>
-
- <para>
-
- One drawback to the use of a Python list
- for source files is that
- each file name must be enclosed in quotes
- (either single quotes or double quotes).
- This can get cumbersome and difficult to read
- when the list of file names is long.
- Fortunately, &SCons; and Python provide a number of ways
- to make sure that
- the &SConstruct; file stays easy to read.
-
- </para>
-
- <para>
-
- To make long lists of file names
- easier to deal with, &SCons; provides a
- &Split; function
- that takes a quoted list of file names,
- with the names separated by spaces or other white-space characters,
- and turns it into a list of separate file names.
- Using the &Split; function turns the
- previous example into:
-
- </para>
-
- <programlisting>
- Program('program', Split('main.c file1.c file2.c'))
- </programlisting>
-
- <para>
-
- (If you're already familiar with Python,
- you'll have realized that this is similar to the
- <function>split()</function> method
- in the Python standard <function>string</function> module.
- Unlike the <function>split()</function> member function of strings,
- however, the &Split; function
- does not require a string as input
- and will wrap up a single non-string object in a list,
- or return its argument untouched if it's already a list.
- This comes in handy as a way to make sure
- arbitrary values can be passed to &SCons; functions
- without having to check the type of the variable by hand.)
-
- </para>
-
- <para>
-
- Putting the call to the &Split; function
- inside the &b-Program; call
- can also be a little unwieldy.
- A more readable alternative is to
- assign the output from the &Split; call
- to a variable name,
- and then use the variable when calling the
- &b-Program; function:
-
- </para>
-
- <programlisting>
- src_files = Split('main.c file1.c file2.c')
- Program('program', src_files)
- </programlisting>
-
- <para>
-
- Lastly, the &Split; function
- doesn't care how much white space separates
- the file names in the quoted string.
- This allows you to create lists of file
- names that span multiple lines,
- which often makes for easier editing:
-
- </para>
-
- <programlisting>
- src_files = Split("""main.c
- file1.c
- file2.c""")
- Program('program', src_files)
- </programlisting>
-
- <para>
-
- (Note in this example that we used
- the Python "triple-quote" syntax,
- which allows a string to contain
- multiple lines.
- The three quotes can be either
- single or double quotes.)
-
- </para>
-
- </section>
-
- <section>
- <title>Keyword Arguments</title>
-
- <para>
-
- &SCons; also allows you to identify
- the output file and input source files
- using Python keyword arguments.
- The output file is known as the
- <emphasis>target</emphasis>,
- and the source file(s) are known (logically enough) as the
- <emphasis>source</emphasis>.
- The Python syntax for this is:
-
- </para>
-
- <programlisting>
- src_files = Split('main.c file1.c file2.c')
- Program(target = 'program', source = src_files)
- </programlisting>
-
- <para>
-
- Because the keywords explicitly identify
- what each argument is,
- you can actually reverse the order if you prefer:
-
- </para>
-
- <programlisting>
- src_files = Split('main.c file1.c file2.c')
- Program(source = src_files, target = 'program')
- </programlisting>
-
- <para>
-
- Whether or not you choose to use keyword arguments
- to identify the target and source files,
- and the order in which you specify them
- when using keywords,
- are purely personal choices;
- &SCons; functions the same regardless.
-
- </para>
-
- </section>
-
- <section>
- <title>Compiling Multiple Programs</title>
-
- <para>
-
- In order to compile multiple programs
- within the same &SConstruct; file,
- simply call the &Program; method
- multiple times,
- once for each program you need to build:
-
- </para>
-
- <scons_example name="ex4">
- <file name="SConstruct" printme="1">
- Program('foo.c')
- Program('bar', ['bar1.c', 'bar2.c'])
- </file>
- <file name="foo.c">
- int main() { printf("foo.c\n"); }
- </file>
- <file name="bar1.c">
- int main() { printf("bar1.c\n"); }
- </file>
- <file name="bar2.c">
- void bar2() { printf("bar2.c\n"); }
- </file>
- </scons_example>
-
- <para>
-
- &SCons; would then build the programs as follows:
-
- </para>
-
- <scons_output example="ex4">
- <scons_output_command>scons -Q</scons_output_command>
- </scons_output>
-
- <para>
-
- Notice that &SCons; does not necessarily build the
- programs in the same order in which you specify
- them in the &SConstruct; file.
- &SCons; does, however, recognize that
- the individual object files must be built
- before the resulting program can be built.
- We'll discuss this in greater detail in
- the "Dependencies" section, below.
-
- </para>
-
- </section>
-
- <section>
- <title>Sharing Source Files Between Multiple Programs</title>
-
- <para>
-
- It's common to re-use code by sharing source files
- between multiple programs.
- One way to do this is to create a library
- from the common source files,
- which can then be linked into resulting programs.
- (Creating libraries is discussed in
- <xref linkend="chap-libraries"></xref>, below.)
-
- </para>
-
- <para>
-
- A more straightforward, but perhaps less convenient,
- way to share source files between multiple programs
- is simply to include the common files
- in the lists of source files for each program:
-
- </para>
-
- <scons_example name="ex5">
- <file name="SConstruct" printme="1">
- Program(Split('foo.c common1.c common2.c'))
- Program('bar', Split('bar1.c bar2.c common1.c common2.c'))
- </file>
- <file name="foo.c">
- int main() { printf("foo.c\n"); }
- </file>
- <file name="bar1.c">
- int main() { printf("bar1.c\n"); }
- </file>
- <file name="bar2.c">
- int bar2() { printf("bar2.c\n"); }
- </file>
- <file name="common1.c">
- void common1() { printf("common1.c\n"); }
- </file>
- <file name="common2.c">
- void common22() { printf("common2.c\n"); }
- </file>
- </scons_example>
-
- <para>
-
- &SCons; recognizes that the object files for
- the &common1_c; and &common2_c; source files
- 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>
-
- <scons_output example="ex5">
- <scons_output_command>scons -Q</scons_output_command>
- </scons_output>
-
- <para>
-
- If two or more programs
- share a lot of common source files,
- repeating the common files in the list for each program
- can be a maintenance problem when you need to change the
- list of common files.
- You can simplify this by creating a separate Python list
- to hold the common file names,
- and concatenating it with other lists
- using the Python &plus; operator:
-
- </para>
-
- <programlisting>
- common = ['common1.c', 'common2.c']
- foo_files = ['foo.c'] + common
- bar_files = ['bar1.c', 'bar2.c'] + common
- Program('foo', foo_files)
- Program('bar', bar_files)
- </programlisting>
-
- <para>
-
- This is functionally equivalent to the previous example.
-
- </para>
-
- </section>