148922eb4967a0b3fb8b7926dd682127cdae15cf
[scons.git] / doc / user / command-line.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   <para>
27
28   &SCons; provides a number of ways
29   for the writer of the &SConscript; files
30   to give the users who will run &SCons;
31   a great deal of control over the build execution.
32   The arguments that the user can specify on
33   the command line are broken down into three types:
34
35   </para>
36
37   <variablelist>
38
39     <varlistentry>
40     <term>Options</term>
41
42     <listitem>
43     <para>
44
45     Command-line options always begin with
46     one or two <literal>-</literal> (hyphen) characters.
47     &SCons; provides ways for you to examine
48     and set options values from within your &SConscript; files,
49     as well as the ability to define your own
50     custom options.
51     See <xref linkend="sect-command-line-options"></xref>, below.
52
53     </para>
54     </listitem>
55     </varlistentry>
56
57     <varlistentry>
58     <term>Variables</term>
59
60     <listitem>
61     <para>
62
63     Any command-line argument containing an <literal>=</literal>
64     (equal sign) is considered a variable setting with the form
65     <varname>variable</varname>=<varname>value</varname>
66     &SCons; provides direct access to
67     all of the command-line variable settings,
68     the ability to apply command-line variable settings
69     to construction environments,
70     and functions for configuring 
71     specific types of variables
72     (Boolean values, path names, etc.)
73     with automatic validation of the user's specified values.
74     See <xref linkend="sect-command-line-variables"></xref>, below.
75
76     </para>
77     </listitem>
78     </varlistentry>
79
80     <varlistentry>
81     <term>Targets</term>
82
83     <listitem>
84     <para>
85
86     Any command-line argument that is not an option
87     or a variable setting
88     (does not begin with a hyphen
89     and does not contain an equal sign)
90     is considered a target that the user
91     (presumably) wants &SCons; to build.
92     A list of Node objects representing
93     the target or targets to build.
94     &SCons; provides access to the list of specified targets,
95     as well as ways to set the default list of targets
96     from within the &SConscript; files.
97     See <xref linkend="sect-command-line-targets"></xref>, below.
98
99     </para>
100     </listitem>
101     </varlistentry>
102
103   </variablelist>
104
105   <section id="sect-command-line-options">
106   <title>Command-Line Options</title>
107
108     <para>
109
110     &SCons; has many <emphasis>command-line options</emphasis>
111     that control its behavior.
112     A &SCons; <emphasis>command-line option</emphasis>
113     always begins with one or two <literal>-</literal> (hyphen)
114     characters.
115
116     </para>
117
118     <section>
119     <title>Not Having to Specify Command-Line Options Each Time:  the &SCONSFLAGS; Environment Variable</title>
120
121       <para>
122
123       Users may find themselves supplying
124       the same command-line options every time
125       they run &SCons;.
126       For example, you might find it saves time
127       to specify a value of <literal>-j 2</literal>
128       to have &SCons; run up to two build commands in parallel.
129       To avoid having to type <literal>-j 2</literal> by hand
130       every time,
131       you can set the external environment variable
132       &SCONSFLAGS; to a string containing
133       command-line options that you want &SCons; to use.
134
135       </para>
136
137       <para>
138
139       If, for example,
140       you're using a POSIX shell that's
141       compatible with the Bourne shell,
142       and you always want &SCons; to use the
143       <literal>-Q</literal> option,
144       you can set the &SCONSFLAGS;
145       environment as follows:
146
147       </para>
148
149       
150
151       <screen>
152         % <userinput>scons</userinput>
153         scons: Reading SConscript files ...
154         scons: done reading SConscript files.
155         scons: Building targets ...
156             ... [build output] ...
157         scons: done building targets.
158         % <userinput>export SCONSFLAGS="-Q"</userinput>
159         % <userinput>scons</userinput>
160             ... [build output] ...
161       </screen>
162
163       <para>
164
165       Users of &csh;-style shells on POSIX systems
166       can set the &SCONSFLAGS; environment as follows:
167
168       </para>
169
170       <screen>
171         $ <userinput>setenv SCONSFLAGS "-Q"</userinput>
172       </screen>
173
174       <para>
175
176       Windows users may typically want to set the
177       &SCONSFLAGS; in the appropriate tab of the
178       <literal>System Properties</literal> window.
179
180       </para>
181
182     </section>
183
184     <section>
185     <title>Getting Values Set by Command-Line Options:  the &GetOption; Function</title>
186
187       <para>
188
189       &SCons; provides the &GetOption; function
190       to get the values set by the various command-line options.
191       One common use of this is to check whether or not
192       the <literal>-h</literal> or <literal>--help</literal> option
193       has been specified.
194       Normally, &SCons; does not print its help text
195       until after it has read all of the &SConscript; files,
196       because it's possible that help text has been added
197       by some subsidiary &SConscript; file deep in the
198       source tree hierarchy.
199       Of course, reading all of the &SConscript; files
200       takes extra time.
201
202       </para>
203
204       <para>
205
206       If you know that your configuration does not define
207       any additional help text in subsidiary &SConscript; files,
208       you can speed up the command-line help available to users
209       by using the &GetOption; function to load the
210       subsidiary &SConscript; files only if the
211       the user has <emphasis>not</emphasis> specified
212       the <literal>-h</literal> or <literal>--help</literal> option,
213       like so:
214
215       </para>
216
217       <programlisting></programlisting>
218
219       <para>
220
221       In general, the string that you pass to the
222       &GetOption; function to fetch the value of a command-line
223       option setting is the same as the "most common" long option name
224       (beginning with two hyphen characters),
225       although there are some exceptions.
226       The list of &SCons; command-line options
227       and the &GetOption; strings for fetching them,
228       are available in the
229       <xref linkend="sect-command-line-option-strings"></xref> section,
230       below.
231
232       </para>
233
234     </section>
235
236     <section>
237     <title>Setting Values of Command-Line Options:  the &SetOption; Function</title>
238
239       <para>
240
241       You can also set the values of &SCons;
242       command-line options from within the &SConscript; files
243       by using the &SetOption; function.
244       The strings that you use to set the values of &SCons;
245       command-line options are available in the
246       <xref linkend="sect-command-line-option-strings"></xref> section,
247       below.
248
249       </para>
250
251       <para>
252
253       One use of the &SetOption; function is to
254       specify a value for the <literal>-j</literal>
255       or <literal>--jobs</literal> option,
256       so that users get the improved performance
257       of a parallel build without having to specify the option by hand.
258       A complicating factor is that a good value
259       for the <literal>-j</literal> option is
260       somewhat system-dependent.
261       One rough guideline is that the more processors
262       your system has,
263       the higher you want to set the
264       <literal>-j</literal> value,
265       in order to take advantage of the number of CPUs.
266
267       </para>
268
269       <para>
270
271       For example, suppose the administrators
272       of your development systems
273       have standardized on setting a
274       <varname>NUM_CPU</varname> environment variable
275       to the number of processors on each system.
276       A little bit of Python code
277       to access the environment variable
278       and the &SetOption; function
279       provide the right level of flexibility:
280
281       </para>
282
283       <programlisting>
284         import os
285         num_cpu = int(os.environ.get('NUM_CPU', 2))
286         SetOption('num_jobs', num_cpu)
287         print "running with -j", GetOption('num_jobs')
288       </programlisting>
289
290       <para>
291
292       The above snippet of code
293       sets the value of the <literal>--jobs</literal> option
294       to the value specified in the
295       <varname>$NUM_CPU</varname> environment variable.
296       (This is one of the exception cases
297       where the string is spelled differently from
298       the from command-line option.
299       The string for fetching or setting the <literal>--jobs</literal>
300       value is <literal>num_jobs</literal>
301       for historical reasons.)
302       The code in this example prints the <literal>num_jobs</literal>
303       value for illustrative purposes.
304       It uses a default value of <literal>2</literal>
305       to provide some minimal parallelism even on
306       single-processor systems:
307
308       </para>
309
310       <screen>
311         % <userinput>scons -Q</userinput>
312         running with -j 2
313         scons: `.' is up to date.
314       </screen>
315
316       <para>
317
318       But if the <varname>$NUM_CPU</varname>
319       environment variable is set,
320       then we use that for the default number of jobs:
321
322       </para>
323
324       <screen>
325         % <userinput>export NUM_CPU="4"</userinput>
326         % <userinput>scons -Q</userinput>
327         running with -j 4
328         scons: `.' is up to date.
329       </screen>
330
331       <para>
332
333       But any explicit
334       <literal>-j</literal> or <literal>--jobs</literal>
335       value the user specifies an the command line is used first,
336       regardless of whether or not
337       the <varname>$NUM_CPU</varname> environment
338       variable is set:
339
340       </para>
341
342       <screen>
343         % <userinput>scons -Q -j 7</userinput>
344         running with -j 7
345         scons: `.' is up to date.
346         % <userinput>export NUM_CPU="4"</userinput>
347         % <userinput>scons -Q -j 3</userinput>
348         running with -j 3
349         scons: `.' is up to date.
350       </screen>
351
352     </section>
353
354     <section id="sect-command-line-option-strings">
355     <title>Strings for Getting or Setting Values of &SCons; Command-Line Options</title>
356
357       <para>
358
359       The strings that you can pass to the &GetOption;
360       and &SetOption; functions usually correspond to the
361       first long-form option name
362       (beginning with two hyphen characters:  <literal>--</literal>),
363       after replacing any remaining hyphen characters
364       with underscores.
365
366       </para>
367
368       <para>
369
370       The full list of strings and the variables they
371       correspond to is as follows:
372
373       </para>
374
375       <informaltable>
376       <tgroup cols="2" align="left">
377
378       <thead>
379
380       <row>
381       <entry>String for &GetOption; and &SetOption;</entry>
382       <entry>Command-Line Option(s)</entry>
383       </row>
384
385       </thead>
386
387       <tbody>
388
389       <row>
390       <entry><literal>cache_debug</literal></entry>
391       <entry><option>--cache-debug</option></entry>
392       </row>
393
394       <row>
395       <entry><literal>cache_disable</literal></entry>
396       <entry><option>--cache-disable</option></entry>
397       </row>
398
399       <row>
400       <entry><literal>cache_force</literal></entry>
401       <entry><option>--cache-force</option></entry>
402       </row>
403
404       <row>
405       <entry><literal>cache_show</literal></entry>
406       <entry><option>--cache-show</option></entry>
407       </row>
408
409       <row>
410       <entry><literal>clean</literal></entry>
411       <entry><option>-c</option>,
412            <option>--clean</option>,
413            <option>--remove</option></entry>
414       </row>
415
416       <row>
417       <entry><literal>config</literal></entry>
418       <entry><option>--config</option></entry>
419       </row>
420
421       <row>
422       <entry><literal>directory</literal></entry>
423       <entry><option>-C</option>,
424              <option>--directory</option></entry>
425       </row>
426
427       <row>
428       <entry><literal>diskcheck</literal></entry>
429       <entry><option>--diskcheck</option></entry>
430       </row>
431
432       <row>
433       <entry><literal>duplicate</literal></entry>
434       <entry><option>--duplicate</option></entry>
435       </row>
436
437       <row>
438       <entry><literal>file</literal></entry>
439       <entry><option>-f</option>,
440              <option>--file</option>,
441              <option>--makefile </option>,
442              <option>--sconstruct</option></entry>
443       </row>
444
445       <row>
446       <entry><literal>help</literal></entry>
447       <entry><option>-h</option>,
448              <option>--help</option></entry>
449       </row>
450
451       <row>
452       <entry><literal>ignore_errors</literal></entry>
453       <entry><option>--ignore-errors</option></entry>
454       </row>
455
456       <row>
457       <entry><literal>implicit_cache</literal></entry>
458       <entry><option>--implicit-cache</option></entry>
459       </row>
460
461       <row>
462       <entry><literal>implicit_deps_changed</literal></entry>
463       <entry><option>--implicit-deps-changed</option></entry>
464       </row>
465
466       <row>
467       <entry><literal>implicit_deps_unchanged</literal></entry>
468       <entry><option>--implicit-deps-unchanged</option></entry>
469       </row>
470
471       <row>
472       <entry><literal>interactive</literal></entry>
473       <entry><option>--interact</option>,
474              <option>--interactive</option></entry>
475       </row>
476
477       <row>
478       <entry><literal>keep_going</literal></entry>
479       <entry><option>-k</option>,
480              <option>--keep-going</option></entry>
481       </row>
482
483       <row>
484       <entry><literal>max_drift</literal></entry>
485       <entry><option>--max-drift</option></entry>
486       </row>
487
488       <row>
489       <entry><literal>no_exec</literal></entry>
490       <entry><option>-n</option>,
491              <option>--no-exec</option>,
492              <option>--just-print</option>,
493              <option>--dry-run</option>,
494              <option>--recon</option></entry>
495       </row>
496
497       <row>
498       <entry><literal>no_site_dir</literal></entry>
499       <entry><option>--no-site-dir</option></entry>
500       </row>
501
502       <row>
503       <entry><literal>num_jobs</literal></entry>
504       <entry><option>-j</option>,
505              <option>--jobs</option></entry>
506       </row>
507
508       <row>
509       <entry><literal>profile_file</literal></entry>
510       <entry><option>--profile</option></entry>
511       </row>
512
513       <row>
514       <entry><literal>question</literal></entry>
515       <entry><option>-q</option>,
516              <option>--question</option></entry>
517       </row>
518
519       <row>
520       <entry><literal>random</literal></entry>
521       <entry><option>--random</option></entry>
522       </row>
523
524       <row>
525       <entry><literal>repository</literal></entry>
526       <entry><option>-Y</option>,
527              <option>--repository</option>,
528              <option>--srcdir</option></entry>
529       </row>
530
531       <row>
532       <entry><literal>silent</literal></entry>
533       <entry><option>-s</option>,
534              <option>--silent</option>,
535              <option>--quiet</option></entry>
536       </row>
537
538       <row>
539       <entry><literal>site_dir</literal></entry>
540       <entry><option>--site-dir</option></entry>
541       </row>
542
543       <row>
544       <entry><literal>stack_size</literal></entry>
545       <entry><option>--stack-size</option></entry>
546       </row>
547
548       <row>
549       <entry><literal>taskmastertrace_file</literal></entry>
550       <entry><option>--taskmastertrace</option></entry>
551       </row>
552
553       <row>
554       <entry><literal>warn</literal></entry>
555       <entry><option>--warn</option> <option>--warning</option></entry>
556       </row>
557
558       </tbody>
559
560       </tgroup>
561       </informaltable>
562
563     </section>
564
565     <section>
566     <title>Adding Custom Command-Line Options:  the &AddOption; Function</title>
567
568       <para>
569
570       &SCons; also allows you to define your own
571       command-line options with the &AddOption; function.
572       The &AddOption; function takes the same arguments
573       as the <function>optparse.add_option</function> function
574       from the standard Python library.
575       <footnote>
576       <para>
577       The &AddOption; function is,
578       in fact, implemented using a subclass
579       of the <classname>optparse.OptionParser</classname>.
580       </para>
581       </footnote>
582       Once you have added a custom command-line option
583       with the &AddOption; function,
584       the value of the option (if any) is immediately available
585       using the standard &GetOption; function.
586       (The value can also be set using &SetOption;,
587       although that's not very useful in practice
588       because a default value can be specified in
589       directly in the &AddOption; call.)
590
591       </para>
592
593       <para>
594
595       One useful example of using this functionality
596       is to provide a <option>--prefix</option> for users:
597
598       </para>
599
600       <programlisting>
601         AddOption('--prefix',
602                   dest='prefix',
603                   type='string',
604                   nargs=1,
605                   action='store',
606                   metavar='DIR',
607                   help='installation prefix')
608
609         env = Environment(PREFIX = GetOption('prefix'))
610
611         installed_foo = env.Install('$PREFIX/usr/bin', 'foo.in')
612         Default(installed_foo)
613       </programlisting>
614
615       <para>
616
617       The above code uses the &GetOption; function
618       to set the <varname>$PREFIX</varname>
619       construction variable to any
620       value that the user specifies with a command-line
621       option of <literal>--prefix</literal>.
622       Because <varname>$PREFIX</varname>
623       will expand to a null string if it's not initialized,
624       running &SCons; without the
625       option of <literal>--prefix</literal>
626       will install the file in the
627       <filename>/usr/bin/</filename> directory:
628
629       </para>
630
631       <screen>
632         % <userinput>scons -Q -n</userinput>
633         Install file: "foo.in" as "/usr/bin/foo.in"
634       </screen>
635
636       <para>
637
638       But specifying <literal>--prefix=/tmp/install</literal>
639       on the command line causes the file to be installed in the
640       <filename>/tmp/install/usr/bin/</filename> directory:
641
642       </para>
643
644       <screen>
645         % <userinput>scons -Q -n --prefix=/tmp/install</userinput>
646         Install file: "foo.in" as "/tmp/install/usr/bin/foo.in"
647       </screen>
648
649     </section>
650
651   </section>
652
653   <section id="sect-command-line-variables">
654   <title>Command-Line <varname>variable</varname>=<varname>value</varname> Build Variables</title>
655
656     <para>
657
658     You may want to control various aspects
659     of your build by allowing the user
660     to specify <varname>variable</varname>=<varname>value</varname>
661     values on the command line.
662     For example, suppose you
663     want users to be able to
664     build a debug version of a program
665     by running &SCons; as follows:
666
667     </para>
668
669     <screen>
670       % <userinput>scons -Q debug=1</userinput>
671     </screen>
672
673     <para>
674
675     &SCons; provides an &ARGUMENTS; dictionary
676     that stores all of the
677     <varname>variable</varname>=<varname>value</varname>
678     assignments from the command line.
679     This allows you to modify
680     aspects of your build in response
681     to specifications on the command line.
682     (Note that unless you want to require
683     that users <emphasis>always</emphasis>
684     specify a variable,
685     you probably want to use
686     the Python
687     <literal>ARGUMENTS.get()</literal> function,
688     which allows you to specify a default value
689     to be used if there is no specification
690     on the command line.)
691
692     </para>
693
694     <para>
695
696     The following code sets the &cv-link-CCFLAGS; construction
697     variable in response to the <varname>debug</varname>
698     flag being set in the &ARGUMENTS; dictionary:
699
700     </para>
701
702     <programlisting>
703        env = Environment()
704        debug = ARGUMENTS.get('debug', 0)
705        if int(debug):
706            env.Append(CCFLAGS = '-g')
707        env.Program('prog.c')
708     </programlisting>
709
710     <para>
711
712     This results in the <varname>-g</varname>
713     compiler option being used when
714     <literal>debug=1</literal>
715     is used on the command line:
716
717     </para>
718
719     <screen>
720        % <userinput>scons -Q debug=0</userinput>
721        cc -o prog.o -c prog.c
722        cc -o prog prog.o
723        % <userinput>scons -Q debug=0</userinput>
724        scons: `.' is up to date.
725        % <userinput>scons -Q debug=1</userinput>
726        cc -o prog.o -c -g prog.c
727        cc -o prog prog.o
728        % <userinput>scons -Q debug=1</userinput>
729        scons: `.' is up to date.
730     </screen>
731
732     <para>
733
734     Notice that &SCons; keeps track of
735     the last values used to build the object files,
736     and as a result correctly rebuilds
737     the object and executable files
738     only when the value of the <literal>debug</literal>
739     argument has changed.
740
741     </para>
742
743     <para>
744
745     The &ARGUMENTS; dictionary has two minor drawbacks.
746     First, because it is a dictionary,
747     it can only store one value for each specified keyword,
748     and thus only "remembers" the last setting
749     for each keyword on the command line.
750     This makes the &ARGUMENTS; dictionary
751     inappropriate if users should be able to
752     specify multiple values
753     on the command line for a given keyword.
754     Second, it does not preserve
755     the order in which the variable settings
756     were specified,
757     which is a problem if
758     you want the configuration to
759     behave differently in response
760     to the order in which the build
761     variable settings were specified on the command line.
762
763     </para>
764
765     <para>
766
767     To accomodate these requirements,
768     &SCons; provides an &ARGLIST; variable
769     that gives you direct access to
770     <varname>variable</varname>=<varname>value</varname>
771     settings on the command line,
772     in the exact order they were specified,
773     and without removing any duplicate settings.
774     Each element in the &ARGLIST; variable
775     is itself a two-element list
776     containing the keyword and the value
777     of the setting,
778     and you must loop through,
779     or otherwise select from,
780     the elements of &ARGLIST; to
781     process the specific settings you want
782     in whatever way is appropriate for your configuration.
783     For example,
784     the following code to let the user
785     add to the &CPPDEFINES; construction variable
786     by specifying multiple
787     <varname>define=</varname>
788     settings on the command line:
789
790     </para>
791
792     <programlisting>
793        cppdefines = []
794        for key, value in ARGLIST:
795            if key == 'define':
796                cppdefines.append(value)
797        env = Environment(CPPDEFINES = cppdefines)
798        env.Object('prog.c')
799     </programlisting>
800
801     <para>
802
803     Yields the following output:
804
805     </para>
806
807     <screen>
808        % <userinput>scons -Q define=FOO</userinput>
809        cc -o prog.o -c -DFOO prog.c
810        % <userinput>scons -Q define=FOO define=BAR</userinput>
811        cc -o prog.o -c -DFOO -DBAR prog.c
812     </screen>
813
814     <para>
815
816     Note that the &ARGLIST; and &ARGUMENTS;
817     variables do not interfere with each other,
818     but merely provide slightly different views
819     into how the user specified
820     <varname>variable</varname>=<varname>value</varname>
821     settings on the command line.
822     You can use both variables in the same
823     &SCons; configuration.
824     In general, the &ARGUMENTS; dictionary
825     is more convenient to use,
826     (since you can just fetch variable
827     settings through a dictionary access),
828     and the &ARGLIST; list
829     is more flexible
830     (since you can examine the
831     specific order in which
832     the user's command-line variabe settings).
833
834     </para>
835
836     <section>
837     <title>Controlling Command-Line Build Variables</title>
838
839       <para>
840
841       Being able to use a command-line build variable like
842       <literal>debug=1</literal> is handy,
843       but it can be a chore to write specific Python code
844       to recognize each such variable,
845       check for errors and provide appropriate messages,
846       and apply the values to a construction variable.
847       To help with this,
848       &SCons; supports a class to
849       define such build variables easily,
850       and a mechanism to apply the
851       build variables to a construction environment.
852       This allows you to control how the build variables affect
853       construction environments.
854
855       </para>
856
857       <para>
858
859       For example, suppose that you want users to set
860       a &RELEASE; construction variable on the
861       command line whenever the time comes to build
862       a program for release,
863       and that the value of this variable
864       should be added to the command line
865       with the appropriate <literal>-D</literal> option
866       (or other command line option)
867       to pass the value to the C compiler.
868       Here's how you might do that by setting
869       the appropriate value in a dictionary for the
870       &cv-link-CPPDEFINES; construction variable:
871
872       </para>
873
874       <programlisting>
875            vars = Variables()
876            vars.Add('RELEASE', 'Set to 1 to build for release', 0)
877            env = Environment(variables = vars,
878                              CPPDEFINES={'RELEASE_BUILD' : '${RELEASE}'})
879            env.Program(['foo.c', 'bar.c'])
880       </programlisting>
881
882       <para>
883
884       This &SConstruct; file first creates a &Variables; object
885       (the <literal>vars = Variables()</literal> call),
886       and then uses the object's &Add;
887       method to indicate that the &RELEASE;
888       variable can be set on the command line,
889       and that its default value will be <literal>0</literal>
890       (the third argument to the &Add; method).
891       The second argument is a line of help text;
892       we'll learn how to use it in the next section.
893
894       </para>
895
896       <para>
897
898       We then pass the created &Variables;
899       object as a &variables; keyword argument
900       to the &Environment; call
901       used to create the construction environment.
902       This then allows a user to set the
903       &RELEASE; build variable on the command line
904       and have the variable show up in
905       the command line used to build each object from
906       a C source file:
907
908       </para>
909
910       <screen>
911         % <userinput>scons -Q RELEASE=1</userinput>
912         cc -o bar.o -c -DRELEASE_BUILD=1 bar.c
913         cc -o foo.o -c -DRELEASE_BUILD=1 foo.c
914         cc -o foo foo.o bar.o
915       </screen>
916
917       <para>
918
919       NOTE:  Before &SCons; release 0.98.1, these build variables
920       were known as "command-line build options."
921       The class was actually named the &Options; class,
922       and in the sections below,
923       the various functions were named
924       &BoolOption;, &EnumOption;, &ListOption;,
925       &PathOption;, &PackageOption; and &AddOptions;.
926       These older names still work,
927       and you may encounter them in older
928       &SConscript; fles,
929       but their use is discouraged
930       and will be officially deprecated some day.
931
932       </para>
933
934     </section>
935
936     <section>
937     <title>Providing Help for Command-Line Build Variables</title>
938
939       <para>
940
941       To make command-line build variables most useful,
942       you ideally want to provide
943       some help text that will describe
944       the available variables
945       when the user runs <literal>scons -h</literal>.
946       You could write this text by hand,
947       but &SCons; provides an easier way.
948       &Variables; objects support a
949       &GenerateHelpText; method
950       that will, as its name suggests,
951       generate text that describes
952       the various variables that
953       have been added to it.
954       You then pass the output from this method to
955       the &Help; function:
956
957       </para>
958
959       <programlisting>
960            vars = Variables('custom.py')
961            vars.Add('RELEASE', 'Set to 1 to build for release', 0)
962            env = Environment(variables = vars)
963            Help(vars.GenerateHelpText(env))
964       </programlisting>
965
966       <para>
967
968       &SCons; will now display some useful text
969       when the <literal>-h</literal> option is used:
970
971       </para>
972
973       <screen>
974         % <userinput>scons -Q -h</userinput>
975         
976         RELEASE: Set to 1 to build for release
977             default: 0
978             actual: 0
979         
980         Use scons -H for help about command-line options.
981       </screen>
982
983       <para>
984
985       Notice that the help output shows the default value,
986       and the current actual value of the build variable.
987
988       </para>
989
990     </section>
991
992     <section>
993     <title>Reading Build Variables From a File</title>
994
995       <para>
996
997       Giving the user a way to specify the
998       value of a build variable on the command line
999       is useful,
1000       but can still be tedious
1001       if users must specify the variable
1002       every time they run &SCons;.
1003       We can let users provide customized build variable settings
1004       in a local file by providing a
1005       file name when we create the
1006       &Variables; object:
1007
1008       </para>
1009
1010       <programlisting>
1011            vars = Variables('custom.py')
1012            vars.Add('RELEASE', 'Set to 1 to build for release', 0)
1013            env = Environment(variables = vars,
1014                              CPPDEFINES={'RELEASE_BUILD' : '${RELEASE}'})
1015            env.Program(['foo.c', 'bar.c'])
1016            Help(vars.GenerateHelpText(env))
1017       </programlisting>
1018
1019       <para>
1020
1021       This then allows the user to control the &RELEASE;
1022       variable by setting it in the &custom_py; file:
1023
1024       </para>
1025
1026       <programlisting>
1027         RELEASE = 1
1028         </programlisting>
1029
1030       <para>
1031
1032       Note that this file is actually executed
1033       like a Python script.
1034       Now when we run &SCons;:
1035
1036       </para>
1037
1038       <screen>
1039         % <userinput>scons -Q</userinput>
1040         cc -o bar.o -c -DRELEASE_BUILD=1 bar.c
1041         cc -o foo.o -c -DRELEASE_BUILD=1 foo.c
1042         cc -o foo foo.o bar.o
1043       </screen>
1044
1045       <para>
1046
1047       And if we change the contents of &custom_py; to:
1048
1049       </para>
1050
1051       <programlisting>
1052         RELEASE = 0
1053       </programlisting>
1054
1055       <para>
1056
1057       The object files are rebuilt appropriately
1058       with the new variable:
1059
1060       </para>
1061
1062       <screen>
1063         % <userinput>scons -Q</userinput>
1064         cc -o bar.o -c -DRELEASE_BUILD=0 bar.c
1065         cc -o foo.o -c -DRELEASE_BUILD=0 foo.c
1066         cc -o foo foo.o bar.o
1067       </screen>
1068
1069     </section>
1070
1071     <section>
1072     <title>Pre-Defined Build Variable Functions</title>
1073
1074       <para>
1075
1076       &SCons; provides a number of functions
1077       that provide ready-made behaviors
1078       for various types of command-line build variables.
1079
1080       </para>
1081
1082       <section>
1083       <title>True/False Values:  the &BoolVariable; Build Variable Function</title>
1084
1085         <para>
1086
1087         It's often handy to be able to specify a
1088         variable that controls a simple Boolean variable
1089         with a &true; or &false; value.
1090         It would be even more handy to accomodate
1091         users who have different preferences for how to represent
1092         &true; or &false; values.
1093         The &BoolVariable; function
1094         makes it easy to accomodate these
1095         common representations of
1096         &true; or &false;.
1097
1098         </para>
1099
1100         <para>
1101
1102         The &BoolVariable; function takes three arguments:
1103         the name of the build variable,
1104         the default value of the build variable,
1105         and the help string for the variable.
1106         It then returns appropriate information for
1107         passing to the &Add; method of a &Variables; object, like so:
1108
1109         </para>
1110
1111         <programlisting>
1112              vars = Variables('custom.py')
1113              vars.Add(BoolVariable('RELEASE', 'Set to build for release', 0))
1114              env = Environment(variables = vars,
1115                                CPPDEFINES={'RELEASE_BUILD' : '${RELEASE}'})
1116              env.Program('foo.c')
1117         </programlisting>
1118
1119         <para>
1120
1121         With this build variable,
1122         the &RELEASE; variable can now be enabled by
1123         setting it to the value <literal>yes</literal>
1124         or <literal>t</literal>:
1125
1126         </para>
1127
1128         <screen>
1129           % <userinput>scons -Q RELEASE=yes foo.o</userinput>
1130           cc -o foo.o -c -DRELEASE_BUILD=True foo.c
1131         </screen>
1132
1133         <screen>
1134           % <userinput>scons -Q RELEASE=t foo.o</userinput>
1135           cc -o foo.o -c -DRELEASE_BUILD=True foo.c
1136         </screen>
1137
1138         <para>
1139
1140         Other values that equate to &true; include
1141         <literal>y</literal>,
1142         <literal>1</literal>,
1143         <literal>on</literal>
1144         and
1145         <literal>all</literal>.
1146
1147         </para>
1148
1149         <para>
1150
1151         Conversely, &RELEASE; may now be given a &false;
1152         value by setting it to
1153         <literal>no</literal>
1154         or
1155         <literal>f</literal>:
1156
1157         </para>
1158
1159         <screen>
1160           % <userinput>scons -Q RELEASE=no foo.o</userinput>
1161           cc -o foo.o -c -DRELEASE_BUILD=False foo.c
1162         </screen>
1163
1164         <screen>
1165           % <userinput>scons -Q RELEASE=f foo.o</userinput>
1166           cc -o foo.o -c -DRELEASE_BUILD=False foo.c
1167         </screen>
1168
1169         <para>
1170
1171         Other values that equate to &false; include
1172         <literal>n</literal>,
1173         <literal>0</literal>,
1174         <literal>off</literal>
1175         and
1176         <literal>none</literal>.
1177
1178         </para>
1179
1180         <para>
1181
1182         Lastly, if a user tries to specify
1183         any other value,
1184         &SCons; supplies an appropriate error message:
1185
1186         </para>
1187
1188         <screen>
1189           % <userinput>scons -Q RELEASE=bad_value foo.o</userinput>
1190           
1191           scons: *** Error converting option: RELEASE
1192           Invalid value for boolean option: bad_value
1193           File "/home/my/project/SConstruct", line 4, in &lt;module&gt;
1194         </screen>
1195
1196       </section>
1197
1198       <section>
1199       <title>Single Value From a List:  the &EnumVariable; Build Variable Function</title>
1200
1201         <para>
1202
1203         Suppose that we want a user to be able to
1204         set a &COLOR; variable
1205         that selects a background color to be
1206         displayed by an application,
1207         but that we want to restrict the
1208         choices to a specific set of allowed colors.
1209         This can be set up quite easily
1210         using the &EnumVariable;,
1211         which takes a list of &allowed_values
1212         in addition to the variable name,
1213         default value,
1214         and help text arguments:
1215
1216         </para>
1217
1218         <programlisting>
1219              vars = Variables('custom.py')
1220              vars.Add(EnumVariable('COLOR', 'Set background color', 'red',
1221                                  allowed_values=('red', 'green', 'blue')))
1222              env = Environment(variables = vars,
1223                                CPPDEFINES={'COLOR' : '"${COLOR}"'})
1224              env.Program('foo.c')
1225         </programlisting>
1226
1227         <para>
1228
1229         The user can now explicity set the &COLOR; build variable
1230         to any of the specified allowed values:
1231
1232         </para>
1233
1234         <screen>
1235           % <userinput>scons -Q COLOR=red foo.o</userinput>
1236           cc -o foo.o -c -DCOLOR="red" foo.c
1237           % <userinput>scons -Q COLOR=blue foo.o</userinput>
1238           cc -o foo.o -c -DCOLOR="blue" foo.c
1239           % <userinput>scons -Q COLOR=green foo.o</userinput>
1240           cc -o foo.o -c -DCOLOR="green" foo.c
1241         </screen>
1242
1243         <para>
1244
1245         But, almost more importantly,
1246         an attempt to set &COLOR;
1247         to a value that's not in the list
1248         generates an error message:
1249
1250         </para>
1251
1252         <screen>
1253           % <userinput>scons -Q COLOR=magenta foo.o</userinput>
1254           
1255           scons: *** Invalid value for option COLOR: magenta
1256           File "/home/my/project/SConstruct", line 5, in &lt;module&gt;
1257         </screen>
1258
1259         <para>
1260
1261         The &EnumVariable; function also supports a way
1262         to map alternate names to allowed values.
1263         Suppose, for example,
1264         that we want to allow the user
1265         to use the word <literal>navy</literal> as a synonym for
1266         <literal>blue</literal>.
1267         We do this by adding a &map; dictionary
1268         that will map its key values
1269         to the desired legal value:
1270
1271         </para>
1272
1273         <programlisting>
1274              vars = Variables('custom.py')
1275              vars.Add(EnumVariable('COLOR', 'Set background color', 'red',
1276                                  allowed_values=('red', 'green', 'blue'),
1277                                  map={'navy':'blue'}))
1278              env = Environment(variables = vars,
1279                                CPPDEFINES={'COLOR' : '"${COLOR}"'})
1280              env.Program('foo.c')
1281         </programlisting>
1282
1283         <para>
1284
1285         As desired, the user can then use
1286         <literal>navy</literal> on the command line,
1287         and &SCons; will translate it into <literal>blue</literal>
1288         when it comes time to use the &COLOR;
1289         variable to build a target:
1290
1291         </para>
1292
1293         <screen>
1294           % <userinput>scons -Q COLOR=navy foo.o</userinput>
1295           cc -o foo.o -c -DCOLOR="blue" foo.c
1296         </screen>
1297
1298         <para>
1299
1300         By default, when using the &EnumVariable; function,
1301         arguments that differ
1302         from the legal values
1303         only in case
1304         are treated as illegal values:
1305
1306         </para>
1307
1308         <screen>
1309           % <userinput>scons -Q COLOR=Red foo.o</userinput>
1310           
1311           scons: *** Invalid value for option COLOR: Red
1312           File "/home/my/project/SConstruct", line 5, in &lt;module&gt;
1313           % <userinput>scons -Q COLOR=BLUE foo.o</userinput>
1314           
1315           scons: *** Invalid value for option COLOR: BLUE
1316           File "/home/my/project/SConstruct", line 5, in &lt;module&gt;
1317           % <userinput>scons -Q COLOR=nAvY foo.o</userinput>
1318           
1319           scons: *** Invalid value for option COLOR: nAvY
1320           File "/home/my/project/SConstruct", line 5, in &lt;module&gt;
1321         </screen>
1322
1323         <para>
1324
1325         The &EnumVariable; function can take an additional
1326         &ignorecase; keyword argument that,
1327         when set to <literal>1</literal>,
1328         tells &SCons; to allow case differences
1329         when the values are specified:
1330
1331         </para>
1332
1333         <programlisting>
1334              vars = Variables('custom.py')
1335              vars.Add(EnumVariable('COLOR', 'Set background color', 'red',
1336                                  allowed_values=('red', 'green', 'blue'),
1337                                  map={'navy':'blue'},
1338                                  ignorecase=1))
1339              env = Environment(variables = vars,
1340                                CPPDEFINES={'COLOR' : '"${COLOR}"'})
1341              env.Program('foo.c')
1342         </programlisting>
1343
1344         <para>
1345
1346         Which yields the output:
1347
1348         </para>
1349
1350         <screen>
1351           % <userinput>scons -Q COLOR=Red foo.o</userinput>
1352           cc -o foo.o -c -DCOLOR="Red" foo.c
1353           % <userinput>scons -Q COLOR=BLUE foo.o</userinput>
1354           cc -o foo.o -c -DCOLOR="BLUE" foo.c
1355           % <userinput>scons -Q COLOR=nAvY foo.o</userinput>
1356           cc -o foo.o -c -DCOLOR="blue" foo.c
1357           % <userinput>scons -Q COLOR=green foo.o</userinput>
1358           cc -o foo.o -c -DCOLOR="green" foo.c
1359         </screen>
1360
1361         <para>
1362
1363         Notice that an &ignorecase; value of <literal>1</literal>
1364         preserves the case-spelling that the user supplied.
1365         If you want &SCons; to translate the names
1366         into lower-case,
1367         regardless of the case used by the user,
1368         specify an &ignorecase; value of <literal>2</literal>:
1369
1370         </para>
1371
1372         <programlisting>
1373              vars = Variables('custom.py')
1374              vars.Add(EnumVariable('COLOR', 'Set background color', 'red',
1375                                  allowed_values=('red', 'green', 'blue'),
1376                                  map={'navy':'blue'},
1377                                  ignorecase=2))
1378              env = Environment(variables = vars,
1379                                CPPDEFINES={'COLOR' : '"${COLOR}"'})
1380              env.Program('foo.c')
1381         </programlisting>
1382
1383         <para>
1384
1385         Now &SCons; will use values of
1386         <literal>red</literal>,
1387         <literal>green</literal> or
1388         <literal>blue</literal>
1389         regardless of how the user spells
1390         those values on the command line:
1391
1392         </para>
1393
1394         <screen>
1395           % <userinput>scons -Q COLOR=Red foo.o</userinput>
1396           cc -o foo.o -c -DCOLOR="red" foo.c
1397           % <userinput>scons -Q COLOR=nAvY foo.o</userinput>
1398           cc -o foo.o -c -DCOLOR="blue" foo.c
1399           % <userinput>scons -Q COLOR=GREEN foo.o</userinput>
1400           cc -o foo.o -c -DCOLOR="green" foo.c
1401         </screen>
1402
1403       </section>
1404
1405       <section>
1406       <title>Multiple Values From a List:  the &ListVariable; Build Variable Function</title>
1407
1408         <para>
1409
1410         Another way in which you might want to allow users
1411         to control a build variable is to
1412         specify a list of one or more legal values.
1413         &SCons; supports this through the &ListVariable; function.
1414         If, for example, we want a user to be able to set a
1415         &COLORS; variable to one or more of the legal list of values:
1416
1417         </para>
1418
1419         <programlisting>
1420              vars = Variables('custom.py')
1421              vars.Add(ListVariable('COLORS', 'List of colors', 0,
1422                                  ['red', 'green', 'blue']))
1423              env = Environment(variables = vars,
1424                                CPPDEFINES={'COLORS' : '"${COLORS}"'})
1425              env.Program('foo.c')
1426         </programlisting>
1427
1428         <para>
1429
1430         A user can now specify a comma-separated list
1431         of legal values,
1432         which will get translated into a space-separated
1433         list for passing to the any build commands:
1434
1435         </para>
1436
1437         <screen>
1438           % <userinput>scons -Q COLORS=red,blue foo.o</userinput>
1439           cc -o foo.o -c -DCOLORS="red blue" foo.c
1440           % <userinput>scons -Q COLORS=blue,green,red foo.o</userinput>
1441           cc -o foo.o -c -DCOLORS="blue green red" foo.c
1442         </screen>
1443
1444         <para>
1445
1446         In addition, the &ListVariable; function
1447         allows the user to specify explicit keywords of
1448         &all; or &none;
1449         to select all of the legal values,
1450         or none of them, respectively:
1451
1452         </para>
1453
1454         <screen>
1455           % <userinput>scons -Q COLORS=all foo.o</userinput>
1456           cc -o foo.o -c -DCOLORS="red green blue" foo.c
1457           % <userinput>scons -Q COLORS=none foo.o</userinput>
1458           cc -o foo.o -c -DCOLORS="" foo.c
1459         </screen>
1460
1461         <para>
1462
1463         And, of course, an illegal value
1464         still generates an error message:
1465
1466         </para>
1467
1468         <screen>
1469           % <userinput>scons -Q COLORS=magenta foo.o</userinput>
1470           
1471           scons: *** Error converting option: COLORS
1472           Invalid value(s) for option: magenta
1473           File "/home/my/project/SConstruct", line 5, in &lt;module&gt;
1474         </screen>
1475
1476       </section>
1477
1478       <section>
1479       <title>Path Names:  the &PathVariable; Build Variable Function</title>
1480
1481         <para>
1482
1483         &SCons; supports a &PathVariable; function
1484         to make it easy to create a build variable
1485         to control an expected path name.
1486         If, for example, you need to
1487         define a variable in the preprocessor
1488         that controls the location of a
1489         configuration file:
1490
1491         </para>
1492
1493         <programlisting>
1494              vars = Variables('custom.py')
1495              vars.Add(PathVariable('CONFIG',
1496                                  'Path to configuration file',
1497                                  '/etc/my_config'))
1498              env = Environment(variables = vars,
1499                                CPPDEFINES={'CONFIG_FILE' : '"$CONFIG"'})
1500              env.Program('foo.c')
1501         </programlisting>
1502
1503         <para>
1504
1505         This then allows the user to
1506         override the &CONFIG; build variable
1507         on the command line as necessary:
1508
1509         </para>
1510
1511         <screen>
1512           % <userinput>scons -Q foo.o</userinput>
1513           cc -o foo.o -c -DCONFIG_FILE="/etc/my_config" foo.c
1514           % <userinput>scons -Q CONFIG=/usr/local/etc/other_config foo.o</userinput>
1515           scons: `foo.o' is up to date.
1516         </screen>
1517
1518         <para>
1519
1520         By default, &PathVariable; checks to make sure
1521         that the specified path exists and generates an error if it
1522         doesn't:
1523
1524         </para>
1525
1526         <screen>
1527           % <userinput>scons -Q CONFIG=/does/not/exist foo.o</userinput>
1528           
1529           scons: *** Path for option CONFIG does not exist: /does/not/exist
1530           File "/home/my/project/SConstruct", line 6, in &lt;module&gt;
1531         </screen>
1532
1533         <para>
1534
1535         &PathVariable; provides a number of methods
1536         that you can use to change this behavior.
1537         If you want to ensure that any specified paths are,
1538         in fact, files and not directories,
1539         use the &PathVariable_PathIsFile; method:
1540
1541         </para>
1542
1543         <programlisting>
1544              vars = Variables('custom.py')
1545              vars.Add(PathVariable('CONFIG',
1546                                  'Path to configuration file',
1547                                  '/etc/my_config',
1548                                  PathVariable.PathIsFile))
1549              env = Environment(variables = vars,
1550                                CPPDEFINES={'CONFIG_FILE' : '"$CONFIG"'})
1551              env.Program('foo.c')
1552         </programlisting>
1553
1554         <para>
1555
1556         Conversely, to ensure that any specified paths are
1557         directories and not files,
1558         use the &PathVariable_PathIsDir; method:
1559
1560         </para>
1561
1562         <programlisting>
1563              vars = Variables('custom.py')
1564              vars.Add(PathVariable('DBDIR',
1565                                  'Path to database directory',
1566                                  '/var/my_dbdir',
1567                                  PathVariable.PathIsDir))
1568              env = Environment(variables = vars,
1569                                CPPDEFINES={'DBDIR' : '"$DBDIR"'})
1570              env.Program('foo.c')
1571         </programlisting>
1572
1573         <para>
1574
1575         If you want to make sure that any specified paths
1576         are directories,
1577         and you would like the directory created
1578         if it doesn't already exist,
1579         use the &PathVariable_PathIsDirCreate; method:
1580
1581         </para>
1582
1583         <programlisting>
1584              vars = Variables('custom.py')
1585              vars.Add(PathVariable('DBDIR',
1586                                  'Path to database directory',
1587                                  '/var/my_dbdir',
1588                                  PathVariable.PathIsDirCreate))
1589              env = Environment(variables = vars,
1590                                CPPDEFINES={'DBDIR' : '"$DBDIR"'})
1591              env.Program('foo.c')
1592         </programlisting>
1593
1594         <para>
1595
1596         Lastly, if you don't care whether the path exists,
1597         is a file, or a directory,
1598         use the &PathVariable_PathAccept; method
1599         to accept any path that the user supplies:
1600
1601         </para>
1602
1603         <programlisting>
1604              vars = Variables('custom.py')
1605              vars.Add(PathVariable('OUTPUT',
1606                                  'Path to output file or directory',
1607                                  None,
1608                                  PathVariable.PathAccept))
1609              env = Environment(variables = vars,
1610                                CPPDEFINES={'OUTPUT' : '"$OUTPUT"'})
1611              env.Program('foo.c')
1612         </programlisting>
1613
1614       </section>
1615
1616       <section>
1617       <title>Enabled/Disabled Path Names: the &PackageVariable; Build Variable Function</title>
1618
1619         <para>
1620
1621         Sometimes you want to give users
1622         even more control over a path name variable,
1623         allowing them to explicitly enable or
1624         disable the path name
1625         by using <literal>yes</literal> or <literal>no</literal> keywords,
1626         in addition to allow them
1627         to supply an explicit path name.
1628         &SCons; supports the &PackageVariable;
1629         function to support this:
1630
1631         </para>
1632
1633         <programlisting>
1634              vars = Variables('custom.py')
1635              vars.Add(PackageVariable('PACKAGE',
1636                                     'Location package',
1637                                     '/opt/location'))
1638              env = Environment(variables = vars,
1639                                CPPDEFINES={'PACKAGE' : '"$PACKAGE"'})
1640              env.Program('foo.c')
1641         </programlisting>
1642
1643         <para>
1644
1645         When the &SConscript; file uses the &PackageVariable; funciton,
1646         user can now still use the default
1647         or supply an overriding path name,
1648         but can now explicitly set the
1649         specified variable to a value
1650         that indicates the package should be enabled
1651         (in which case the default should be used)
1652         or disabled:
1653
1654         </para>
1655
1656         <screen>
1657           % <userinput>scons -Q foo.o</userinput>
1658           cc -o foo.o -c -DPACKAGE="/opt/location" foo.c
1659           % <userinput>scons -Q PACKAGE=/usr/local/location foo.o</userinput>
1660           cc -o foo.o -c -DPACKAGE="/usr/local/location" foo.c
1661           % <userinput>scons -Q PACKAGE=yes foo.o</userinput>
1662           cc -o foo.o -c -DPACKAGE="True" foo.c
1663           % <userinput>scons -Q PACKAGE=no foo.o</userinput>
1664           cc -o foo.o -c -DPACKAGE="False" foo.c
1665         </screen>
1666
1667       </section>
1668
1669     </section>
1670
1671     <section>
1672     <title>Adding Multiple Command-Line Build Variables at Once</title>
1673
1674       <para>
1675
1676       Lastly, &SCons; provides a way to add
1677       multiple build variables to a &Variables; object at once.
1678       Instead of having to call the &Add; method
1679       multiple times,
1680       you can call the &AddVariables;
1681       method with a list of build variables
1682       to be added to the object.
1683       Each build variable is specified
1684       as either a tuple of arguments,
1685       just like you'd pass to the &Add; method itself,
1686       or as a call to one of the pre-defined
1687       functions for pre-packaged command-line build variables.
1688       in any order:
1689
1690       </para>
1691
1692       <programlisting>
1693           vars = Variables()
1694           vars.AddVariables(
1695               ('RELEASE', 'Set to 1 to build for release', 0),
1696               ('CONFIG', 'Configuration file', '/etc/my_config'),
1697               BoolVariable('warnings', 'compilation with -Wall and similiar', 1),
1698               EnumVariable('debug', 'debug output and symbols', 'no',
1699                          allowed_values=('yes', 'no', 'full'),
1700                          map={}, ignorecase=0),  # case sensitive
1701               ListVariable('shared',
1702                          'libraries to build as shared libraries',
1703                          'all',
1704                          names = list_of_libs),
1705               PackageVariable('x11',
1706                             'use X11 installed here (yes = search some places)',
1707                             'yes'),
1708               PathVariable('qtdir', 'where the root of Qt is installed', qtdir),
1709           )
1710       </programlisting>
1711
1712       <para>
1713       </para>
1714
1715     </section>
1716
1717     <section>
1718     <title>Handling Unknown Command-Line Build Variables:  the &UnknownVariables; Function</title>
1719
1720       <para>
1721
1722       Users may, of course,
1723       occasionally misspell variable names in their command-line settings.
1724       &SCons; does not generate an error or warning
1725       for any unknown variables the users specifies on the command line.
1726       (This is in no small part because you may be
1727       processing the arguments directly using the &ARGUMENTS; dictionary,
1728       and therefore &SCons; can't know in the general case
1729       whether a given "misspelled" variable is
1730       really unknown and a potential problem,
1731       or something that your &SConscript; file
1732       will handle directly with some Python code.)
1733
1734       </para>
1735
1736       <para>
1737
1738       If, however, you're using a &Variables; object to
1739       define a specific set of command-line build variables
1740       that you expect users to be able to set,
1741       you may want to provide an error
1742       message or warning of your own
1743       if the user supplies a variable setting
1744       that is <emphasis>not</emphasis> among
1745       the defined list of variable names known to the &Variables; object.
1746       You can do this by calling the &UnknownVariables;
1747       method of the &Variables; object:
1748
1749       </para>
1750
1751       <programlisting>
1752            vars = Variables(None)
1753            vars.Add('RELEASE', 'Set to 1 to build for release', 0)
1754            env = Environment(variables = vars,
1755                              CPPDEFINES={'RELEASE_BUILD' : '${RELEASE}'})
1756            unknown = vars.UnknownVariables()
1757            if unknown:
1758                print "Unknown variables:", unknown.keys()
1759                Exit(1)
1760            env.Program('foo.c')
1761       </programlisting>
1762
1763       <para>
1764
1765       The &UnknownVariables; method returns a dictionary
1766       containing the keywords and values
1767       of any variables the user specified on the command line
1768       that are <emphasis>not</emphasis>
1769       among the variables known to the &Variables; object
1770       (from having been specified using
1771       the &Variables; object's&Add; method).
1772       In the examble above,
1773       we check for whether the dictionary
1774       returned by the &UnknownVariables; is non-empty,
1775       and if so print the Python list
1776       containing the names of the unknwown variables
1777       and then call the &Exit; function
1778       to terminate &SCons;:
1779
1780       </para>
1781
1782       <screen>
1783         % <userinput>scons -Q NOT_KNOWN=foo</userinput>
1784         Unknown variables: ['NOT_KNOWN']
1785       </screen>
1786
1787       <para>
1788
1789       Of course, you can process the items in the
1790       dictionary returned by the &UnknownVariables; function
1791       in any way appropriate to your build configuration,
1792       including just printing a warning message
1793       but not exiting,
1794       logging an error somewhere,
1795       etc.
1796
1797       </para>
1798
1799       <para>
1800
1801       Note that you must delay the call of &UnknownVariables;
1802       until after you have applied the &Variables; object
1803       to a construction environment
1804       with the <literal>variables=</literal>
1805       keyword argument of an &Environment; call.
1806
1807       </para>
1808
1809     </section>
1810
1811   </section>
1812
1813   <section id="sect-command-line-targets">
1814   <title>Command-Line Targets</title>
1815
1816     <section>
1817     <title>Fetching Command-Line Targets: the &COMMAND_LINE_TARGETS; Variable</title>
1818
1819       <para>
1820
1821       &SCons; supports a &COMMAND_LINE_TARGETS; variable
1822       that lets you fetch the list of targets that the
1823       user specified on the command line.
1824       You can use the targets to manipulate the
1825       build in any way you wish.
1826       As a simple example,
1827       suppose that you want to print a reminder
1828       to the user whenever a specific program is built.
1829       You can do this by checking for the
1830       target in the &COMMAND_LINE_TARGETS; list:
1831
1832       </para>
1833
1834       <programlisting>
1835         if 'bar' in COMMAND_LINE_TARGETS:
1836             print "Don't forget to copy `bar' to the archive!"
1837         Default(Program('foo.c'))
1838         Program('bar.c')
1839       </programlisting>
1840
1841       <para>
1842
1843       Then, running &SCons; with the default target
1844       works as it always does,
1845       but explicity specifying the &bar; target
1846       on the command line generates the warning message:
1847
1848       </para>
1849
1850       <screen>
1851         % <userinput>scons -Q</userinput>
1852         cc -o foo.o -c foo.c
1853         cc -o foo foo.o
1854         % <userinput>scons -Q bar</userinput>
1855         Don't forget to copy `bar' to the archive!
1856         cc -o bar.o -c bar.c
1857         cc -o bar bar.o
1858       </screen>
1859
1860       <para>
1861
1862       Another practical use for the &COMMAND_LINE_TARGETS; variable
1863       might be to speed up a build
1864       by only reading certain subsidiary &SConscript;
1865       files if a specific target is requested.
1866
1867       </para>
1868
1869     </section>
1870
1871     <section>
1872     <title>Controlling the Default Targets:  the &Default; Function</title>
1873
1874       <para>
1875
1876       One of the most basic things you can control
1877       is which targets &SCons; will build by default--that is,
1878       when there are no targets specified on the command line.
1879       As mentioned previously,
1880       &SCons; will normally build every target
1881       in or below the current directory
1882       by default--that is, when you don't
1883       explicitly specify one or more targets
1884       on the command line.
1885       Sometimes, however, you may want
1886       to specify explicitly that only
1887       certain programs, or programs in certain directories,
1888       should be built by default.
1889       You do this with the &Default; function:
1890
1891       </para>
1892
1893       <programlisting>
1894          env = Environment()
1895          hello = env.Program('hello.c')
1896          env.Program('goodbye.c')
1897          Default(hello)
1898       </programlisting>
1899
1900       <para>
1901
1902       This &SConstruct; file knows how to build two programs,
1903       &hello; and &goodbye;,
1904       but only builds the
1905       &hello; program by default:
1906
1907       </para>
1908
1909       <screen>
1910          % <userinput>scons -Q</userinput>
1911          cc -o hello.o -c hello.c
1912          cc -o hello hello.o
1913          % <userinput>scons -Q</userinput>
1914          scons: `hello' is up to date.
1915          % <userinput>scons -Q goodbye</userinput>
1916          cc -o goodbye.o -c goodbye.c
1917          cc -o goodbye goodbye.o
1918       </screen>
1919
1920       <para>
1921
1922       Note that, even when you use the &Default;
1923       function in your &SConstruct; file,
1924       you can still explicitly specify the current directory
1925       (<literal>.</literal>) on the command line
1926       to tell &SCons; to build
1927       everything in (or below) the current directory:
1928
1929       </para>
1930
1931       <screen>
1932          % <userinput>scons -Q .</userinput>
1933          cc -o goodbye.o -c goodbye.c
1934          cc -o goodbye goodbye.o
1935          cc -o hello.o -c hello.c
1936          cc -o hello hello.o
1937       </screen>
1938
1939       <para>
1940
1941       You can also call the &Default;
1942       function more than once,
1943       in which case each call
1944       adds to the list of targets to be built by default:
1945
1946       </para>
1947
1948       <programlisting>
1949          env = Environment()
1950          prog1 = env.Program('prog1.c')
1951          Default(prog1)
1952          prog2 = env.Program('prog2.c')
1953          prog3 = env.Program('prog3.c')
1954          Default(prog3)
1955       </programlisting>
1956
1957       <para>
1958
1959       Or you can specify more than one target
1960       in a single call to the &Default; function:
1961
1962       </para>
1963
1964       <programlisting>
1965          env = Environment()
1966          prog1 = env.Program('prog1.c')
1967          prog2 = env.Program('prog2.c')
1968          prog3 = env.Program('prog3.c')
1969          Default(prog1, prog3)
1970       </programlisting>
1971
1972       <para>
1973
1974       Either of these last two examples
1975       will build only the
1976       <application>prog1</application>
1977       and
1978       <application>prog3</application>
1979       programs by default:
1980
1981       </para>
1982
1983       <screen>
1984          % <userinput>scons -Q</userinput>
1985          cc -o prog1.o -c prog1.c
1986          cc -o prog1 prog1.o
1987          cc -o prog3.o -c prog3.c
1988          cc -o prog3 prog3.o
1989          % <userinput>scons -Q .</userinput>
1990          cc -o prog2.o -c prog2.c
1991          cc -o prog2 prog2.o
1992       </screen>
1993
1994       <para>
1995
1996       You can list a directory as
1997       an argument to &Default;:
1998
1999       </para>
2000
2001       <programlisting>
2002          env = Environment()
2003          env.Program(['prog1/main.c', 'prog1/foo.c'])
2004          env.Program(['prog2/main.c', 'prog2/bar.c'])
2005          Default('prog1')
2006       </programlisting>
2007
2008       <para>
2009
2010       In which case only the target(s) in that
2011       directory will be built by default:
2012
2013       </para>
2014
2015       <screen>
2016          % <userinput>scons -Q</userinput>
2017          cc -o prog1/foo.o -c prog1/foo.c
2018          cc -o prog1/main.o -c prog1/main.c
2019          cc -o prog1/main prog1/main.o prog1/foo.o
2020          % <userinput>scons -Q</userinput>
2021          scons: `prog1' is up to date.
2022          % <userinput>scons -Q .</userinput>
2023          cc -o prog2/bar.o -c prog2/bar.c
2024          cc -o prog2/main.o -c prog2/main.c
2025          cc -o prog2/main prog2/main.o prog2/bar.o
2026       </screen>
2027
2028       <para>
2029
2030       Lastly, if for some reason you don't want
2031       any targets built by default,
2032       you can use the Python <literal>None</literal>
2033       variable:
2034
2035       </para>
2036
2037       <programlisting>
2038          env = Environment()
2039          prog1 = env.Program('prog1.c')
2040          prog2 = env.Program('prog2.c')
2041          Default(None)
2042       </programlisting>
2043
2044       <para>
2045
2046       Which would produce build output like:
2047
2048       </para>
2049
2050       <screen>
2051          % <userinput>scons -Q</userinput>
2052          scons: *** No targets specified and no Default() targets found.  Stop.
2053          % <userinput>scons -Q .</userinput>
2054          cc -o prog1.o -c prog1.c
2055          cc -o prog1 prog1.o
2056          cc -o prog2.o -c prog2.c
2057          cc -o prog2 prog2.o
2058       </screen>
2059
2060       <section>
2061       <title>Fetching the List of Default Targets: the &DEFAULT_TARGETS; Variable</title>
2062
2063         <para>
2064
2065         &SCons; supports a &DEFAULT_TARGETS; variable
2066         that lets you get at the current list of default targets.
2067         The &DEFAULT_TARGETS variable has
2068         two important differences from the &COMMAND_LINE_TARGETS; variable.
2069         First, the &DEFAULT_TARGETS; variable is a list of
2070         internal &SCons; nodes,
2071         so you need to convert the list elements to strings
2072         if you want to print them or look for a specific target name.
2073         Fortunately, you can do this easily
2074         by using the Python <function>map</function> function
2075         to run the list through <function>str</function>:
2076
2077         </para>
2078
2079         <programlisting>
2080            prog1 = Program('prog1.c')
2081            Default(prog1)
2082            print "DEFAULT_TARGETS is", map(str, DEFAULT_TARGETS)
2083         </programlisting>
2084
2085         <para>
2086
2087         (Keep in mind that all of the manipulation of the
2088         &DEFAULT_TARGETS; list takes place during the
2089         first phase when &SCons; is reading up the &SConscript; files,
2090         which is obvious if
2091         we leave off the <literal>-Q</literal> flag when we run &SCons;:)
2092
2093         </para>
2094
2095         <screen>
2096            % <userinput>scons</userinput>
2097            scons: Reading SConscript files ...
2098            DEFAULT_TARGETS is ['prog1']
2099            scons: done reading SConscript files.
2100            scons: Building targets ...
2101            cc -o prog1.o -c prog1.c
2102            cc -o prog1 prog1.o
2103            scons: done building targets.
2104         </screen>
2105
2106         <para>
2107
2108         Second,
2109         the contents of the &DEFAULT_TARGETS; list change
2110         in response to calls to the &Default;: function,
2111         as you can see from the following &SConstruct; file:
2112
2113         </para>
2114
2115         <programlisting>
2116            prog1 = Program('prog1.c')
2117            Default(prog1)
2118            print "DEFAULT_TARGETS is now", map(str, DEFAULT_TARGETS)
2119            prog2 = Program('prog2.c')
2120            Default(prog2)
2121            print "DEFAULT_TARGETS is now", map(str, DEFAULT_TARGETS)
2122         </programlisting>
2123
2124         <para>
2125
2126         Which yields the output:
2127
2128         </para>
2129
2130         <screen>
2131            % <userinput>scons</userinput>
2132            scons: Reading SConscript files ...
2133            DEFAULT_TARGETS is now ['prog1']
2134            DEFAULT_TARGETS is now ['prog1', 'prog2']
2135            scons: done reading SConscript files.
2136            scons: Building targets ...
2137            cc -o prog1.o -c prog1.c
2138            cc -o prog1 prog1.o
2139            cc -o prog2.o -c prog2.c
2140            cc -o prog2 prog2.o
2141            scons: done building targets.
2142         </screen>
2143
2144         <para>
2145
2146         In practice, this simply means that you
2147         need to pay attention to the order in
2148         which you call the &Default; function
2149         and refer to the &DEFAULT_TARGETS; list,
2150         to make sure that you don't examine the
2151         list before you've added the default targets
2152         you expect to find in it.
2153
2154         </para>
2155
2156       </section>
2157
2158     </section>
2159
2160     <section>
2161     <title>Fetching the List of Build Targets, Regardless of Origin: the &BUILD_TARGETS; Variable</title>
2162
2163       <para>
2164
2165       We've already been introduced to the
2166       &COMMAND_LINE_TARGETS; variable,
2167       which contains a list of targets specified on the command line,
2168       and the &DEFAULT_TARGETS; variable,
2169       which contains a list of targets specified
2170       via calls to the &Default; method or function.
2171       Sometimes, however,
2172       you want a list of whatever targets
2173       &SCons; will try to build,
2174       regardless of whether the targets came from the
2175       command line or a &Default; call.
2176       You could code this up by hand, as follows:
2177
2178       </para>
2179
2180       <programlisting>
2181         if COMMAND_LINE_TARGETS:
2182             targets = COMMAND_LINE_TARGETS
2183         else:
2184             targets = DEFAULT_TARGETS
2185       </programlisting>
2186
2187       <para>
2188
2189       &SCons;, however, provides a convenient
2190       &BUILD_TARGETS; variable
2191       that eliminates the need for this by-hand manipulation.
2192       Essentially, the &BUILD_TARGETS; variable
2193       contains a list of the command-line targets,
2194       if any were specified,
2195       and if no command-line targets were specified,
2196       it contains a list of the targets specified
2197       via the &Default; method or function.
2198
2199       </para>
2200
2201       <para>
2202
2203       Because &BUILD_TARGETS; may contain a list of &SCons; nodes,
2204       you must convert the list elements to strings
2205       if you want to print them or look for a specific target name,
2206       just like the &DEFAULT_TARGETS; list:
2207
2208       </para>
2209
2210       <programlisting>
2211         prog1 = Program('prog1.c')
2212         Program('prog2.c')
2213         Default(prog1)
2214         print "BUILD_TARGETS is", map(str, BUILD_TARGETS)
2215       </programlisting>
2216
2217       <para>
2218
2219       Notice how the value of &BUILD_TARGETS;
2220       changes depending on whether a target is
2221       specified on the command line:
2222
2223       </para>
2224
2225       <screen>
2226         % <userinput>scons -Q</userinput>
2227         BUILD_TARGETS is ['prog1']
2228         cc -o prog1.o -c prog1.c
2229         cc -o prog1 prog1.o
2230         % <userinput>scons -Q prog2</userinput>
2231         BUILD_TARGETS is ['prog2']
2232         cc -o prog2.o -c prog2.c
2233         cc -o prog2 prog2.o
2234         % <userinput>scons -Q -c .</userinput>
2235         BUILD_TARGETS is ['.']
2236         Removed prog1.o
2237         Removed prog1
2238         Removed prog2.o
2239         Removed prog2
2240       </screen>
2241
2242     </section>
2243
2244   </section>