Update items for 0.97.0d20071212.
[scons.git] / doc / user / hierarchy.xml
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 <!--
27
28
29 =head2 The Build command
30
31 By default, Cons does not change its working directory to the directory
32 containing a subsidiary F<Conscript> file it is including.  This behavior
33 can be enabled for a build by specifying, in the top-level F<Construct>
34 file:
35
36   Conscript_chdir 1;
37
38 When enabled, Cons will change to the subsidiary F<Conscript> file's
39 containing directory while reading in that file, and then change back
40 to the top-level directory once the file has been processed.
41
42 It is expected that this behavior will become the default in some future
43 version of Cons.  To prepare for this transition, builds that expect
44 Cons to remain at the top of the build while it reads in a subsidiary
45 F<Conscript> file should explicitly disable this feature as follows:
46
47   Conscript_chdir 0;
48
49 =head2 Relative, top-relative, and absolute file names
50
51 (There is another file prefix, ``!'', that is interpreted specially by
52 Cons.  See discussion of the C<Link> command, below, for details.)
53
54
55 =head2 Using modules in build scripts
56
57 You may pull modules into each F<Conscript> file using the normal Perl
58 C<use> or C<require> statements:
59
60   use English;
61   require My::Module;
62
63 Each C<use> or C<require> only affects the one F<Conscript> file in which
64 it appears.  To use a module in multiple F<Conscript> files, you must
65 put a C<use> or C<require> statement in each one that needs the module.
66
67
68 =head2 Scope of variables
69
70 The top-level F<Construct> file and all F<Conscript> files begin life in
71 a common, separate Perl package.  B<Cons> controls the symbol table for
72 the package so that, the symbol table for each script is empty, except
73 for the F<Construct> file, which gets some of the command line arguments.
74 All of the variables that are set or used, therefore, are set by the
75 script itself, not by some external script.
76
77 Variables can be explicitly B<imported> by a script from its parent
78 script. To import a variable, it must have been B<exported> by the parent
79 and initialized (otherwise an error will occur).
80
81
82 =head2 The Export command
83
84 The C<Export> command is used as in the following example:
85
86   $env = new cons();
87   $INCLUDE = "#export/include";
88   $LIB = "#export/lib";
89   Export qw( env INCLUDE LIB );
90   Build qw( util/Conscript );
91
92 The values of the simple variables mentioned in the C<Export> list will be
93 squirreled away by any subsequent C<Build> commands. The C<Export> command
94 will only export Perl B<scalar> variables, that is, variables whose name
95 begins with C<$>. Other variables, objects, etc. can be exported by
96 reference, but all scripts will refer to the same object, and this object
97 should be considered to be read-only by the subsidiary scripts and by the
98 original exporting script. It's acceptable, however, to assign a new value
99 to the exported scalar variable, that won't change the underlying variable
100 referenced. This sequence, for example, is OK:
101
102   $env = new cons();
103   Export qw( env INCLUDE LIB );
104   Build qw( util/Conscript );
105   $env = new cons(CFLAGS => '-O');
106   Build qw( other/Conscript );
107
108 It doesn't matter whether the variable is set before or after the C<Export>
109 command. The important thing is the value of the variable at the time the
110 C<Build> command is executed. This is what gets squirreled away. Any
111 subsequent C<Export> commands, by the way, invalidate the first: you must
112 mention all the variables you wish to export on each C<Export> command.
113
114
115 =head2 The Import command
116
117 Variables exported by the C<Export> command can be imported into subsidiary
118 scripts by the C<Import> command. The subsidiary script always imports
119 variables directly from the superior script. Consider this example:
120
121   Import qw( env INCLUDE );
122
123 This is only legal if the parent script exported both C<$env> and
124 C<$INCLUDE>. It also must have given each of these variables values. It is
125 OK for the subsidiary script to only import a subset of the exported
126 variables (in this example, C<$LIB>, which was exported by the previous
127 example, is not imported).
128
129 All the imported variables are automatically re-exported, so the sequence:
130
131   Import qw ( env INCLUDE );
132   Build qw ( beneath-me/Conscript );
133
134 will supply both C<$env> and C<$INCLUDE> to the subsidiary file. If only
135 C<$env> is to be exported, then the following will suffice:
136
137   Import qw ( env INCLUDE );
138   Export qw ( env );
139   Build qw ( beneath-me/Conscript );
140
141 Needless to say, the variables may be modified locally before invoking
142 C<Build> on the subsidiary script.
143
144 =head2 Build script evaluation order
145
146 The only constraint on the ordering of build scripts is that superior
147 scripts are evaluated before their inferior scripts. The top-level
148 F<Construct> file, for instance, is evaluated first, followed by any
149 inferior scripts. This is all you really need to know about the evaluation
150 order, since order is generally irrelevant. Consider the following C<Build>
151 command:
152
153   Build qw(
154         drivers/display/Conscript
155         drivers/mouse/Conscript
156         parser/Conscript
157         utilities/Conscript
158   );
159
160 We've chosen to put the script names in alphabetical order, simply because
161 that's the most convenient for maintenance purposes. Changing the order will
162 make no difference to the build.
163
164 -->
165
166   <para>
167
168   The source code for large software projects
169   rarely stays in a single directory,
170   but is nearly always divided into a
171   hierarchy of directories.
172   Organizing a large software build using &SCons;
173   involves creating a hierarchy of build scripts
174   using the &SConscript; function.
175
176   </para>
177
178   <section>
179   <title>&SConscript; Files</title>
180
181     <para>
182
183     As we've already seen,
184     the build script at the top of the tree is called &SConstruct;.
185     The top-level &SConstruct; file can
186     use the &SConscript; function to
187     include other subsidiary scripts in the build.
188     These subsidiary scripts can, in turn,
189     use the &SConscript; function
190     to include still other scripts in the build.
191     By convention, these subsidiary scripts are usually
192     named &SConscript;.
193     For example, a top-level &SConstruct; file might
194     arrange for four subsidiary scripts to be included
195     in the build as follows:
196
197     </para>
198
199     <programlisting>
200       SConscript(['drivers/display/SConscript',
201                   'drivers/mouse/SConscript',
202                   'parser/SConscript',
203                   'utilities/SConscript'])
204     </programlisting>
205
206     <para>
207
208     In this case, the &SConstruct; file
209     lists all of the &SConscript; files in the build explicitly.
210     (Note, however, that not every directory in the tree
211     necessarily has an &SConscript; file.)
212     Alternatively, the <literal>drivers</literal>
213     subdirectory might contain an intermediate
214     &SConscript; file,
215     in which case the &SConscript; call in
216     the top-level &SConstruct; file
217     would look like:
218
219     </para>
220
221     <programlisting>
222       SConscript(['drivers/SConscript',
223                   'parser/SConscript',
224                   'utilities/SConscript'])
225     </programlisting>
226
227     <para>
228
229     And the subsidiary &SConscript; file in the
230     <literal>drivers</literal> subdirectory
231     would look like:
232
233     </para>
234
235     <programlisting>
236       SConscript(['display/SConscript',
237                   'mouse/SConscript'])
238     </programlisting>
239
240     <para>
241
242     Whether you list all of the &SConscript; files in the
243     top-level &SConstruct; file,
244     or place a subsidiary &SConscript; file in
245     intervening directories,
246     or use some mix of the two schemes,
247     is up to you and the needs of your software.
248
249     </para>
250
251   </section>
252
253   <section>
254   <title>Path Names Are Relative to the &SConscript; Directory</title>
255
256     <para>
257
258     Subsidiary &SConscript; files make it easy to create a build
259     hierarchy because all of the file and directory names
260     in a subsidiary &SConscript; files are interpreted
261     relative to the directory in which the &SConscript; file lives.
262     Typically, this allows the &SConscript; file containing the
263     instructions to build a target file
264     to live in the same directory as the source files
265     from which the target will be built,
266     making it easy to update how the software is built
267     whenever files are added or deleted
268     (or other changes are made).
269
270     </para>
271
272     <para>
273
274     For example, suppose we want to build two programs
275     &prog1; and &prog2; in two separate directories
276     with the same names as the programs.
277     One typical way to do this would be
278     with a top-level &SConstruct; file like this:
279
280     </para>
281
282     <programlisting>
283       SConscript(['prog1/SConscript',
284                   'prog2/SConscript'])
285     </programlisting>
286
287     <para>
288
289     And subsidiary &SConscript; files that look like this:
290
291     </para>
292
293     
294     <programlisting>
295       env = Environment()
296       env.Program('prog1', ['main.c', 'foo1.c', 'foo2.c'])
297       </programlisting>
298
299     <para>
300
301     And this:
302
303     </para>
304
305     
306     <programlisting>
307       env = Environment()
308       env.Program('prog2', ['main.c', 'bar1.c', 'bar2.c'])
309       </programlisting>
310
311     <para>
312
313     Then, when we run &SCons; in the top-level directory,
314     our build looks like:
315
316     </para>
317
318     <screen>
319        % <userinput>scons -Q</userinput>
320        cc -o prog1/foo1.o -c prog1/foo1.c
321        cc -o prog1/foo2.o -c prog1/foo2.c
322        cc -o prog1/main.o -c prog1/main.c
323        cc -o prog1/prog1 prog1/main.o prog1/foo1.o prog1/foo2.o
324        cc -o prog2/bar1.o -c prog2/bar1.c
325        cc -o prog2/bar2.o -c prog2/bar2.c
326        cc -o prog2/main.o -c prog2/main.c
327        cc -o prog2/prog2 prog2/main.o prog2/bar1.o prog2/bar2.o
328     </screen>
329
330     <para>
331
332     Notice the following:
333
334     First, you can have files with the same names
335     in multiple directories, like main.c in the above example.
336
337     Second, unlike standard recursive use of &Make;,
338     &SCons; stays in the top-level directory
339     (where the &SConstruct; file lives)
340     and issues commands that use the path names
341     from the top-level directory to the
342     target and source files within the hierarchy.
343
344     </para>
345
346   </section>
347
348   <section>
349   <title>Top-Level Path Names in Subsidiary &SConscript; Files</title>
350
351     <para>
352
353     If you need to use a file from another directory,
354     it's sometimes more convenient to specify
355     the path to a file in another directory
356     from the top-level &SConstruct; directory,
357     even when you're using that file in
358     a subsidiary &SConscript; file in a subdirectory.
359     You can tell &SCons; to interpret a path name
360     as relative to the top-level &SConstruct; directory,
361     not the local directory of the &SConscript; file,
362     by appending a &hash; (hash mark)
363     to the beginning of the path name:
364
365     </para>
366
367     <programlisting>
368        env = Environment()
369        env.Program('prog', ['main.c', '#lib/foo1.c', 'foo2.c'])
370     </programlisting>
371
372     <para>
373
374     In this example,
375     the <literal>lib</literal> directory is
376     directly underneath the top-level &SConstruct; directory.
377     If the above &SConscript; file is in a subdirectory
378     named <literal>src/prog</literal>,
379     the output would look like:
380
381     </para>
382
383     <screen>
384        % <userinput>scons -Q</userinput>
385        cc -o lib/foo1.o -c lib/foo1.c
386        cc -o src/prog/foo2.o -c src/prog/foo2.c
387        cc -o src/prog/main.o -c src/prog/main.c
388        cc -o src/prog/prog src/prog/main.o lib/foo1.o src/prog/foo2.o
389     </screen>
390
391     <para>
392
393     (Notice that the <literal>lib/foo1.o</literal> object file
394     is built in the same directory as its source file.
395     See <xref linkend="chap-separate"></xref>, below,
396     for information about
397     how to build the object file in a different subdirectory.)
398
399     </para>
400
401   </section>
402
403   <section>
404   <title>Absolute Path Names</title>
405
406     <para>
407
408     Of course, you can always specify
409     an absolute path name for a file--for example:
410
411     </para>
412
413     <programlisting>
414        env = Environment()
415        env.Program('prog', ['main.c', '/usr/joe/lib/foo1.c', 'foo2.c'])
416     </programlisting>
417
418     <para>
419
420     Which, when executed, would yield:
421
422     </para>
423
424     <screen>
425        % <userinput>scons -Q</userinput>
426        cc -o src/prog/foo2.o -c src/prog/foo2.c
427        cc -o src/prog/main.o -c src/prog/main.c
428        cc -o /usr/joe/lib/foo1.o -c /usr/joe/lib/foo1.c
429        cc -o src/prog/prog src/prog/main.o /usr/joe/lib/foo1.o src/prog/foo2.o
430     </screen>
431
432     <para>
433
434     (As was the case with top-relative path names,
435     notice that the <literal>/usr/joe/lib/foo1.o</literal> object file
436     is built in the same directory as its source file.
437     See <xref linkend="chap-separate"></xref>, below,
438     for information about
439     how to build the object file in a different subdirectory.)
440
441     </para>
442
443   </section>
444
445   <section>
446   <title>Sharing Environments (and Other Variables) Between &SConscript; Files</title>
447
448     <para>
449
450     In the previous example,
451     each of the subsidiary &SConscript; files
452     created its own construction environment
453     by calling &Environment; separately.
454     This obviously works fine,
455     but if each program must be built
456     with the same construction variables,
457     it's cumbersome and error-prone to initialize
458     separate construction environments
459     in the same way over and over in each subsidiary
460     &SConscript; file.
461
462     </para>
463
464     <para>
465
466     &SCons; supports the ability to <emphasis>export</emphasis> variables
467     from a parent &SConscript; file
468     to its subsidiary &SConscript; files,
469     which allows you to share common initialized
470     values throughout your build hierarchy.
471
472     </para>
473
474     <section>
475     <title>Exporting Variables</title>
476
477       <para>
478
479       There are two ways to export a variable,
480       such as a construction environment,
481       from an &SConscript; file,
482       so that it may be used by other &SConscript; files.
483       First, you can call the &Export;
484       function with a list of variables,
485       or a string white-space separated variable names.
486       Each call to &Export; adds one
487       or more variables to a global list
488       of variables that are available for import
489       by other &SConscript; files.
490
491       </para>
492
493       <programlisting>
494         env = Environment()
495         Export('env')
496       </programlisting>
497
498       <para>
499
500       You may export more than one variable name at a time:
501
502       </para>
503
504       <programlisting>
505         env = Environment()
506         debug = ARGUMENTS['debug']
507         Export('env', 'debug')
508       </programlisting>
509
510       <para>
511
512       Because white space is not legal in Python variable names,
513       the &Export; function will even automatically split
514       a string into separate names for you:
515
516       </para>
517
518       <programlisting>
519         Export('env debug')
520       </programlisting>
521
522       <para>
523
524       Second, you can specify a list of
525       variables to export as a second argument
526       to the &SConscript; function call:
527
528       </para>
529
530       <programlisting>
531         SConscript('src/SConscript', 'env')
532       </programlisting>
533
534       <para>
535
536       Or as the &exports; keyword argument:
537
538       </para>
539
540       <programlisting>
541         SConscript('src/SConscript', exports='env')
542       </programlisting>
543
544       <para>
545
546       These calls export the specified variables
547       to only the listed &SConscript; files.
548       You may, however, specify more than one
549       &SConscript; file in a list:
550
551       </para>
552
553       <programlisting>
554         SConscript(['src1/SConscript',
555                     'src2/SConscript'], exports='env')
556       </programlisting>
557
558       <para>
559
560       This is functionally equivalent to
561       calling the &SConscript; function
562       multiple times with the same &exports; argument,
563       one per &SConscript; file.
564
565       </para>
566
567     </section>
568
569     <section>
570     <title>Importing Variables</title>
571
572       <para>
573
574       Once a variable has been exported from a calling
575       &SConscript; file,
576       it may be used in other &SConscript; files
577       by calling the &Import; function:
578
579       </para>
580
581       <programlisting>
582         Import('env')
583         env.Program('prog', ['prog.c'])
584       </programlisting>
585
586       <para>
587
588       The &Import; call makes the <literal>env</literal> construction
589       environment available to the &SConscript; file,
590       after which the variable can be used to build
591       programs, libraries, etc.
592
593       </para>
594
595       <para>
596
597       Like the &Export; function,
598       the &Import; function can be used
599       with multiple variable names:
600
601       </para>
602
603       <programlisting>
604         Import('env', 'debug')
605         env = env.Clone(DEBUG = debug)
606         env.Program('prog', ['prog.c'])
607       </programlisting>
608
609       <para>
610
611       And the &Import; function will similarly
612       split a string along white-space
613       into separate variable names:
614
615       </para>
616
617       <programlisting>
618         Import('env debug')
619         env = env.Clone(DEBUG = debug)
620         env.Program('prog', ['prog.c'])
621       </programlisting>
622
623       <para>
624
625       Lastly, as a special case,
626       you may import all of the variables that
627       have been exported by supplying an asterisk
628       to the &Import; function:
629
630       </para>
631
632       <programlisting>
633         Import('*')
634         env = env.Clone(DEBUG = debug)
635         env.Program('prog', ['prog.c'])
636       </programlisting>
637
638       <para>
639
640       If you're dealing with a lot of &SConscript; files,
641       this can be a lot simpler than keeping
642       arbitrary lists of imported variables in each file.
643
644       </para>
645
646     </section>
647
648     <section>
649     <title>Returning Values From an &SConscript; File</title>
650
651       <para>
652
653       Sometimes, you would like to be able to
654       use information from a subsidiary
655       &SConscript; file in some way.
656       For example,
657       suppose that you want to create one
658       library from source files
659       scattered throughout a number
660       of subsidiary &SConscript; files.
661       You can do this by using the &Return;
662       function to return values
663       from the subsidiary &SConscript; files
664       to the calling file.
665
666       </para>
667
668       <para>
669
670       If, for example, we have two subdirectories
671       &foo; and &bar;
672       that should each contribute a source
673       file to a Library,
674       what we'd like to be able to do is
675       collect the object files
676       from the subsidiary &SConscript; calls
677       like this:
678
679       </para>
680
681       <programlisting>
682           env = Environment()
683           Export('env')
684           objs = []
685           for subdir in ['foo', 'bar']:
686               o = SConscript('%s/SConscript' % subdir)
687               objs.append(o)
688           env.Library('prog', objs)
689       </programlisting>
690
691       <para>
692
693       We can do this by using the &Return;
694       function in the
695       <literal>foo/SConscript</literal> file like this:
696
697       </para>
698
699       
700       <programlisting>
701           Import('env')
702           obj = env.Object('foo.c')
703           Return('obj')
704         </programlisting>
705
706       <para>
707
708       (The corresponding
709       <literal>bar/SConscript</literal>
710       file should be pretty obvious.)
711       Then when we run &SCons;,
712       the object files from the subsidiary subdirectories
713       are all correctly archived in the desired library:
714
715       </para>
716
717       <screen>
718         % <userinput>scons -Q</userinput>
719         cc -o bar/bar.o -c bar/bar.c
720         cc -o foo/foo.o -c foo/foo.c
721         ar rc libprog.a foo/foo.o bar/bar.o
722         ranlib libprog.a
723       </screen>
724
725     </section>
726
727   </section>
728
729   <!--
730
731   <section>
732   <title>Executing From a Subdirectory:  the -D, -u and -U Options</title>
733
734     <para>
735
736     XXX -D, -u and -U
737
738     </para>
739
740   </section>
741
742   -->