More User's Guide updates.
[scons.git] / doc / user / simple.sgml
1 <!--
2
3   Copyright (c) 2001, 2002, 2003 Steven Knight
4
5   Permission is hereby granted, free of charge, to any person obtaining
6   a copy of this software and associated documentation files (the
7   "Software"), to deal in the Software without restriction, including
8   without limitation the rights to use, copy, modify, merge, publish,
9   distribute, sublicense, and/or sell copies of the Software, and to
10   permit persons to whom the Software is furnished to do so, subject to
11   the following conditions:
12
13   The above copyright notice and this permission notice shall be included
14   in all copies or substantial portions of the Software.
15
16   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
17   KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
18   WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20   LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21   OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22   WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
24 -->
25
26 <!--
27
28 =head2 Perl scripts
29
30 Cons is Perl-based. That is, Cons scripts F<Conscript> and F<Construct>
31 files, the equivalent to F<Makefile> or F<makefile> are all written in
32 Perl. This provides an immediate benefit: the language for writing scripts
33 is a familiar one. Even if you don't happen to be a Perl programmer, it
34 helps to know that Perl is basically just a simple declarative language,
35 with a well-defined flow of control, and familiar semantics. It has
36 variables that behave basically the way you would expect them to,
37 subroutines, flow of control, and so on. There is no special syntax
38 introduced for Cons. The use of Perl as a scripting language simplifies
39 the task of expressing the appropriate solution to the often complex
40 requirements of a build.
41
42 -->
43
44  <para>
45
46  Here's how to build the famous "Hello, World!" example using &SCons;.
47
48  </para>
49
50  <programlisting>
51     int
52     main()
53     {
54         printf("Hello, world!\n");
55     }
56  </programlisting>
57
58  <para>
59
60  Enter the following into a file name &SConstruct;:
61
62  </para>
63
64  <programlisting>
65     env = Environment()
66     env.Program('hello.c')
67  </programlisting>
68
69  <para>
70
71  That's it.  Now run the &scons; command to build the program.
72  On a POSIX-compliant system like Linux or UNIX,
73  you'll see something like:
74
75  </para>
76
77  <literallayout>
78     % <userinput>scons</userinput>
79     cc -c hello.c -o hello.o
80     cc -o hello hello.o
81  </literallayout>
82
83  <para>
84
85  On a Windows system with the Microsoft Visual C++ compiler,
86  you'll see something like:
87
88  </para>
89
90  <literallayout>
91     C:\><userinput>scons</userinput>
92     cl /Fohello.obj hello.c
93     link /Fohello.exe hello.obj
94  </literallayout>
95
96  <para>
97
98  First, notice that you only need
99  to specify the name of the source file,
100  and that &SCons; deduces the names of
101  the object and executable files
102  correctly from the source file.
103
104  </para>
105
106  <para>
107
108  Second, notice that the same input &SConstruct; file,
109  without any changes,
110  generates the correct output file names on both systems:
111  <filename>hello.o</filename> and <filename>hello</filename>
112  on POSIX systems,
113  <filename>hello.obj</filename> and <filename>hello.exe</filename>
114  on Windows systems.
115  This is a simple example of how easy it is to
116  use &SCons; to write portable software builds.
117
118  </para>
119
120  <para>
121
122  (Note that we won't provide duplicate side-by-side
123  POSIX and Windows output for the 
124  rest of the examples in this guide;
125  just keep in mind that, unless otherwise specified,
126  any of the examples should work equally well on both types of systems.)
127
128  </para>
129
130  <section>
131  <title>The &SConstruct; File</title>
132
133    <para>
134
135    If you're used to build systems like &Make;
136    you've already figured out that the &SConstruct; file
137    is the &SCons; equivalent of a &Makefile;.
138    That is, the &SConstruct; file is the input file
139    that &SCons; reads to control the build.
140
141    </para>
142
143    <para>
144
145    What may not be obvious, though, is that
146    there's an important difference between
147    an &SConstruct; file and a &Makefile:
148    the &SConstruct; file is actually a Python script.
149    If you're not already familiar with Python, don't worry;
150    Python is very easy to learn,
151    and this User's Guide will introduce you step-by-step
152    to the relatively small amount of Python you'll
153    need to know to be able to use &SCons; effectively.
154
155    </para>
156
157    <para>
158
159    One aspect of using Python as the
160    scripting language is that you can put comments
161    in your &SConstruct; file using Python's commenting convention;
162    that is, everything between a '#' and the end of the line
163    will be ignored:
164
165    </para>
166
167    <programlisting>
168       env = Environment()    # Create an environment.
169       # Arrange to build the "hello" program.
170       env.Program('hello.c')
171    </programlisting>
172
173    <para>
174
175    You'll see throughout the remainder of this Guide
176    that being able to use the power of a
177    real scripting language
178    can greatly simplify the solutions
179    to complex requirements of real-world builds.
180
181    </para>
182
183  </section>
184
185  <section>
186  <title>Compiling Multiple Source Files</title>
187
188    <para>
189
190    It's more common, of course,
191    that you'll need to build a program from
192    not just one, but many input source files.
193    To do this, you need to put the
194    source files in a Python list
195    (enclosed in square brackets),
196    and slide that list over to to the right
197    to make room for the output program file name.
198    For example:
199
200    </para>
201
202    <programlisting>
203       env = Environment()
204       env.Program('program', ['main.c', 'file1.c', 'file2.'])
205    </programlisting>
206
207    <para>
208
209    (&SCons; puts the output file name to the left
210    of the source file names
211    so that the order mimics that of an
212    assignment statement:  "program = source files".)
213
214    </para>
215
216    <para>
217
218    A build of the above example would look:
219
220    </para>
221
222    <literallayout>
223       % <userinput>scons</userinput>
224       cc -c file1.c -o file1.o
225       cc -c file2.c -o file2.o
226       cc -c main.c -o main.o
227       cc -o program main.o file1.o file2.o
228    </literallayout>
229
230    <!--
231
232    XXX DO WE NEED WINDOWS EXAMPLE OUTPUT HERE?
233
234    </para>
235
236    Or on Windows:
237
238    </para>
239
240    <literallayout>
241       C:\><userinput>scons</userinput>
242       cl /Fofile1.obj file1.c
243       cl /Fofile2.obj file2.c
244       cl /Fomain.obj main.c
245       link /Foprogram.exe main.obj file1.obj file2.obj
246    </literallayout>
247
248    -->
249
250  </section>
251
252  <section>
253  <title>Keeping &SConstruct; Files Easy to Read</title>
254
255    <para>
256
257    One drawback to the use of a Python list
258    for source files is that 
259    each file name must be enclosed in quotes
260    (either single quotes or double quotes).
261    This can get cumbersome and difficult to read
262    when the list of file names is long.
263    Fortunately, there are a number of things
264    we can do to make sure that
265    the &SConstruct; file stays easy to read.
266
267    </para>
268
269    <para>
270
271    To make long lists of file names
272    easier to deal with, &SCons; provides a
273    &Split; function
274    that takes a quoted list of file names,
275    with the names separated by spaces or other white-space characters,
276    and turns it into a list of separate file names.
277    Using the &Split; function turns the
278    previous example into:
279
280    </para>
281
282    <programlisting>
283       env = Environment()
284       env.Program('program', Split('main.c file1.c file2.'))
285    </programlisting>
286
287    <para>
288
289    Putting the call to the &Split; function
290    inside the <function>env.Program</function> call
291    can also be a little unwieldy.
292    A more readable alternative is to
293    assign the output from the &Split; call
294    to a variable name,
295    and then use the variable when calling the
296    <function>env.Program</function> function:
297
298    </para>
299
300    <programlisting>
301       env = Environment()
302       list = Split('main.c file1.c file2.')
303       env.Program('program', list)
304    </programlisting>
305
306    <para>
307
308    Lastly, the &Split; function
309    doesn't care how much white space separates
310    the file names in the quoted string.
311    This allows you to create lists of file
312    names that span multiple lines,
313    which often makes for easier editing:
314
315    </para>
316
317    <programlisting>
318       env = Environment()
319       list = Split('main.c
320                     file1.c
321                     file2.c')
322       env.Program('program', list)
323    </programlisting>
324
325  </section>
326
327  <section>
328  <title>Keyword Arguments</title>
329
330    <para>
331
332    &SCons; also allows you to identify
333    the output file and input source files
334    by Python keyword arguments.
335    The output file is known as the
336    <emphasis>target</emphasis>,
337    and the source file(s) are known (logically enough) as the
338    <emphasis>source</emphasis>.
339    The Python syntax for this is:
340
341    </para>
342
343    <programlisting>
344       env = Environment()
345       list = Split('main.c file1.c file2.')
346       env.Program(target = 'program', source = list)
347    </programlisting>
348
349    <para>
350
351    Whether or not you choose to use keyword arguments
352    to identify the target and source files
353    is purely a personal choice.
354
355    </para>
356
357  </section>
358
359  <section>
360  <title>Compiling Multiple Programs</title>
361
362    <para>
363
364    In order to compile multiple programs
365    within the same &SConstruct; file,
366    simply call <function>env.Program</function>
367    multiple times,
368    once for each program you need to build:
369
370    </para>
371
372    <programlisting>
373       env = Environment()
374       env.Program('foo.c')
375       env.Program('bar', ['bar1.c', 'bar2.c'])
376    </programlisting>
377
378    <para>
379
380    &SCons; would then build the programs as follows:
381
382    </para>
383
384    <literallayout>
385       % <userinput>scons</userinput>
386       cc -c bar1.c -o bar1.o
387       cc -c bar2.c -o bar2.o
388       cc -o bar bar1.o bar2.o
389       cc -c foo.c -o foo.o
390       cc -o foo foo.o
391    </literallayout>
392
393  </section>
394
395  <section>
396  <title>Sharing Source Files Between Multiple Programs</title>
397
398    <para>
399
400    XXX
401
402    </para>
403
404    <programlisting>
405       common = ['common1.c', 'common2.c']
406       env = Environment()
407       env.Program(['foo.c'] + common)
408       env.Program('bar', ['bar1.c', 'bar2.c'] + common)
409    </programlisting>
410
411    <literallayout>
412       % <userinput>scons</userinput>
413       cc -c bar1.c -o bar1.o
414       cc -c bar2.c -o bar2.o
415       cc -c common1.c -o common1.o
416       cc -c common2.c -o common2.o
417       cc -o bar bar1.o bar2.o common1.o common2.o
418       cc -c foo.c -o foo.o
419       cc -o foo foo.o common1.o common2.o
420    </literallayout>
421
422  </section>