Branch for User's Guide changes.
[scons.git] / doc / user / simple.in
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  <para>
27
28  Here's the famous "Hello, World!" program in C:
29
30  </para>
31
32  <programlisting>
33     int
34     main()
35     {
36         printf("Hello, world!\n");
37     }
38  </programlisting>
39
40  <para>
41
42  And here's how to build it using &SCons;.
43  Enter the following into a file named &SConstruct;:
44
45  </para>
46
47  <scons_example name="ex1">
48     <file name="SConstruct" printme="1">
49     env = Environment()
50     env.Program('hello.c')
51     </file>
52     <file name="hello.c">
53     int main() { printf("Hello, world!\n"); }
54     </file>
55  </scons_example>
56
57  <para>
58
59  That's it.  Now run the &scons; command to build the program.
60  On a POSIX-compliant system like Linux or UNIX,
61  you'll see something like:
62
63  </para>
64
65  <scons_output example="ex1" os="posix">
66     <command>scons</command>
67  </scons_output>
68
69  <para>
70
71  On a Windows system with the Microsoft Visual C++ compiler,
72  you'll see something like:
73
74  </para>
75
76  <scons_output example="ex1" os="win32">
77     <command>scons</command>
78  </scons_output>
79
80  <para>
81
82  First, notice that you only need
83  to specify the name of the source file,
84  and that &SCons; deduces the names of
85  the object and executable files
86  correctly from the base of the source file name.
87
88  </para>
89
90  <para>
91
92  Second, notice that the same input &SConstruct; file,
93  without any changes,
94  generates the correct output file names on both systems:
95  <filename>hello.o</filename> and <filename>hello</filename>
96  on POSIX systems,
97  <filename>hello.obj</filename> and <filename>hello.exe</filename>
98  on Windows systems.
99  This is a simple example of how &SCons;
100  makes it extremely easy to
101  write portable software builds.
102
103  </para>
104
105  <para>
106
107  (Note that we won't provide duplicate side-by-side
108  POSIX and Windows output for all of the examples in this guide;
109  just keep in mind that, unless otherwise specified,
110  any of the examples should work equally well on both types of systems.)
111
112  </para>
113
114  <section>
115  <title>The &SConstruct; File</title>
116
117    <para>
118
119    If you're used to build systems like &Make;
120    you've already figured out that the &SConstruct; file
121    is the &SCons; equivalent of a &Makefile;.
122    That is, the &SConstruct; file is the input file
123    that &SCons; reads to control the build.
124
125    </para>
126
127    <para>
128
129    There is, however, an important difference between
130    an &SConstruct; file and a &Makefile;:
131    the &SConstruct; file is actually a Python script.
132    If you're not already familiar with Python, don't worry.
133    This User's Guide will introduce you step-by-step
134    to the relatively small amount of Python you'll
135    need to know to be able to use &SCons; effectively.
136    And Python is very easy to learn.
137
138    </para>
139
140    <para>
141
142    One aspect of using Python as the
143    scripting language is that you can put comments
144    in your &SConstruct; file using Python's commenting convention;
145    that is, everything between a '#' and the end of the line
146    will be ignored:
147
148    </para>
149
150    <programlisting>
151       env = Environment()    # Create an environment.
152       # Arrange to build the "hello" program.
153       env.Program('hello.c')
154    </programlisting>
155
156    <para>
157
158    You'll see throughout the remainder of this Guide
159    that being able to use the power of a
160    real scripting language
161    can greatly simplify the solutions
162    to complex requirements of real-world builds.
163
164    </para>
165
166  </section>
167
168  <section>
169  <title>Compiling Multiple Source Files</title>
170
171    <para>
172
173    You've just seen how to configure &SCons;
174    to compile a program from a single source file.
175    It's more common, of course,
176    that you'll need to build a program from
177    many input source files, not just one.
178    To do this, you need to put the
179    source files in a Python list
180    (enclosed in square brackets),
181    like so:
182
183    </para>
184
185    <scons_example name="ex2">
186       <file name="SConstruct" printme="1">
187       env = Environment()
188       env.Program(['prog.c', 'file1.c', 'file2.c'])
189       </file>
190       <file name="prog.c">
191       int main() { printf("prog.c\n"); }
192       </file>
193       <file name="file1.c">
194       void file1() { printf("file1.c\n"); }
195       </file>
196       <file name="file2.c">
197       void file2() { printf("file2.c\n"); }
198       </file>
199    </scons_example>
200
201    <para>
202
203    A build of the above example would look like:
204
205    </para>
206
207    <scons_output example="ex2">
208       <command>scons</command>
209    </scons_output>
210
211    <para>
212
213    Notice that &SCons;
214    deduces the output program name
215    from the first source file specified
216    in the list--that is,
217    because the first source file was &prog_c;,
218    &SCons; will name the resulting program &prog;
219    (or &prog_exe; on a Windows system).
220    If you want to specify a different program name,
221    then you slide the list of source files
222    over to the right
223    to make room for the output program file name.
224    (&SCons; puts the output file name to the left
225    of the source file names
226    so that the order mimics that of an
227    assignment statement:  "program = source files".)
228    This makes our example:
229
230    </para>
231
232    <scons_example name="ex3">
233       <file name="SConstruct" printme="1">
234       env = Environment()
235       env.Program('program', ['main.c', 'file1.c', 'file2.c'])
236       </file>
237       <file name="main.c">
238       int main() { printf("prog.c\n"); }
239       </file>
240       <file name="file1.c">
241       void file1() { printf("file1.c\n"); }
242       </file>
243       <file name="file2.c">
244       void file2() { printf("file2.c\n"); }
245       </file>
246    </scons_example>
247
248    <para>
249
250    On Linux, a build of this example would look like:
251
252    </para>
253
254    <scons_output example="ex3" os="posix">
255       <command>scons</command>
256    </scons_output>
257
258    <para>
259
260    Or on Windows:
261
262    </para>
263
264    <scons_output example="ex3" os="win32">
265       <command>scons</command>
266    </scons_output>
267
268  </section>
269
270  <section>
271  <title>Keeping &SConstruct; Files Easy to Read</title>
272
273    <para>
274
275    One drawback to the use of a Python list
276    for source files is that 
277    each file name must be enclosed in quotes
278    (either single quotes or double quotes).
279    This can get cumbersome and difficult to read
280    when the list of file names is long.
281    Fortunately, &SCons; and Python provide a number of ways
282    to make sure that
283    the &SConstruct; file stays easy to read.
284
285    </para>
286
287    <para>
288
289    To make long lists of file names
290    easier to deal with, &SCons; provides a
291    &Split; function
292    that takes a quoted list of file names,
293    with the names separated by spaces or other white-space characters,
294    and turns it into a list of separate file names.
295    Using the &Split; function turns the
296    previous example into:
297
298    </para>
299
300    <programlisting>
301       env = Environment()
302       env.Program('program', Split('main.c file1.c file2.'))
303    </programlisting>
304
305    <para>
306
307    Putting the call to the &Split; function
308    inside the <function>env.Program</function> call
309    can also be a little unwieldy.
310    A more readable alternative is to
311    assign the output from the &Split; call
312    to a variable name,
313    and then use the variable when calling the
314    <function>env.Program</function> function:
315
316    </para>
317
318    <programlisting>
319       env = Environment()
320       list = Split('main.c file1.c file2.')
321       env.Program('program', list)
322    </programlisting>
323
324    <para>
325
326    Lastly, the &Split; function
327    doesn't care how much white space separates
328    the file names in the quoted string.
329    This allows you to create lists of file
330    names that span multiple lines,
331    which often makes for easier editing:
332
333    </para>
334
335    <programlisting>
336       env = Environment()
337       list = Split('main.c
338                     file1.c
339                     file2.c')
340       env.Program('program', list)
341    </programlisting>
342
343  </section>
344
345  <section>
346  <title>Keyword Arguments</title>
347
348    <para>
349
350    &SCons; also allows you to identify
351    the output file and input source files
352    using Python keyword arguments.
353    The output file is known as the
354    <emphasis>target</emphasis>,
355    and the source file(s) are known (logically enough) as the
356    <emphasis>source</emphasis>.
357    The Python syntax for this is:
358
359    </para>
360
361    <programlisting>
362       env = Environment()
363       list = Split('main.c file1.c file2.')
364       env.Program(target = 'program', source = list)
365    </programlisting>
366
367    <para>
368
369    Whether or not you choose to use keyword arguments
370    to identify the target and source files
371    is purely a personal choice;
372    &SCons; functions the same either way.
373
374    </para>
375
376  </section>
377
378  <section>
379  <title>Compiling Multiple Programs</title>
380
381    <para>
382
383    In order to compile multiple programs
384    within the same &SConstruct; file,
385    simply call the <function>env.Program</function> method
386    multiple times,
387    once for each program you need to build:
388
389    </para>
390
391    <scons_example name="ex4">
392       <file name="SConstruct" printme="1">
393       env = Environment()
394       env.Program('foo.c')
395       env.Program('bar', ['bar1.c', 'bar2.c'])
396       </file>
397       <file name="foo.c">
398       int main() { printf("foo.c\n"); }
399       </file>
400       <file name="bar1.c">
401       int main() { printf("bar1.c\n"); }
402       </file>
403       <file name="bar2.c">
404       void bar2() { printf("bar2.c\n"); }
405       </file>
406    </scons_example>
407
408    <para>
409
410    &SCons; would then build the programs as follows:
411
412    </para>
413
414    <scons_output example="ex4">
415       <command>scons</command>
416    </scons_output>
417
418    <para>
419
420    Notice that &SCons; does not necessarily build the
421    programs in the same order in which you specify
422    them in the &SConstruct; file.
423    &SCons; does, however, recognize that
424    the individual object files must be built
425    before the resulting program can be built.
426    We'll discuss this in greater detail in
427    the "Dependencies" section, below.
428
429    </para>
430
431  </section>
432
433  <section>
434  <title>Sharing Source Files Between Multiple Programs</title>
435
436    <para>
437
438    It's common to re-use code by sharing source files
439    between multiple programs.
440    One way to do this is to create a library
441    from the common source files,
442    which can then be linked into resulting programs.
443    (Creating libraries is discussed in
444    section XXX, below.)
445
446    </para>
447
448    <para>
449
450    A more straightforward, but perhaps less convenient,
451    way to share source files between multiple programs
452    is simply to include the common files
453    in the lists of source files for each program:
454
455    </para>
456
457    <scons_example name="ex5">
458       <file name="SConstruct" printme="1">
459       env = Environment()
460       env.Program(Split('foo.c common1.c common2.c'))
461       env.Program('bar', Split('bar1.c bar2.c common1.c common2.c'))
462       </file>
463       <file name="foo.c">
464       int main() { printf("foo.c\n"); }
465       </file>
466       <file name="bar1.c">
467       int main() { printf("bar1.c\n"); }
468       </file>
469       <file name="bar2.c">
470       int bar2() { printf("bar2.c\n"); }
471       </file>
472       <file name="common1.c">
473       void common1() { printf("common1.c\n"); }
474       </file>
475       <file name="common2.c">
476       void common22() { printf("common2.c\n"); }
477       </file>
478    </scons_example>
479
480    <para>
481
482    &SCons; recognizes that the object files for
483    the &common1_c; and &common2_c; source files
484    each only need to be built once,
485    even though the files are listed multiple times:
486
487    </para>
488
489    <scons_output example="ex5">
490       <command>scons</command>
491    </scons_output>
492
493    <para>
494
495    If two or more programs
496    share a lot of common source files,
497    repeating the common files in the list for each program
498    can be a maintenance problem when you need to change the
499    list of common files.
500    You can simplify this by creating a separate Python list
501    to hold the common file names,
502    and concatenating it with other lists
503    using the Python &plus; operator:
504
505    </para>
506
507    <programlisting>
508       common = ['common1.c', 'common2.c']
509       foo_files = ['foo.c'] + common
510       bar_files = ['bar1.c', 'bar2.c'] + common
511       env = Environment()
512       env.Program('foo', foo_files)
513       env.Program('bar', bar_files)
514    </programlisting>
515
516    <para>
517
518    This is functionally equivalent to the previous example.
519
520    </para>
521
522  </section>