Expanded SCons.Scanner.LaTeX.comment_re to not break on \%
[scons.git] / doc / user / less-simple.in
1 <!--
2
3   __COPYRIGHT__
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   In this chapter,
29   you will see several examples of
30   very simple build configurations using &SCons;,
31   which will demonstrate how easy
32   it is to use &SCons; to
33   build programs from several different programming languages
34   on different types of systems.
35
36   </para>
37
38   <section>
39   <title>Specifying the Name of the Target (Output) File</title>
40
41     <para>
42
43     You've seen that when you call the &b-link-Program; builder method,
44     it builds the resulting program with the same
45     base name as the source file.
46     That is, the following call to build an
47     executable program from the &hello_c; source file
48     will build an executable program named &hello; on POSIX systems,
49     and an executable program named &hello_exe; on Windows systems:
50
51     </para>
52
53     <programlisting>
54        Program('hello.c')
55     </programlisting>
56
57     <para>
58
59     If you want to build a program with
60     a different name than the base of the source file name,
61     you simply put the target file name
62     to the left of the source file name:
63
64     </para>
65
66     <scons_example name="target">
67        <file name="SConstruct" printme="1">
68        Program('new_hello', 'hello.c')
69        </file>
70        <file name="hello.c">
71        int main() { printf("Hello, world!\n"); }
72        </file>
73     </scons_example>
74
75     <para>
76
77     (&SCons; requires the target file name first,
78     followed by the source file name,
79     so that the order mimics that of an
80     assignment statement in most programming languages,
81     including Python:
82     <literal>"program = source files"</literal>.)
83
84     </para>
85
86     <para>
87
88     Now &SCons; will build an executable program
89     named &new_hello; when run on a POSIX system:
90
91     </para>
92
93     <scons_output example="target" os="posix">
94        <scons_output_command>scons -Q</scons_output_command>
95     </scons_output>
96
97     <para>
98
99     And &SCons; will build an executable program
100     named &new_hello_exe; when run on a Windows system:
101
102     </para>
103
104     <scons_output example="target" os="win32">
105        <scons_output_command>scons -Q</scons_output_command>
106     </scons_output>
107
108   </section>
109
110   <section>
111   <title>Compiling Multiple Source Files</title>
112
113     <para>
114
115     You've just seen how to configure &SCons;
116     to compile a program from a single source file.
117     It's more common, of course,
118     that you'll need to build a program from
119     many input source files, not just one.
120     To do this, you need to put the
121     source files in a Python list
122     (enclosed in square brackets),
123     like so:
124
125     </para>
126
127     <scons_example name="ex2">
128        <file name="SConstruct" printme="1">
129        Program(['prog.c', 'file1.c', 'file2.c'])
130        </file>
131        <file name="prog.c">
132        int main() { printf("prog.c\n"); }
133        </file>
134        <file name="file1.c">
135        void file1() { printf("file1.c\n"); }
136        </file>
137        <file name="file2.c">
138        void file2() { printf("file2.c\n"); }
139        </file>
140     </scons_example>
141
142     <para>
143
144     A build of the above example would look like:
145
146     </para>
147
148     <scons_output example="ex2">
149        <scons_output_command>scons -Q</scons_output_command>
150     </scons_output>
151
152     <para>
153
154     Notice that &SCons;
155     deduces the output program name
156     from the first source file specified
157     in the list--that is,
158     because the first source file was &prog_c;,
159     &SCons; will name the resulting program &prog;
160     (or &prog_exe; on a Windows system).
161     If you want to specify a different program name,
162     then (as we've seen in the previous section)
163     you slide the list of source files
164     over to the right
165     to make room for the output program file name.
166     (&SCons; puts the output file name to the left
167     of the source file names
168     so that the order mimics that of an
169     assignment statement:  "program = source files".)
170     This makes our example:
171
172     </para>
173
174     <scons_example name="ex3">
175        <file name="SConstruct" printme="1">
176        Program('program', ['prog.c', 'file1.c', 'file2.c'])
177        </file>
178        <file name="prog.c">
179        int main() { printf("prog.c\n"); }
180        </file>
181        <file name="file1.c">
182        void file1() { printf("file1.c\n"); }
183        </file>
184        <file name="file2.c">
185        void file2() { printf("file2.c\n"); }
186        </file>
187     </scons_example>
188
189     <para>
190
191     On Linux, a build of this example would look like:
192
193     </para>
194
195     <scons_output example="ex3" os="posix">
196        <scons_output_command>scons -Q</scons_output_command>
197     </scons_output>
198
199     <para>
200
201     Or on Windows:
202
203     </para>
204
205     <scons_output example="ex3" os="win32">
206        <scons_output_command>scons -Q</scons_output_command>
207     </scons_output>
208
209   </section>
210
211   <section>
212   <title>Making a list of files with &Glob;</title>
213
214     <para>
215
216     You can also use the &Glob; function to find all files matching a
217     certain template, using the standard shell pattern matching
218     characters <literal>*</literal>, <literal>?</literal>
219     and <literal>[abc]</literal> to match any of
220     <literal>a</literal>, <literal>b</literal> or <literal>c</literal>.
221     <literal>[!abc]</literal> is also supported,
222     to match any character <emphasis>except</emphasis>
223     <literal>a</literal>, <literal>b</literal> or <literal>c</literal>.
224     This makes many multi-source-file builds quite easy:
225
226     </para>
227
228     <sconstruct>
229        Program('program', Glob('*.c'))
230     </sconstruct>
231
232     <para>
233
234     The SCons man page has more details on using &Glob;
235     with variant directories
236     (see <xref linkend="chap-variants"></xref>, below)
237     and repositories
238     (see <xref linkend="chap-repositories"></xref>, below),
239     and returning strings rather than Nodes.
240
241     </para>
242
243   </section>
244
245   <section>
246   <title>Specifying Single Files Vs. Lists of Files</title>
247
248     <para>
249
250     We've now shown you two ways to specify
251     the source for a program,
252     one with a list of files:
253
254     </para>
255
256     <sconstruct>
257        Program('hello', ['file1.c', 'file2.c'])
258     </sconstruct>
259
260     <para>
261
262     And one with a single file:
263
264     </para>
265
266     <sconstruct>
267        Program('hello', 'hello.c')
268     </sconstruct>
269
270     <para>
271
272     You could actually put a single file name in a list, too,
273     which you might prefer just for the sake of consistency:
274
275     </para>
276
277     <sconstruct>
278        Program('hello', ['hello.c'])
279     </sconstruct>
280
281     <para>
282
283     &SCons; functions will accept a single file name in either form.
284     In fact, internally, &SCons; treats all input as lists of files,
285     but allows you to omit the square brackets
286     to cut down a little on the typing
287     when there's only a single file name.
288
289     </para>
290
291     <important>
292     
293     <para>
294
295     Although &SCons; functions
296     are forgiving about whether or not you
297     use a string vs. a list for a single file name,
298     Python itself is more strict about
299     treating lists and strings differently.
300     So where &SCons; allows either
301     a string or list:
302
303     </para>
304
305     <sconstruct>
306        # The following two calls both work correctly:
307        Program('program1', 'program1.c')
308        Program('program2', ['program2.c'])
309     </sconstruct>
310
311     <para>
312
313     Trying to do "Python things" that mix strings and
314     lists will cause errors or lead to incorrect results:
315
316     </para>
317
318     <sconstruct>
319        common_sources = ['file1.c', 'file2.c']
320
321        # THE FOLLOWING IS INCORRECT AND GENERATES A PYTHON ERROR
322        # BECAUSE IT TRIES TO ADD A STRING TO A LIST:
323        Program('program1', common_sources + 'program1.c')
324
325        # The following works correctly, because it's adding two
326        # lists together to make another list.
327        Program('program2', common_sources + ['program2.c'])
328     </sconstruct>
329
330     </important>
331
332   </section>
333
334   <section>
335   <title>Making Lists of Files Easier to Read</title>
336
337     <para>
338
339     One drawback to the use of a Python list
340     for source files is that 
341     each file name must be enclosed in quotes
342     (either single quotes or double quotes).
343     This can get cumbersome and difficult to read
344     when the list of file names is long.
345     Fortunately, &SCons; and Python provide a number of ways
346     to make sure that
347     the &SConstruct; file stays easy to read.
348
349     </para>
350
351     <para>
352
353     To make long lists of file names
354     easier to deal with, &SCons; provides a
355     &Split; function
356     that takes a quoted list of file names,
357     with the names separated by spaces or other white-space characters,
358     and turns it into a list of separate file names.
359     Using the &Split; function turns the
360     previous example into:
361
362     </para>
363
364     <programlisting>
365        Program('program', Split('main.c file1.c file2.c'))
366     </programlisting>
367
368     <para>
369
370     (If you're already familiar with Python,
371     you'll have realized that this is similar to the
372     <function>split()</function> method
373     in the Python standard <function>string</function> module.
374     Unlike the <function>split()</function> member function of strings,
375     however, the &Split; function
376     does not require a string as input
377     and will wrap up a single non-string object in a list,
378     or return its argument untouched if it's already a list.
379     This comes in handy as a way to make sure
380     arbitrary values can be passed to &SCons; functions
381     without having to check the type of the variable by hand.)
382
383     </para>
384
385     <para>
386
387     Putting the call to the &Split; function
388     inside the &b-Program; call
389     can also be a little unwieldy.
390     A more readable alternative is to
391     assign the output from the &Split; call
392     to a variable name,
393     and then use the variable when calling the
394     &b-Program; function:
395
396     </para>
397
398     <programlisting>
399        src_files = Split('main.c file1.c file2.c')
400        Program('program', src_files)
401     </programlisting>
402
403     <para>
404
405     Lastly, the &Split; function
406     doesn't care how much white space separates
407     the file names in the quoted string.
408     This allows you to create lists of file
409     names that span multiple lines,
410     which often makes for easier editing:
411
412     </para>
413
414     <programlisting>
415        src_files = Split("""main.c
416                             file1.c
417                             file2.c""")
418        Program('program', src_files)
419     </programlisting>
420
421     <para>
422
423     (Note in this example that we used
424     the Python "triple-quote" syntax,
425     which allows a string to contain
426     multiple lines.
427     The three quotes can be either
428     single or double quotes.)
429
430     </para>
431
432   </section>
433
434   <section>
435   <title>Keyword Arguments</title>
436
437     <para>
438
439     &SCons; also allows you to identify
440     the output file and input source files
441     using Python keyword arguments.
442     The output file is known as the
443     <emphasis>target</emphasis>,
444     and the source file(s) are known (logically enough) as the
445     <emphasis>source</emphasis>.
446     The Python syntax for this is:
447
448     </para>
449
450     <programlisting>
451        src_files = Split('main.c file1.c file2.c')
452        Program(target = 'program', source = src_files)
453     </programlisting>
454
455     <para>
456
457     Because the keywords explicitly identify
458     what each argument is,
459     you can actually reverse the order if you prefer:
460
461     </para>
462
463     <programlisting>
464        src_files = Split('main.c file1.c file2.c')
465        Program(source = src_files, target = 'program')
466     </programlisting>
467
468     <para>
469
470     Whether or not you choose to use keyword arguments
471     to identify the target and source files,
472     and the order in which you specify them
473     when using keywords,
474     are purely personal choices;
475     &SCons; functions the same regardless.
476
477     </para>
478
479   </section>
480
481   <section>
482   <title>Compiling Multiple Programs</title>
483
484     <para>
485
486     In order to compile multiple programs
487     within the same &SConstruct; file,
488     simply call the &Program; method
489     multiple times,
490     once for each program you need to build:
491
492     </para>
493
494     <scons_example name="ex4">
495        <file name="SConstruct" printme="1">
496        Program('foo.c')
497        Program('bar', ['bar1.c', 'bar2.c'])
498        </file>
499        <file name="foo.c">
500        int main() { printf("foo.c\n"); }
501        </file>
502        <file name="bar1.c">
503        int main() { printf("bar1.c\n"); }
504        </file>
505        <file name="bar2.c">
506        void bar2() { printf("bar2.c\n"); }
507        </file>
508     </scons_example>
509
510     <para>
511
512     &SCons; would then build the programs as follows:
513
514     </para>
515
516     <scons_output example="ex4">
517        <scons_output_command>scons -Q</scons_output_command>
518     </scons_output>
519
520     <para>
521
522     Notice that &SCons; does not necessarily build the
523     programs in the same order in which you specify
524     them in the &SConstruct; file.
525     &SCons; does, however, recognize that
526     the individual object files must be built
527     before the resulting program can be built.
528     We'll discuss this in greater detail in
529     the "Dependencies" section, below.
530
531     </para>
532
533   </section>
534
535   <section>
536   <title>Sharing Source Files Between Multiple Programs</title>
537
538     <para>
539
540     It's common to re-use code by sharing source files
541     between multiple programs.
542     One way to do this is to create a library
543     from the common source files,
544     which can then be linked into resulting programs.
545     (Creating libraries is discussed in
546     <xref linkend="chap-libraries"></xref>, below.)
547
548     </para>
549
550     <para>
551
552     A more straightforward, but perhaps less convenient,
553     way to share source files between multiple programs
554     is simply to include the common files
555     in the lists of source files for each program:
556
557     </para>
558
559     <scons_example name="ex5">
560        <file name="SConstruct" printme="1">
561        Program(Split('foo.c common1.c common2.c'))
562        Program('bar', Split('bar1.c bar2.c common1.c common2.c'))
563        </file>
564        <file name="foo.c">
565        int main() { printf("foo.c\n"); }
566        </file>
567        <file name="bar1.c">
568        int main() { printf("bar1.c\n"); }
569        </file>
570        <file name="bar2.c">
571        int bar2() { printf("bar2.c\n"); }
572        </file>
573        <file name="common1.c">
574        void common1() { printf("common1.c\n"); }
575        </file>
576        <file name="common2.c">
577        void common22() { printf("common2.c\n"); }
578        </file>
579     </scons_example>
580
581     <para>
582
583     &SCons; recognizes that the object files for
584     the &common1_c; and &common2_c; source files
585     each need to be built only once,
586     even though the resulting object files are
587     each linked in to both of the resulting executable programs:
588
589     </para>
590
591     <scons_output example="ex5">
592        <scons_output_command>scons -Q</scons_output_command>
593     </scons_output>
594
595     <para>
596
597     If two or more programs
598     share a lot of common source files,
599     repeating the common files in the list for each program
600     can be a maintenance problem when you need to change the
601     list of common files.
602     You can simplify this by creating a separate Python list
603     to hold the common file names,
604     and concatenating it with other lists
605     using the Python &plus; operator:
606
607     </para>
608
609     <programlisting>
610        common = ['common1.c', 'common2.c']
611        foo_files = ['foo.c'] + common
612        bar_files = ['bar1.c', 'bar2.c'] + common
613        Program('foo', foo_files)
614        Program('bar', bar_files)
615     </programlisting>
616
617     <para>
618
619     This is functionally equivalent to the previous example.
620
621     </para>
622
623   </section>