Deprecate $WIN32 variables name in place of $WINDOWS* variables names, and eliminate...
[scons.git] / doc / user / command-line.in
1 <!--
2
3   __COPYRIGHT__
4
5   Permission is hereby granted, free of charge, to any person obtaining
6   a copy of this software and associated documentation files (the
7   "Software"), to deal in the Software without restriction, including
8   without limitation the rights to use, copy, modify, merge, publish,
9   distribute, sublicense, and/or sell copies of the Software, and to
10   permit persons to whom the Software is furnished to do so, subject to
11   the following conditions:
12
13   The above copyright notice and this permission notice shall be included
14   in all copies or substantial portions of the Software.
15
16   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
17   KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
18   WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20   LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21   OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22   WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
24 -->
25
26   <para>
27
28   &SCons; provides a number of ways that
29   allow the writer of the &SConscript; files
30   to give users a great deal of control over how to run the builds.
31
32   </para>
33
34   <section>
35   <title>Not Having to Specify Command-Line Options Each Time:  the &SCONSFLAGS; Environment Variable</title>
36
37     <para>
38
39     Users may find themselves supplying
40     the same command-line options every time
41     they run &SCons;.
42     For example, a user might find that it saves time
43     to specify a value of <literal>-j 2</literal>
44     to run the builds in parallel.
45     To avoid having to type <literal>-j 2</literal> by hand
46     every time,
47     you can set the external environment variable
48     &SCONSFLAGS; to a string containing
49     command-line options that you want &SCons; to use.
50
51     </para>
52
53     <para>
54
55     If, for example,
56     and you're using a POSIX shell that's
57     compatible with the Bourne shell,
58     and you always want &SCons; to use the
59     <literal>-Q</literal> option,
60     you can set the &SCONSFLAGS;
61     environment as follows:
62
63     </para>
64
65     <scons_example name="SCONSFLAGS">
66       <file name="SConstruct">
67       def b(target, source, env):
68           pass
69       def s(target, source, env):
70           return "    ... [build output] ..."
71       a = Action(b, strfunction = s)
72       env = Environment(BUILDERS = {'A' : Builder(action=a)})
73       env.A('foo.out', 'foo.in')
74       </file>
75       <file name="foo.in">
76       foo.in
77       </file>
78     </scons_example>
79
80     <scons_output example="SCONSFLAGS">
81       <scons_output_command>scons</scons_output_command>
82       <scons_output_command>export SCONSFLAGS="-Q"</scons_output_command>
83       <scons_output_command environment="SCONSFLAGS=-Q">scons</scons_output_command>
84     </scons_output>
85
86     <para>
87
88     Users of &csh;-style shells on POSIX systems
89     can set the &SCONSFLAGS; environment as follows:
90
91     </para>
92
93     <screen>
94       $ <userinput>setenv SCONSFLAGS "-Q"</userinput>
95     </screen>
96
97     <para>
98
99     Windows users may typically want to set this
100     &SCONSFLAGS; in the appropriate tab of the
101     <literal>System Properties</literal> window.
102
103     </para>
104
105   </section>
106
107   <section>
108   <title>Getting at Command-Line Targets</title>
109
110     <para>
111
112     &SCons; supports a &COMMAND_LINE_TARGETS; variable
113     that lets you get at the list of targets that the
114     user specified on the command line.
115     You can use the targets to manipulate the
116     build in any way you wish.
117     As a simple example,
118     suppose that you want to print a reminder
119     to the user whenever a specific program is built.
120     You can do this by checking for the
121     target in the &COMMAND_LINE_TARGETS; list:
122
123     </para>
124
125     <scons_example name="COMMAND_LINE_TARGETS">
126       <file name="SConstruct" printme="1">
127       if 'bar' in COMMAND_LINE_TARGETS:
128           print "Don't forget to copy `bar' to the archive!"
129       Default(Program('foo.c'))
130       Program('bar.c')
131       </file>
132       <file name="foo.c">
133       foo.c
134       </file>
135       <file name="bar.c">
136       foo.c
137       </file>
138     </scons_example>
139
140     <para>
141
142     Then, running &SCons; with the default target
143     works as it always does,
144     but explicity specifying the &bar; target
145     on the command line generates the warning message:
146
147     </para>
148
149     <scons_output example="COMMAND_LINE_TARGETS">
150       <scons_output_command>scons -Q</scons_output_command>
151       <scons_output_command>scons -Q bar</scons_output_command>
152     </scons_output>
153
154     <para>
155
156     Another practical use for the &COMMAND_LINE_TARGETS; variable
157     might be to speed up a build
158     by only reading certain subsidiary &SConscript;
159     files if a specific target is requested.
160
161     </para>
162
163   </section>
164
165   <section>
166   <title>Controlling the Default Targets</title>
167
168     <para>
169
170     One of the most basic things you can control
171     is which targets &SCons; will build by default--that is,
172     when there are no targets specified on the command line.
173     As mentioned previously,
174     &SCons; will normally build every target
175     in or below the current directory
176     by default--that is, when you don't
177     explicitly specify one or more targets
178     on the command line.
179     Sometimes, however, you may want
180     to specify explicitly that only
181     certain programs, or programs in certain directories,
182     should be built by default.
183     You do this with the &Default; function:
184
185     </para>
186
187     <scons_example name="Default1">
188        <file name="SConstruct" printme="1">
189        env = Environment()
190        hello = env.Program('hello.c')
191        env.Program('goodbye.c')
192        Default(hello)
193        </file>
194        <file name="hello.c">
195        hello.c
196        </file>
197        <file name="goodbye.c">
198        goodbye.c
199        </file>
200     </scons_example>
201
202     <para>
203
204     This &SConstruct; file knows how to build two programs,
205     &hello; and &goodbye;,
206     but only builds the
207     &hello; program by default:
208
209     </para>
210
211     <scons_output example="Default1">
212        <scons_output_command>scons -Q</scons_output_command>
213        <scons_output_command>scons -Q</scons_output_command>
214        <scons_output_command>scons -Q goodbye</scons_output_command>
215     </scons_output>
216
217     <para>
218
219     Note that, even when you use the &Default;
220     function in your &SConstruct; file,
221     you can still explicitly specify the current directory
222     (<literal>.</literal>) on the command line
223     to tell &SCons; to build
224     everything in (or below) the current directory:
225
226     </para>
227
228     <scons_output example="Default1">
229        <scons_output_command>scons -Q .</scons_output_command>
230     </scons_output>
231
232     <para>
233
234     You can also call the &Default;
235     function more than once,
236     in which case each call
237     adds to the list of targets to be built by default:
238
239     </para>
240
241     <scons_example name="Default2">
242        <file name="SConstruct" printme="1">
243        env = Environment()
244        prog1 = env.Program('prog1.c')
245        Default(prog1)
246        prog2 = env.Program('prog2.c')
247        prog3 = env.Program('prog3.c')
248        Default(prog3)
249        </file>
250        <file name="prog1.c">
251        prog1.c
252        </file>
253        <file name="prog2.c">
254        prog2.c
255        </file>
256        <file name="prog3.c">
257        prog3.c
258        </file>
259     </scons_example>
260
261     <para>
262
263     Or you can specify more than one target
264     in a single call to the &Default; function:
265
266     </para>
267
268     <programlisting>
269        env = Environment()
270        prog1 = env.Program('prog1.c')
271        prog2 = env.Program('prog2.c')
272        prog3 = env.Program('prog3.c')
273        Default(prog1, prog3)
274     </programlisting>
275
276     <para>
277
278     Either of these last two examples
279     will build only the
280     <application>prog1</application>
281     and
282     <application>prog3</application>
283     programs by default:
284
285     </para>
286
287     <scons_output example="Default2">
288        <scons_output_command>scons -Q</scons_output_command>
289        <scons_output_command>scons -Q .</scons_output_command>
290     </scons_output>
291
292     <para>
293
294     You can list a directory as
295     an argument to &Default;:
296
297     </para>
298
299     <scons_example name="Default3">
300        <file name="SConstruct" printme="1">
301        env = Environment()
302        env.Program(['prog1/main.c', 'prog1/foo.c'])
303        env.Program(['prog2/main.c', 'prog2/bar.c'])
304        Default('prog1')
305        </file>
306        <directory name="prog1"></directory>
307        <directory name="prog2"></directory>
308        <file name="prog1/main.c">
309        int main() { printf("prog1/main.c\n"); }
310        </file>
311        <file name="prog1/foo.c">
312        int foo() { printf("prog1/foo.c\n"); }
313        </file>
314        <file name="prog2/main.c">
315        int main() { printf("prog2/main.c\n"); }
316        </file>
317        <file name="prog2/bar.c">
318        int bar() { printf("prog2/bar.c\n"); }
319        </file>
320     </scons_example>
321
322     <para>
323
324     In which case only the target(s) in that
325     directory will be built by default:
326
327     </para>
328
329     <scons_output example="Default3">
330        <scons_output_command>scons -Q</scons_output_command>
331        <scons_output_command>scons -Q</scons_output_command>
332        <scons_output_command>scons -Q .</scons_output_command>
333     </scons_output>
334
335     <para>
336
337     Lastly, if for some reason you don't want
338     any targets built by default,
339     you can use the Python <literal>None</literal>
340     variable:
341
342     </para>
343
344     <scons_example name="Default4">
345        <file name="SConstruct" printme="1">
346        env = Environment()
347        prog1 = env.Program('prog1.c')
348        prog2 = env.Program('prog2.c')
349        Default(None)
350        </file>
351        <file name="prog1.c">
352        prog1.c
353        </file>
354        <file name="prog2.c">
355        prog2.c
356        </file>
357     </scons_example>
358
359     <para>
360
361     Which would produce build output like:
362
363     </para>
364
365     <scons_output example="Default4">
366        <scons_output_command>scons -Q</scons_output_command>
367        <scons_output_command>scons -Q .</scons_output_command>
368     </scons_output>
369
370     <section>
371     <title>Getting at the List of Default Targets</title>
372
373       <para>
374
375       &SCons; supports a &DEFAULT_TARGETS; variable
376       that lets you get at the current list of default targets.
377       The &DEFAULT_TARGETS variable has
378       two important differences from the &COMMAND_LINE_TARGETS; variable.
379       First, the &DEFAULT_TARGETS; variable is a list of
380       internal &SCons; nodes,
381       so you need to convert the list elements to strings
382       if you want to print them or look for a specific target name.
383       Fortunately, you can do this easily
384       by using the Python <function>map</function> function
385       to run the list through <function>str</function>:
386
387       </para>
388
389       <scons_example name="DEFAULT_TARGETS_1">
390          <file name="SConstruct" printme="1">
391          prog1 = Program('prog1.c')
392          Default(prog1)
393          print "DEFAULT_TARGETS is", map(str, DEFAULT_TARGETS)
394          </file>
395          <file name="prog1.c">
396          prog1.c
397          </file>
398       </scons_example>
399
400       <para>
401
402       (Keep in mind that all of the manipulation of the
403       &DEFAULT_TARGETS; list takes place during the
404       first phase when &SCons; is reading up the &SConscript; files,
405       which is obvious if 
406       we leave off the <literal>-Q</literal> flag when we run &SCons;:)
407
408       </para>
409
410       <scons_output example="DEFAULT_TARGETS_1">
411          <scons_output_command>scons</scons_output_command>
412       </scons_output>
413
414       <para>
415
416       Second,
417       the contents of the &DEFAULT_TARGETS; list change
418       in response to calls to the &Default: function,
419       as you can see from the following &SConstruct; file:
420
421       </para>
422
423       <scons_example name="DEFAULT_TARGETS_2">
424          <file name="SConstruct" printme="1">
425          prog1 = Program('prog1.c')
426          Default(prog1)
427          print "DEFAULT_TARGETS is now", map(str, DEFAULT_TARGETS)
428          prog2 = Program('prog2.c')
429          Default(prog2)
430          print "DEFAULT_TARGETS is now", map(str, DEFAULT_TARGETS)
431          </file>
432          <file name="prog1.c">
433          prog1.c
434          </file>
435          <file name="prog2.c">
436          prog2.c
437          </file>
438       </scons_example>
439
440       <para>
441
442       Which yields the output:
443
444       </para>
445
446       <scons_output example="DEFAULT_TARGETS_2">
447          <scons_output_command>scons</scons_output_command>
448       </scons_output>
449
450       <para>
451
452       In practice, this simply means that you
453       need to pay attention to the order in
454       which you call the &Default; function
455       and refer to the &DEFAULT_TARGETS; list,
456       to make sure that you don't examine the
457       list before you've added the default targets
458       you expect to find in it.
459
460       </para>
461
462     </section>
463
464   </section>
465
466   <section>
467   <title>Getting at the List of Build Targets, Regardless of Origin</title>
468
469     <para>
470
471     We've already been introduced to the
472     &COMMAND_LINE_TARGETS; variable,
473     which contains a list of targets specified on the command line,
474     and the &DEFAULT_TARGETS; variable,
475     which contains a list of targets specified
476     via calls to the &Default; method or function.
477     Sometimes, however,
478     you want a list of whatever targets
479     &SCons; will try to build,
480     regardless of whether the targets came from the
481     command line or a &Default; call.
482     You could code this up by hand, as follows:
483
484     </para>
485
486     <sconstruct>
487       if COMMAND_LINE_TARGETS:
488           targets = COMMAND_LINE_TARGETS
489       else:
490           targets = DEFAULT_TARGETS
491     </sconstruct>
492
493     <para>
494
495     &SCons;, however, provides a convenient
496     &BUILD_TARGETS; variable
497     that eliminates the need for this by-hand manipulation.
498     Essentially, the &BUILD_TARGETS; variable
499     contains a list of the command-line targets,
500     if any were specified,
501     and if no command-line targets were specified,
502     it contains a list of the targets specified
503     via the &Default; method or function.
504
505     </para>
506
507     <para>
508
509     Because &BUILD_TARGETS; may contain a list of &SCons; nodes,
510     you must convert the list elements to strings
511     if you want to print them or look for a specific target name,
512     just like the &DEFAULT_TARGETS; list:
513
514     </para>
515
516     <scons_example name="BUILD_TARGETS_1">
517       <file name="SConstruct" printme="1">
518       prog1 = Program('prog1.c')
519       Program('prog2.c')
520       Default(prog1)
521       print "BUILD_TARGETS is", map(str, BUILD_TARGETS)
522       </file>
523       <file name="prog1.c">
524       prog1.c
525       </file>
526       <file name="prog2.c">
527       prog2.c
528       </file>
529     </scons_example>
530
531     <para>
532
533     Notice how the value of &BUILD_TARGETS;
534     changes depending on whether a target is
535     specified on the command line:
536
537     </para>
538
539     <scons_output example="BUILD_TARGETS_1">
540       <scons_output_command>scons -Q</scons_output_command>
541       <scons_output_command>scons -Q prog2</scons_output_command>
542       <scons_output_command>scons -Q -c .</scons_output_command>
543     </scons_output>
544
545   </section>
546
547   <section>
548   <title>Command-Line <varname>variable</varname>=<varname>value</varname> Build Options</title>
549
550     <para>
551
552     You may want to control various aspects
553     of your build by allowing the user
554     to specify <varname>variable</varname>=<varname>value</varname>
555     values on the command line.
556     For example, suppose you
557     want users to be able to
558     build a debug version of a program
559     by running &SCons; as follows:
560
561     </para>
562
563     <screen>
564       % <userinput>scons -Q debug=1</userinput>
565     </screen>
566
567     <para>
568
569     &SCons; provides an &ARGUMENTS; dictionary
570     that stores all of the
571     <varname>variable</varname>=<varname>value</varname>
572     assignments from the command line.
573     This allows you to modify
574     aspects of your build in response
575     to specifications on the command line.
576     (Note that unless you want to require
577     that users <emphasis>always</emphasis>
578     specify an option,
579     you probably want to use
580     the Python
581     <literal>ARGUMENTS.get()</literal> function,
582     which allows you to specify a default value
583     to be used if there is no specification
584     on the command line.)
585
586     </para>
587
588     <para>
589
590     The following code sets the &cv-link-CCFLAGS; construction
591     variable in response to the <varname>debug</varname>
592     flag being set in the &ARGUMENTS; dictionary:
593
594     </para>
595
596     <scons_example name="ARGUMENTS">
597        <file name="SConstruct" printme="1">
598        env = Environment()
599        debug = ARGUMENTS.get('debug', 0)
600        if int(debug):
601            env.Append(CCFLAGS = '-g')
602        env.Program('prog.c')
603        </file>
604        <file name="prog.c">
605        prog.c
606        </file>
607     </scons_example>
608
609     <para>
610
611     This results in the <varname>-g</varname>
612     compiler option being used when
613     <literal>debug=1</literal>
614     is used on the command line:
615
616     </para>
617
618     <scons_output example="ARGUMENTS">
619        <scons_output_command>scons -Q debug=0</scons_output_command>
620        <scons_output_command>scons -Q debug=0</scons_output_command>
621        <scons_output_command>scons -Q debug=1</scons_output_command>
622        <scons_output_command>scons -Q debug=1</scons_output_command>
623     </scons_output>
624
625     <para>
626
627     Notice that &SCons; keeps track of
628     the last values used to build the object files,
629     and as a result correctly rebuilds
630     the object and executable files
631     only when the value of the <literal>debug</literal>
632     argument has changed.
633
634     </para>
635
636   </section>
637
638   <section>
639   <title>Controlling Command-Line Build Options</title>
640
641     <para>
642
643     Being able to use a command-line build option like
644     <literal>debug=1</literal> is handy,
645     but it can be a chore to write specific Python code
646     to recognize each such option
647     and apply the values to a construction variable.
648     To help with this,
649     &SCons; supports a class to
650     define such build options easily,
651     and a mechanism to apply the
652     build options to a construction environment.
653     This allows you to control how the build options affect
654     construction environments.
655
656     </para>
657
658     <para>
659
660     For example, suppose that you want users to set
661     a &RELEASE; construction variable on the
662     command line whenever the time comes to build
663     a program for release,
664     and that the value of this variable
665     should be added to the command line
666     with the appropriate <literal>-D</literal> option
667     (or other command line option)
668     to pass the value to the C compiler.
669     Here's how you might do that by setting
670     the appropriate value in a dictionary for the
671     &cv-link-CPPDEFINES; construction variable:
672
673     </para>
674
675     <scons_example name="Options1">
676       <file name="SConstruct" printme="1">
677          opts = Options()
678          opts.Add('RELEASE', 'Set to 1 to build for release', 0)
679          env = Environment(options = opts,
680                            CPPDEFINES={'RELEASE_BUILD' : '${RELEASE}'})
681          env.Program(['foo.c', 'bar.c'])
682       </file>
683       <file name="foo.c">
684       foo.c
685       </file>
686       <file name="bar.c">
687       bar.c
688       </file>
689     </scons_example>
690
691     <para>
692
693     This &SConstruct; file first creates an
694     &Options; object
695     (the <literal>opts = Options()</literal> call),
696     and then uses the object's &Add;
697     method to indicate that the &RELEASE;
698     option can be set on the command line,
699     and that it's default value will be <literal>0</literal>
700     (the third argument to the &Add; method).
701     The second argument is a line of help text;
702     we'll learn how to use it in the next section.
703
704     </para>
705
706     <para>
707
708     We then pass the created &Options;
709     object as an &options; keyword argument
710     to the &Environment; call
711     used to create the construction environment.
712     This then allows a user to set the
713     &RELEASE; build option on the command line
714     and have the variable show up in
715     the command line used to build each object from
716     a C source file:
717
718     </para>
719
720     <scons_output example="Options1">
721       <scons_output_command>scons -Q RELEASE=1</scons_output_command>
722     </scons_output>
723
724   </section>
725
726   <section>
727   <title>Providing Help for Command-Line Build Options</title>
728
729     <para>
730
731     To make command-line build options most useful,
732     you ideally want to provide
733     some help text that will describe
734     the available options
735     when the user runs <literal>scons -h</literal>.
736     You could write this text by hand,
737     but &SCons; provides an easier way.
738     &Options; objects support a
739     &GenerateHelpText; method
740     that will, as its name indicates,
741     generate text that describes
742     the various options that
743     have been added to it.
744     You then pass the output from this method to
745     the &Help; function:
746
747     </para>
748
749     <scons_example name="Options_Help">
750       <file name="SConstruct" printme="1">
751          opts = Options('custom.py')
752          opts.Add('RELEASE', 'Set to 1 to build for release', 0)
753          env = Environment(options = opts)
754          Help(opts.GenerateHelpText(env))
755       </file>
756     </scons_example>
757
758     <para>
759
760     &SCons; will now display some useful text
761     when the <literal>-h</literal> option is used:
762
763     </para>
764
765     <scons_output example="Options_Help">
766       <scons_output_command>scons -Q -h</scons_output_command>
767     </scons_output>
768
769     <para>
770
771     Notice that the help output shows the default value,
772     and the current actual value of the build option.
773
774     </para>
775
776   </section>
777
778   <section>
779   <title>Reading Build Options From a File</title>
780
781     <para>
782
783     Being able to use a command-line build option like
784     <literal>debug=1</literal> is handy,
785     but it can be a chore to write specific Python code
786     to recognize each such option
787     and apply the values to a construction variable.
788     To help with this,
789     &SCons; supports a class to
790     define such build options easily
791     and to read build option values from a file.
792     This allows you to control how the build options affect
793     construction environments.
794     The way you do this is by specifying
795     a file name when you call &Options;,
796     like &custom_py; in the following example:
797
798     </para>
799
800     <scons_example name="Options_custom_py_1">
801       <file name="SConstruct" printme="1">
802          opts = Options('custom.py')
803          opts.Add('RELEASE', 'Set to 1 to build for release', 0)
804          env = Environment(options = opts,
805                            CPPDEFINES={'RELEASE_BUILD' : '${RELEASE}'})
806          env.Program(['foo.c', 'bar.c'])
807          Help(opts.GenerateHelpText(env))
808       </file>
809       <file name="foo.c">
810       foo.c
811       </file>
812       <file name="bar.c">
813       bar.c
814       </file>
815       <file name="custom.py">
816       RELEASE = 1
817       </file>
818     </scons_example>
819
820     <para>
821
822     This then allows us to control the &RELEASE;
823     variable by setting it in the &custom_py; file:
824
825     </para>
826
827     <scons_example_file example="Options_custom_py_1" name="custom.py"></scons_example_file>
828
829     <para>
830
831     Note that this file is actually executed
832     like a Python script.
833     Now when we run &SCons;:
834
835     </para>
836
837     <scons_output example="Options_custom_py_1">
838       <scons_output_command>scons -Q</scons_output_command>
839     </scons_output>
840
841     <para>
842
843     And if we change the contents of &custom_py; to:
844
845     </para>
846
847     <scons_example name="Options_custom_py_2">
848       <file name="SConstruct">
849          opts = Options('custom.py')
850          opts.Add('RELEASE', 'Set to 1 to build for release', 0)
851          env = Environment(options = opts,
852                            CPPDEFINES={'RELEASE_BUILD' : '${RELEASE}'})
853          env.Program(['foo.c', 'bar.c'])
854          Help(opts.GenerateHelpText(env))
855       </file>
856       <file name="foo.c">
857       foo.c
858       </file>
859       <file name="bar.c">
860       bar.c
861       </file>
862       <file name="custom.py" printme="1">
863       RELEASE = 0
864       </file>
865     </scons_example>
866
867     <para>
868
869     The object files are rebuilt appropriately
870     with the new option:
871
872     </para>
873
874     <scons_output example="Options_custom_py_2">
875       <scons_output_command>scons -Q</scons_output_command>
876     </scons_output>
877
878   </section>
879
880   <section>
881   <title>Canned Build Options</title>
882
883     <para>
884
885     &SCons; provides a number of functions
886     that provide ready-made behaviors
887     for various types of command-line build options.
888
889     </para>
890
891     <section>
892     <title>True/False Values:  the &BoolOption; Build Option</title>
893
894       <para>
895
896       It's often handy to be able to specify an
897       option that controls a simple Boolean variable
898       with a &true; or &false; value.
899       It would be even more handy to accomodate
900       users who have different preferences for how to represent
901       &true; or &false; values.
902       The &BoolOption; function
903       makes it easy to accomodate a variety of
904       common values that represent
905       &true; or &false;.
906
907       </para>
908
909       <para>
910
911       The &BoolOption; function takes three arguments:
912       the name of the build option,
913       the default value of the build option,
914       and the help string for the option.
915       It then returns appropriate information for
916       passing to the &Add; method of an &Options; object, like so:
917
918       </para>
919
920       <scons_example name="BoolOption">
921         <file name="SConstruct" printme="1">
922            opts = Options('custom.py')
923            opts.Add(BoolOption('RELEASE', 'Set to build for release', 0))
924            env = Environment(options = opts,
925                              CPPDEFINES={'RELEASE_BUILD' : '${RELEASE}'})
926            env.Program('foo.c')
927         </file>
928         <file name="foo.c">
929         foo.c
930         </file>
931       </scons_example>
932
933       <para>
934
935       With this build option,
936       the &RELEASE; variable can now be enabled by
937       setting it to the value <literal>yes</literal>
938       or <literal>t</literal>:
939
940       </para>
941
942       <scons_output example="BoolOption">
943         <scons_output_command>scons -Q RELEASE=yes foo.o</scons_output_command>
944       </scons_output>
945
946       <scons_output example="BoolOption">
947         <scons_output_command>scons -Q RELEASE=t foo.o</scons_output_command>
948       </scons_output>
949
950       <para>
951
952       Other values that equate to &true; include
953       <literal>y</literal>,
954       <literal>1</literal>,
955       <literal>on</literal>
956       and
957       <literal>all</literal>.
958
959       </para>
960
961       <para>
962
963       Conversely, &RELEASE; may now be given a &false;
964       value by setting it to
965       <literal>no</literal>
966       or
967       <literal>f</literal>:
968
969       </para>
970
971       <scons_output example="BoolOption">
972         <scons_output_command>scons -Q RELEASE=no foo.o</scons_output_command>
973       </scons_output>
974
975       <scons_output example="BoolOption">
976         <scons_output_command>scons -Q RELEASE=f foo.o</scons_output_command>
977       </scons_output>
978
979       <para>
980
981       Other values that equate to &true; include
982       <literal>n</literal>,
983       <literal>0</literal>,
984       <literal>off</literal>
985       and
986       <literal>none</literal>.
987
988       </para>
989
990       <para>
991
992       Lastly, if a user tries to specify
993       any other value,
994       &SCons; supplies an appropriate error message:
995
996       </para>
997
998       <scons_output example="BoolOption">
999         <scons_output_command>scons -Q RELEASE=bad_value foo.o</scons_output_command>
1000       </scons_output>
1001
1002     </section>
1003
1004     <section>
1005     <title>Single Value From a List:  the &EnumOption; Build Option</title>
1006
1007       <para>
1008
1009       Suppose that we want a user to be able to
1010       set a &COLOR; option
1011       that selects a background color to be
1012       displayed by an application,
1013       but that we want to restrict the
1014       choices to a specific set of allowed colors.
1015       This can be set up quite easily
1016       using the &EnumOption;,
1017       which takes a list of &allowed_values
1018       in addition to the variable name,
1019       default value,
1020       and help text arguments:
1021
1022       </para>
1023
1024       <scons_example name="EnumOption">
1025         <file name="SConstruct" printme="1">
1026            opts = Options('custom.py')
1027            opts.Add(EnumOption('COLOR', 'Set background color', 'red',
1028                                allowed_values=('red', 'green', 'blue')))
1029            env = Environment(options = opts,
1030                              CPPDEFINES={'COLOR' : '"${COLOR}"'})
1031            env.Program('foo.c')
1032         </file>
1033         <file name="foo.c">
1034         foo.c
1035         </file>
1036       </scons_example>
1037
1038       <para>
1039
1040       The user can now explicity set the &COLOR; build option
1041       to any of the specified allowed values:
1042
1043       </para>
1044
1045       <scons_output example="EnumOption">
1046         <scons_output_command>scons -Q COLOR=red foo.o</scons_output_command>
1047         <scons_output_command>scons -Q COLOR=blue foo.o</scons_output_command>
1048         <scons_output_command>scons -Q COLOR=green foo.o</scons_output_command>
1049       </scons_output>
1050
1051       <para>
1052
1053       But, almost more importantly,
1054       an attempt to set &COLOR;
1055       to a value that's not in the list
1056       generates an error message:
1057
1058       </para>
1059
1060       <scons_output example="EnumOption">
1061         <scons_output_command>scons -Q COLOR=magenta foo.o</scons_output_command>
1062       </scons_output>
1063
1064       <para>
1065
1066       The &EnumOption; function also supports a way
1067       to map alternate names to allowed values.
1068       Suppose, for example,
1069       that we want to allow the user
1070       to use the word <literal>navy</literal> as a synonym for
1071       <literal>blue</literal>.
1072       We do this by adding a &map; dictionary
1073       that will map its key values
1074       to the desired legal value:
1075
1076       </para>
1077
1078       <scons_example name="EnumOption_map">
1079         <file name="SConstruct" printme="1">
1080            opts = Options('custom.py')
1081            opts.Add(EnumOption('COLOR', 'Set background color', 'red',
1082                                allowed_values=('red', 'green', 'blue'),
1083                                map={'navy':'blue'}))
1084            env = Environment(options = opts,
1085                              CPPDEFINES={'COLOR' : '"${COLOR}"'})
1086            env.Program('foo.c')
1087         </file>
1088         <file name="foo.c">
1089         foo.c
1090         </file>
1091       </scons_example>
1092
1093       <para>
1094
1095       As desired, the user can then use
1096       <literal>navy</literal> on the command line,
1097       and &SCons; will translate it into <literal>blue</literal>
1098       when it comes time to use the &COLOR;
1099       option to build a target:
1100
1101       </para>
1102
1103       <scons_output example="EnumOption_map">
1104         <scons_output_command>scons -Q COLOR=navy foo.o</scons_output_command>
1105       </scons_output>
1106
1107       <para>
1108
1109       By default, when using the &EnumOption; function,
1110       arguments that differ
1111       from the legal values
1112       only in case
1113       are treated as illegal values:
1114
1115       </para>
1116
1117       <scons_output example="EnumOption">
1118         <scons_output_command>scons -Q COLOR=Red foo.o</scons_output_command>
1119         <scons_output_command>scons -Q COLOR=BLUE foo.o</scons_output_command>
1120         <scons_output_command>scons -Q COLOR=nAvY foo.o</scons_output_command>
1121       </scons_output>
1122
1123       <para>
1124
1125       The &EnumOption; function can take an additional
1126       &ignorecase; keyword argument that,
1127       when set to <literal>1</literal>,
1128       tells &SCons; to allow case differences
1129       when the values are specified:
1130
1131       </para>
1132
1133       <scons_example name="EnumOption_ic1">
1134         <file name="SConstruct" printme="1">
1135            opts = Options('custom.py')
1136            opts.Add(EnumOption('COLOR', 'Set background color', 'red',
1137                                allowed_values=('red', 'green', 'blue'),
1138                                map={'navy':'blue'},
1139                                ignorecase=1))
1140            env = Environment(options = opts,
1141                              CPPDEFINES={'COLOR' : '"${COLOR}"'})
1142            env.Program('foo.c')
1143         </file>
1144         <file name="foo.c">
1145         foo.c
1146         </file>
1147       </scons_example>
1148
1149       <para>
1150
1151       Which yields the output:
1152
1153       </para>
1154
1155       <scons_output example="EnumOption_ic1">
1156         <scons_output_command>scons -Q COLOR=Red foo.o</scons_output_command>
1157         <scons_output_command>scons -Q COLOR=BLUE foo.o</scons_output_command>
1158         <scons_output_command>scons -Q COLOR=nAvY foo.o</scons_output_command>
1159         <scons_output_command>scons -Q COLOR=green foo.o</scons_output_command>
1160       </scons_output>
1161
1162       <para>
1163
1164       Notice that an &ignorecase; value of <literal>1</literal>
1165       preserves the case-spelling that the user supplied.
1166       If you want &SCons; to translate the names
1167       into lower-case,
1168       regardless of the case used by the user,
1169       specify an &ignorecase; value of <literal>2</literal>:
1170
1171       </para>
1172
1173       <scons_example name="EnumOption_ic2">
1174         <file name="SConstruct" printme="1">
1175            opts = Options('custom.py')
1176            opts.Add(EnumOption('COLOR', 'Set background color', 'red',
1177                                allowed_values=('red', 'green', 'blue'),
1178                                map={'navy':'blue'},
1179                                ignorecase=2))
1180            env = Environment(options = opts,
1181                              CPPDEFINES={'COLOR' : '"${COLOR}"'})
1182            env.Program('foo.c')
1183         </file>
1184         <file name="foo.c">
1185         foo.c
1186         </file>
1187       </scons_example>
1188
1189       <para>
1190
1191       Now &SCons; will use values of
1192       <literal>red</literal>,
1193       <literal>green</literal> or
1194       <literal>blue</literal>
1195       regardless of how the user spells
1196       those values on the command line:
1197
1198       </para>
1199
1200       <scons_output example="EnumOption_ic2">
1201         <scons_output_command>scons -Q COLOR=Red foo.o</scons_output_command>
1202         <scons_output_command>scons -Q COLOR=nAvY foo.o</scons_output_command>
1203         <scons_output_command>scons -Q COLOR=GREEN foo.o</scons_output_command>
1204       </scons_output>
1205
1206     </section>
1207
1208     <section>
1209     <title>Multiple Values From a List:  the &ListOption; Build Option</title>
1210
1211       <para>
1212
1213       Another way in which you might want to allow users
1214       to control build option is to
1215       specify a list of one or more legal values.
1216       &SCons; supports this through the &ListOption; function.
1217       If, for example, we want a user to be able to set a
1218       &COLORS; option to one or more of the legal list of values:
1219
1220       </para>
1221
1222       <scons_example name="ListOption">
1223         <file name="SConstruct" printme="1">
1224            opts = Options('custom.py')
1225            opts.Add(ListOption('COLORS', 'List of colors', 0,
1226                                ['red', 'green', 'blue']))
1227            env = Environment(options = opts,
1228                              CPPDEFINES={'COLORS' : '"${COLORS}"'})
1229            env.Program('foo.c')
1230         </file>
1231         <file name="foo.c">
1232         foo.c
1233         </file>
1234       </scons_example>
1235
1236       <para>
1237
1238       A user can now specify a comma-separated list
1239       of legal values,
1240       which will get translated into a space-separated
1241       list for passing to the any build commands:
1242
1243       </para>
1244
1245       <scons_output example="ListOption">
1246         <scons_output_command>scons -Q COLORS=red,blue foo.o</scons_output_command>
1247         <scons_output_command>scons -Q COLORS=blue,green,red foo.o</scons_output_command>
1248       </scons_output>
1249
1250       <para>
1251
1252       In addition, the &ListOption; function
1253       allows the user to specify explicit keywords of
1254       &all; or &none;
1255       to select all of the legal values,
1256       or none of them, respectively:
1257
1258       </para>
1259
1260       <scons_output example="ListOption">
1261         <scons_output_command>scons -Q COLORS=all foo.o</scons_output_command>
1262         <scons_output_command>scons -Q COLORS=none foo.o</scons_output_command>
1263       </scons_output>
1264
1265       <para>
1266
1267       And, of course, an illegal value
1268       still generates an error message:
1269
1270       </para>
1271
1272       <scons_output example="ListOption">
1273         <scons_output_command>scons -Q COLORS=magenta foo.o</scons_output_command>
1274       </scons_output>
1275
1276     </section>
1277
1278     <section>
1279     <title>Path Names:  the &PathOption; Build Option</title>
1280
1281       <para>
1282
1283       &SCons; supports a &PathOption; function
1284       to make it easy to create a build option
1285       to control an expected path name.
1286       If, for example, you need to
1287       define a variable in the preprocessor
1288       that control the location of a
1289       configuration file:
1290
1291       </para>
1292
1293       <scons_example name="PathOption">
1294         <file name="SConstruct" printme="1">
1295            opts = Options('custom.py')
1296            opts.Add(PathOption('CONFIG',
1297                                'Path to configuration file',
1298                                '__ROOT__/etc/my_config'))
1299            env = Environment(options = opts,
1300                              CPPDEFINES={'CONFIG_FILE' : '"$CONFIG"'})
1301            env.Program('foo.c')
1302         </file>
1303         <file name="foo.c">
1304         foo.c
1305         </file>
1306         <file name="__ROOT__/etc/my_config">
1307         /opt/location
1308         </file>
1309         <file name="__ROOT__/usr/local/etc/other_config">
1310         /opt/location
1311         </file>
1312       </scons_example>
1313
1314       <para>
1315
1316       This then allows the user to
1317       override the &CONFIG; build option
1318       on the command line as necessary:
1319
1320       </para>
1321
1322       <scons_output example="PathOption">
1323         <scons_output_command>scons -Q foo.o</scons_output_command>
1324         <scons_output_command>scons -Q CONFIG=__ROOT__/usr/local/etc/other_config foo.o</scons_output_command>
1325       </scons_output>
1326
1327       <para>
1328
1329       By default, &PathOption; checks to make sure
1330       that the specified path exists and generates an error if it
1331       doesn't:
1332
1333       </para>
1334
1335       <scons_output example="PathOption">
1336         <scons_output_command>scons -Q CONFIG=__ROOT__/does/not/exist foo.o</scons_output_command>
1337       </scons_output>
1338
1339       <para>
1340
1341       &PathOption; provides a number of methods
1342       that you can use to change this behavior.
1343       If you want to ensure that any specified paths are,
1344       in fact, files and not directories,
1345       use the &PathOption_PathIsFile; method:
1346
1347       </para>
1348
1349       <scons_example name="PathIsFile">
1350         <file name="SConstruct" printme="1">
1351            opts = Options('custom.py')
1352            opts.Add(PathOption('CONFIG',
1353                                'Path to configuration file',
1354                                '__ROOT__/etc/my_config',
1355                                PathOption.PathIsFile))
1356            env = Environment(options = opts,
1357                              CPPDEFINES={'CONFIG_FILE' : '"$CONFIG"'})
1358            env.Program('foo.c')
1359         </file>
1360         <file name="foo.c">
1361         foo.c
1362         </file>
1363         <file name="__ROOT__/etc/my_config">
1364         /opt/location
1365         </file>
1366       </scons_example>
1367
1368       <para>
1369
1370       Conversely, to ensure that any specified paths are
1371       directories and not files,
1372       use the &PathOption_PathIsDir; method:
1373
1374       </para>
1375
1376       <scons_example name="PathIsDir">
1377         <file name="SConstruct" printme="1">
1378            opts = Options('custom.py')
1379            opts.Add(PathOption('DBDIR',
1380                                'Path to database directory',
1381                                '__ROOT__/var/my_dbdir',
1382                                PathOption.PathIsDir))
1383            env = Environment(options = opts,
1384                              CPPDEFINES={'DBDIR' : '"$DBDIR"'})
1385            env.Program('foo.c')
1386         </file>
1387         <file name="foo.c">
1388         foo.c
1389         </file>
1390         <file name="__ROOT__/var/my_dbdir">
1391         /opt/location
1392         </file>
1393       </scons_example>
1394
1395       <para>
1396
1397       If you want to make sure that any specified paths
1398       are directories,
1399       and you would like the directory created
1400       if it doesn't already exist,
1401       use the &PathOption_PathIsDirCreate; method:
1402
1403       </para>
1404
1405       <scons_example name="PathIsDirCreate">
1406         <file name="SConstruct" printme="1">
1407            opts = Options('custom.py')
1408            opts.Add(PathOption('DBDIR',
1409                                'Path to database directory',
1410                                '__ROOT__/var/my_dbdir',
1411                                PathOption.PathIsDirCreate))
1412            env = Environment(options = opts,
1413                              CPPDEFINES={'DBDIR' : '"$DBDIR"'})
1414            env.Program('foo.c')
1415         </file>
1416         <file name="foo.c">
1417         foo.c
1418         </file>
1419         <file name="__ROOT__/var/my_dbdir">
1420         /opt/location
1421         </file>
1422       </scons_example>
1423
1424       <para>
1425
1426       Lastly, if you don't care whether the path exists,
1427       is a file, or a directory,
1428       use the &PathOption_PathAccept; method
1429       to accept any path that the user supplies:
1430
1431       </para>
1432
1433       <scons_example name="PathAccept">
1434         <file name="SConstruct" printme="1">
1435            opts = Options('custom.py')
1436            opts.Add(PathOption('OUTPUT',
1437                                'Path to output file or directory',
1438                                None,
1439                                PathOption.PathAccept))
1440            env = Environment(options = opts,
1441                              CPPDEFINES={'OUTPUT' : '"$OUTPUT"'})
1442            env.Program('foo.c')
1443         </file>
1444         <file name="foo.c">
1445         foo.c
1446         </file>
1447       </scons_example>
1448
1449     </section>
1450
1451     <section>
1452     <title>Enabled/Disabled Path Names: the &PackageOption; Build Option</title>
1453
1454       <para>
1455
1456       Sometimes you want to give users
1457       even more control over a path name variable,
1458       allowing them to explicitly enable or
1459       disable the path name
1460       by using <literal>yes</literal> or <literal>no</literal> keywords,
1461       in addition to allow them
1462       to supply an explicit path name.
1463       &SCons; supports the &PackageOption;
1464       function to support this:
1465
1466       </para>
1467
1468       <scons_example name="PackageOption">
1469         <file name="SConstruct" printme="1">
1470            opts = Options('custom.py')
1471            opts.Add(PackageOption('PACKAGE',
1472                                   'Location package',
1473                                   '__ROOT__/opt/location'))
1474            env = Environment(options = opts,
1475                              CPPDEFINES={'PACKAGE' : '"$PACKAGE"'})
1476            env.Program('foo.c')
1477         </file>
1478         <file name="foo.c">
1479         foo.c
1480         </file>
1481         <file name="__ROOT__/opt/location">
1482         /opt/location
1483         </file>
1484         <file name="__ROOT__/usr/local/location">
1485         /opt/location
1486         </file>
1487       </scons_example>
1488
1489       <para>
1490
1491       When the &SConscript; file uses the &PackageOption; funciton,
1492       user can now still use the default
1493       or supply an overriding path name,
1494       but can now explicitly set the
1495       specified variable to a value
1496       that indicates the package should be enabled
1497       (in which case the default should be used)
1498       or disabled:
1499
1500       </para>
1501
1502       <scons_output example="PackageOption">
1503         <scons_output_command>scons -Q foo.o</scons_output_command>
1504         <scons_output_command>scons -Q PACKAGE=__ROOT__/usr/local/location foo.o</scons_output_command>
1505         <scons_output_command>scons -Q PACKAGE=yes foo.o</scons_output_command>
1506         <scons_output_command>scons -Q PACKAGE=no foo.o</scons_output_command>
1507       </scons_output>
1508
1509     </section>
1510
1511   </section>
1512
1513   <section>
1514   <title>Adding Multiple Command-Line Build Options at Once</title>
1515
1516     <para>
1517
1518     Lastly, &SCons; provides a way to add
1519     multiple build options to an &Options object at once.
1520     Instead of having to call the &Add; method
1521     multiple times,
1522     you can call the &AddOptions;
1523     method with a list of build options
1524     to be added to the object.
1525     Each build option is specified
1526     as either a tuple of arguments,
1527     just like you'd pass to the &Add; method itself,
1528     or as a call to one of the canned
1529     functions for pre-packaged command-line build options.
1530     in any order:
1531
1532     </para>
1533
1534     <scons_example name="AddOptions_1">
1535       <file name="SConstruct" printme="1">
1536         opts = Options()
1537         opts.AddOptions(
1538             ('RELEASE', 'Set to 1 to build for release', 0),
1539             ('CONFIG', 'Configuration file', '/etc/my_config'),
1540             BoolOption('warnings', 'compilation with -Wall and similiar', 1),
1541             EnumOption('debug', 'debug output and symbols', 'no',
1542                        allowed_values=('yes', 'no', 'full'),
1543                        map={}, ignorecase=0),  # case sensitive
1544             ListOption('shared',
1545                        'libraries to build as shared libraries',
1546                        'all',
1547                        names = list_of_libs),
1548             PackageOption('x11',
1549                           'use X11 installed here (yes = search some places)',
1550                           'yes'),
1551             PathOption('qtdir', 'where the root of Qt is installed', qtdir),
1552         )
1553       </file>
1554     </scons_example>
1555
1556     <para>
1557     </para>
1558
1559   </section>