[ci skip] multi-user should be multiuser
[scons.git] / doc / user / command-line.xml
blob5245edf9b31f116b0fa2b6d5a666da258753f122
1 <?xml version='1.0'?>
3 <!--
4 SPDX-FileCopyrightText: Copyright The SCons Foundation (https://scons.org)
5 SPDX-License-Identifier: MIT
6 SPDX-FileType: DOCUMENTATION
8 This file is processed by the bin/SConsDoc.py module.
9 -->
11 <!DOCTYPE sconsdoc [
12     <!ENTITY % scons SYSTEM "../scons.mod">
13     %scons;
15     <!ENTITY % builders-mod SYSTEM "../generated/builders.mod">
16     %builders-mod;
17     <!ENTITY % functions-mod SYSTEM "../generated/functions.mod">
18     %functions-mod;
19     <!ENTITY % tools-mod SYSTEM "../generated/tools.mod">
20     %tools-mod;
21     <!ENTITY % variables-mod SYSTEM "../generated/variables.mod">
22     %variables-mod;
26 <chapter id="chap-command-line"
27          xmlns="http://www.scons.org/dbxsd/v1.0"
28          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
29          xsi:schemaLocation="http://www.scons.org/dbxsd/v1.0 http://www.scons.org/dbxsd/v1.0/scons.xsd">
30 <title>Controlling a Build From the Command Line</title>
32   <para>
34   Software builds are rarely completely static,
35   so &SCons; gives you a number of ways to help control
36   build execution via instructions on the command line.
37   The arguments that can be specified on
38   the command line are broken down into three types:
40   </para>
42   <variablelist>
44     <varlistentry>
45     <term>Options</term>
47     <listitem>
48     <para>
50     Command-line arguments that begin with a
51     <literal>-</literal> (hyphen) characters
52     are called <firstterm>options</firstterm>.
53     &SCons; provides ways for you to examine
54     and act on options and their values,
55     as well as the ability to define custom options
56     for your project.
57     See <xref linkend="sect-command-line-options"></xref>, below.
59     </para>
60     </listitem>
61     </varlistentry>
63     <varlistentry>
64     <term>Variables</term>
66     <listitem>
67     <para>
69     Command-line arguments containing an <literal>=</literal>
70     (equal sign) character are called <firstterm>build variables</firstterm>
71     (or just <firstterm>variables</firstterm>).
72     &SCons; provides direct access to
73     all of the build variable settings from the command line,
74     as well as a higher-level interface that lets you
75     define known build variables,
76     including defining types, default values, help text,
77     and automatic validation,
78     as well as applying those to a &consenv;.
79     See <xref linkend="sect-command-line-variables"></xref>, below.
81     </para>
82     </listitem>
83     </varlistentry>
85     <varlistentry>
86     <term>Targets</term>
88     <listitem>
89     <para>
91     Command-line arguments that are neither options
92     nor build variables
93     (that is, do not begin with a hyphen
94     and do not contain an equal sign)
95     are considered <firstterm>targets</firstterm>
96     that you are telling &SCons; to build.
97     &SCons; provides access to the list of specified targets,
98     as well as ways to set the default list of targets
99     from within the &SConscript; files.
100     See <xref linkend="sect-command-line-targets"></xref>, below.
102     </para>
103     </listitem>
104     </varlistentry>
106   </variablelist>
108   <section id="sect-command-line-options">
109   <title>Command-Line Options</title>
111     <para>
113     &SCons; has many command-line options that control its behavior.
114     A command-line option always begins with one
115     or two hyphen (<literal>-</literal>) characters.
116     The &SCons; manual page contains the description of
117     the current options
118     (see <ulink url="https://scons.org/doc/production/HTML/scons-man.html"/>).
120     </para>
122     <section id="sect-SCONSFLAGS">
123     <title>How To Avoid Typing Command-Line Options Each Time:  the &SCONSFLAGS; Environment Variable</title>
125       <para>
127       You may find yourself using
128       certain command-line options every time
129       you run &SCons;.
130       For example, you might find it saves time
131       to specify <userinput>-j 2</userinput>
132       to have &SCons; run up to two build commands in parallel.
133       To avoid having to type <userinput>-j 2</userinput> by hand
134       every time,
135       you can set the external environment variable
136       &SCONSFLAGS; to a string containing
137       <option>-j 2</option>, as well as any other
138       command-line options that you want &SCons; to always use.
139       &SCONSFLAGS; is an exception to the usual rule that
140       &SCons; itself avoids looking at environment variables from the
141       shell you are running.
143       </para>
145       <para>
147       If, for example,
148       you are using a POSIX shell such as <command>bash</command>
149       or <command>zsh</command>
150       and you always want &SCons; to use the
151       <option>-Q</option> option,
152       you can set the &SCONSFLAGS;
153       environment as follows:
155       </para>
157       <scons_example name="commandline_SCONSFLAGS">
158         <file name="SConstruct">
159 def b(target, source, env):
160     pass
162 def s(target, source, env):
163     return "    ... [build output] ..."
165 a = Action(b, strfunction=s)
166 env = Environment(BUILDERS={'A': Builder(action=a)})
167 env.A('foo.out', 'foo.in')
168         </file>
169         <file name="foo.in">
170 foo.in
171         </file>
172       </scons_example>
174       <scons_output example="commandline_SCONSFLAGS" suffix="1">
175         <scons_output_command>scons</scons_output_command>
176         <scons_output_command>export SCONSFLAGS="-Q"</scons_output_command>
177         <scons_output_command environment="SCONSFLAGS=-Q">scons</scons_output_command>
178       </scons_output>
180       <para>
182       For &csh;-style shells on POSIX systems
183       you can set the &SCONSFLAGS; environment variable as follows:
185       </para>
187       <screen>
188 $ <userinput>setenv SCONSFLAGS "-Q"</userinput>
189       </screen>
191       <para>
193       For the Windows command shell (<command>cmd</command>)
194       you can set the &SCONSFLAGS; environment variable as follows:
196       </para>
198       <screen>
199 C:\Users\foo> <userinput>set SCONSFLAGS="-Q"</userinput>
200       </screen>
202       <para>
204       To set &SCONSFLAGS; more permanently you can add the
205       setting to the shell's startup file on POSIX systems,
206       and on Windows you can use the
207       <literal>System Properties</literal> control panel applet
208       to select <literal>Environment Variables</literal>
209       and set it there.
211       </para>
213     </section>
215     <section id="sect-GetOption">
216     <title>Getting Values Set by Command-Line Options:  the &GetOption; Function</title>
218       <para>
220       The &f-link-GetOption; function
221       lets you query the values set by the various command-line options.
223       </para>
225       <para>
227       One use case for &GetOption; is to check the operation
228       mode in order to bypass some steps,
229       for example, checking whether
230       the <option>-h</option> (or <option>--help</option>)
231       option was given.
232       Normally, &SCons; does not print its help text
233       until after it has read all of the SConscript files,
234       since any SConscript can make additions to the help text.
235       Of course, reading all of the SConscript files
236       takes extra time.
237       If you know that your configuration does not define
238       any additional help text in subsidiary SConscript files,
239       you can speed up displaying the command-line help
240       by using a &GetOption; query as a guard for whether
241       to load the subsidiary SConscript files:
243       </para>
245       <sconstruct>
246 if not GetOption('help'):
247     SConscript('src/SConscript', export='env')
248       </sconstruct>
250       <para>
252       The same technique can be used to special-case the
253       clean (<literal>GetOption('clean')</literal>)
254       and no-execute (<literal>GetOption('no_exec')</literal>)
255       modes.
257       </para>
259       <para>
261       In general, the string that you pass to the
262       &f-GetOption; function to fetch the value of a command-line
263       option setting is the same as the "most common" long option name
264       (beginning with two hyphen characters),
265       although there are some exceptions.
266       The list of &SCons; command-line options
267       and the &f-GetOption; strings for fetching them,
268       are available in the
269       <xref linkend="sect-command-line-option-strings"></xref> section,
270       below.
272       </para>
274       <para>
276       &f-GetOption; can be used to retrieve the values of options
277       defined by calls to &f-link-AddOption;. A &f-GetOption; call
278       must appear after the &f-AddOption; call for that option
279       (unlike the defining of build targets,
280       this is a case where "order matters" in &SCons;).
281       If the &f-AddOption; call supplied a <parameter>dest</parameter>
282       keyword argument, a string with that name is what to pass
283       as the argument to &f-GetOption;, otherwise it is a
284       (possibly modified) version of the first long option name -
285       see &f-link-AddOption;.
287       </para>
289     </section>
291     <section id="sect-SetOption">
292     <title>Setting Values of Command-Line Options:  the &SetOption; Function</title>
294       <para>
296       You can also set the values of certain (but not all) &SCons;
297       command-line options from within the &SConscript; files
298       by using the &f-link-SetOption; function.
299       The strings that you use to set the values of &SCons;
300       command-line options are available in the
301       <xref linkend="sect-command-line-option-strings"></xref> section,
302       below.
304       </para>
306       <para>
308       One use of the &SetOption; function is to
309       specify a value for the <option>-j</option>
310       or <option>--jobs</option> option,
311       so that you get the improved performance
312       of a parallel build without having to specify the option by hand.
313       A complicating factor is that a good value
314       for the <option>-j</option> option is
315       somewhat system-dependent.
316       One rough guideline is that the more processors
317       your system has,
318       the higher you want to set the
319       <option>-j</option> value,
320       in order to take advantage of the number of CPUs.
322       </para>
324       <para>
326       For example, suppose the administrators
327       of your development systems
328       have standardized on setting a
329       <envar>NUM_CPU</envar> environment variable
330       to the number of processors on each system.
331       A little bit of Python code
332       to access the environment variable
333       and the &SetOption; function
334       provides the right level of flexibility:
336       </para>
338       <scons_example name="commandline_SetOption">
339         <file name="SConstruct" printme="1">
340 import os
342 num_cpu = int(os.environ.get('NUM_CPU', 2))
343 SetOption('num_jobs', num_cpu)
344 print("running with -j %s" % GetOption('num_jobs'))
345         </file>
346         <file name="foo.in">
347 foo.in
348         </file>
349       </scons_example>
351       <para>
353       The above snippet of code
354       sets the value of the <option>--jobs</option> option
355       to the value specified in the
356       <varname>NUM_CPU</varname> environment variable.
357       (This is one of the exception cases
358       where the string is spelled differently from
359       the command-line option.
360       The string for fetching or setting the <option>--jobs</option>
361       value is <parameter>num_jobs</parameter>
362       for historical reasons.)
363       The code in this example prints the <parameter>num_jobs</parameter>
364       value for illustrative purposes.
365       It uses a default value of <literal>2</literal>
366       to provide some minimal parallelism even on
367       single-processor systems:
369       </para>
371       <scons_output example="commandline_SetOption" suffix="1">
372         <scons_output_command>scons -Q</scons_output_command>
373       </scons_output>
375       <para>
377       But if the <envar>NUM_CPU</envar>
378       environment variable is set,
379       then use that for the default number of jobs:
381       </para>
383       <scons_output example="commandline_SetOption" suffix="2">
384         <scons_output_command>export NUM_CPU="4"</scons_output_command>
385         <scons_output_command environment="NUM_CPU=4">scons -Q</scons_output_command>
386       </scons_output>
388       <para>
390       But any explicit
391       <option>-j</option> or <option>--jobs</option>
392       value you specify on the command line is used first,
393       whether
394       the <envar>NUM_CPU</envar> environment
395       variable is set or not:
397       </para>
399       <scons_output example="commandline_SetOption" suffix="3">
400         <scons_output_command>scons -Q -j 7</scons_output_command>
401         <scons_output_command>export NUM_CPU="4"</scons_output_command>
402         <scons_output_command environment="NUM_CPU=4">scons -Q -j 3</scons_output_command>
403       </scons_output>
405     </section>
407     <section id="sect-command-line-option-strings">
408     <title>Strings for Getting or Setting Values of &SCons; Command-Line Options</title>
410       <para>
412       The strings that you can pass to the &f-link-GetOption;
413       and &f-link-SetOption; functions usually correspond to the
414       first long-form option name
415       (that is,  name beginning with two hyphen characters:  <literal>--</literal>),
416       after replacing any remaining hyphen characters
417       with underscores.
419       </para>
421       <para>
423       &SetOption; works for options added with &AddOption;,
424       but only if they were created with
425       <parameter>settable=True</parameter> in the call to &AddOption;
426       (only available in SCons 4.8.0 and later).
428       </para>
430       <para>
432       The full list of strings and the variables they
433       correspond to is as follows:
435       </para>
437       <informaltable>
438       <tgroup cols="2" align="left">
440       <thead>
442       <row>
443       <entry>String for &GetOption; and &SetOption;</entry>
444       <entry>Command-Line Option(s)</entry>
445       </row>
447       </thead>
449       <tbody>
451       <row>
452       <entry><literal>cache_debug</literal></entry>
453       <entry><option>--cache-debug</option></entry>
454       </row>
456       <row>
457       <entry><literal>cache_disable</literal></entry>
458       <entry><option>--cache-disable</option></entry>
459       </row>
461       <row>
462       <entry><literal>cache_force</literal></entry>
463       <entry><option>--cache-force</option></entry>
464       </row>
466       <row>
467       <entry><literal>cache_show</literal></entry>
468       <entry><option>--cache-show</option></entry>
469       </row>
471       <row>
472       <entry><literal>clean</literal></entry>
473       <entry><option>-c</option>,
474            <option>--clean</option>,
475            <option>--remove</option></entry>
476       </row>
478       <row>
479       <entry><literal>config</literal></entry>
480       <entry><option>--config</option></entry>
481       </row>
483       <row>
484       <entry><literal>directory</literal></entry>
485       <entry><option>-C</option>,
486              <option>--directory</option></entry>
487       </row>
489       <row>
490       <entry><literal>diskcheck</literal></entry>
491       <entry><option>--diskcheck</option></entry>
492       </row>
494       <row>
495       <entry><literal>duplicate</literal></entry>
496       <entry><option>--duplicate</option></entry>
497       </row>
499       <row>
500       <entry><literal>file</literal></entry>
501       <entry><option>-f</option>,
502              <option>--file</option>,
503              <option>--makefile </option>,
504              <option>--sconstruct</option></entry>
505       </row>
507       <row>
508       <entry><literal>help</literal></entry>
509       <entry><option>-h</option>,
510              <option>--help</option></entry>
511       </row>
513       <row>
514       <entry><literal>ignore_errors</literal></entry>
515       <entry><option>--ignore-errors</option></entry>
516       </row>
518       <row>
519       <entry><literal>implicit_cache</literal></entry>
520       <entry><option>--implicit-cache</option></entry>
521       </row>
523       <row>
524       <entry><literal>implicit_deps_changed</literal></entry>
525       <entry><option>--implicit-deps-changed</option></entry>
526       </row>
528       <row>
529       <entry><literal>implicit_deps_unchanged</literal></entry>
530       <entry><option>--implicit-deps-unchanged</option></entry>
531       </row>
533       <row>
534       <entry><literal>interactive</literal></entry>
535       <entry><option>--interact</option>,
536              <option>--interactive</option></entry>
537       </row>
539       <row>
540       <entry><literal>keep_going</literal></entry>
541       <entry><option>-k</option>,
542              <option>--keep-going</option></entry>
543       </row>
545       <row>
546       <entry><literal>max_drift</literal></entry>
547       <entry><option>--max-drift</option></entry>
548       </row>
550       <row>
551       <entry><literal>no_exec</literal></entry>
552       <entry><option>-n</option>,
553              <option>--no-exec</option>,
554              <option>--just-print</option>,
555              <option>--dry-run</option>,
556              <option>--recon</option></entry>
557       </row>
559       <row>
560       <entry><literal>no_site_dir</literal></entry>
561       <entry><option>--no-site-dir</option></entry>
562       </row>
564       <row>
565       <entry><literal>num_jobs</literal></entry>
566       <entry><option>-j</option>,
567              <option>--jobs</option></entry>
568       </row>
570       <row>
571       <entry><literal>profile_file</literal></entry>
572       <entry><option>--profile</option></entry>
573       </row>
575       <row>
576       <entry><literal>question</literal></entry>
577       <entry><option>-q</option>,
578              <option>--question</option></entry>
579       </row>
581       <row>
582       <entry><literal>random</literal></entry>
583       <entry><option>--random</option></entry>
584       </row>
586       <row>
587       <entry><literal>repository</literal></entry>
588       <entry><option>-Y</option>,
589              <option>--repository</option>,
590              <option>--srcdir</option></entry>
591       </row>
593       <row>
594       <entry><literal>silent</literal></entry>
595       <entry><option>-s</option>,
596              <option>--silent</option>,
597              <option>--quiet</option></entry>
598       </row>
600       <row>
601       <entry><literal>site_dir</literal></entry>
602       <entry><option>--site-dir</option></entry>
603       </row>
605       <row>
606       <entry><literal>stack_size</literal></entry>
607       <entry><option>--stack-size</option></entry>
608       </row>
610       <row>
611       <entry><literal>taskmastertrace_file</literal></entry>
612       <entry><option>--taskmastertrace</option></entry>
613       </row>
615       <row>
616       <entry><literal>warn</literal></entry>
617       <entry><option>--warn</option> <option>--warning</option></entry>
618       </row>
620       </tbody>
622       </tgroup>
623       </informaltable>
625     </section>
627     <section id="sect-AddOption">
628     <title>Adding Custom Command-Line Options:  the &AddOption; Function</title>
630       <para>
632       You can also define your own command-line options
633       for the project with the &f-link-AddOption; function.
634       The &AddOption; function takes the same arguments
635       as the <function>add_option</function> method
636       from the &Python; standard library module
637       <systemitem>optparse</systemitem>
638       <footnote>
639       <para>
640       The &AddOption; function is,
641       in fact, implemented using a subclass
642       of <classname>optparse.OptionParser</classname>.
643       </para>
644       </footnote>
645       (see <ulink url="https://docs.python.org/3/library/optparse.html"/>).
646       </para>
648       <para>
649       Once you add a custom command-line option
650       with the &AddOption; function,
651       the value of the option (if any) is immediately available
652       using the &f-link-GetOption; function.
653       The argument to &f-GetOption; must be the name of the
654       variable which holds the option.
655       If the <parameter>dest</parameter>
656       keyword argument to &AddOption; is specified, the value is the
657       variable name.
658       given. If not given, it is the name
659       (without the leading hyphens) of the first long option name
660       given to &AddOption;
661       after replacing any remaining hyphen characters
662       with underscores, since hyphens are not legal in Python
663       identifier names.
665       </para>
667       <para>
669       &f-link-SetOption; works for options added with &AddOption;,
670       but only if they were created with
671       <parameter>settable=True</parameter> in the call to &AddOption;
672       (only available in SCons 4.8.0 and later).
674       </para>
676       <para>
678       One useful example of using this functionality
679       is to provide a <option>--prefix</option> to help describe
680       where to install files:
682       </para>
684       <scons_example name="commandline_AddOption">
685         <file name="SConstruct" printme="1">
686 AddOption(
687     '--prefix',
688     dest='prefix',
689     type='string',
690     nargs=1,
691     action='store',
692     metavar='DIR',
693     help='installation prefix',
696 env = Environment(PREFIX=GetOption('prefix'))
698 installed_foo = env.Install('$PREFIX/usr/bin', 'foo.in')
699 Default(installed_foo)
700         </file>
701         <file name="foo.in">
702 foo.in
703         </file>
704       </scons_example>
706       <para>
708       The above code uses the &GetOption; function
709       to set the <varname>$PREFIX</varname>
710       &consvar; to a
711       value you specify with a command-line
712       option of <option>--prefix</option>.
713       Because <varname>$PREFIX</varname>
714       expands to a null string if it's not initialized,
715       running &SCons; without the
716       option of <option>--prefix</option>
717       installs the file in the
718       <filename>/usr/bin/</filename> directory:
720       </para>
722       <scons_output example="commandline_AddOption" suffix="1">
723         <scons_output_command>scons -Q -n</scons_output_command>
724       </scons_output>
726       <para>
728       But specifying <option>--prefix=/tmp/install</option>
729       on the command line causes the file to be installed in the
730       <filename>/tmp/install/usr/bin/</filename> directory:
732       </para>
734       <scons_output example="commandline_AddOption" suffix="2">
735         <scons_output_command>scons -Q -n --prefix=/tmp/install</scons_output_command>
736       </scons_output>
738       <note>
739       <para>
740       The <systemitem>optparse</systemitem> parser which &SCons; uses
741       allows option-arguments to follow their options after either
742       an <literal>=</literal> or space separator,
743       however the latter form does not work well in &SCons; for
744       added options and should be avoided.
745       &SCons; does not place an ordering constraint on the
746       types of command-line arguments,
747       so while <option>--input=ARG</option> is unambiguous,
748       for <option>--input ARG</option>
749       it is not possible to tell without instructions whether
750       <parameter>ARG</parameter> is an argument belonging to the
751       <parameter>input</parameter> option or a standalone word.
752       &SCons; considers words on the command line which do not
753       begin with hyphen as either command-line build variables
754       or command-line targets,
755       both of which are made available for use in an &SConscript;
756       (see the immediately following sections for details).
757       Thus, they must be collected before &SConscript; processing
758       takes place. &AddOption; calls do provide the
759       necessary instructions to resolve the ambiguity,
760       but as they appear in &SConscript; files,
761       &SCons; does not have the information early enough,
762       and unexpected things may happen,
763       such as option-arguments appearing in the list of targets,
764       and processing exceptions due to missing option-arguments.
765       </para>
766       <para>
767       As a result,
768       this usage style should be avoided when invoking &scons;.
769       For single-argument options,
770       tell your users to use the <option>--input=ARG</option>
771       form on the command line.
772       For multiple-argument options
773       (<parameter>nargs</parameter> value greater than one),
774       set <parameter>nargs</parameter> to one in the
775       &AddOption; call and either: combine the option-arguments into one word
776       with a separator, and parse the result in your own code
777       (see the built-in <option>--debug</option> option, which
778       allows specifying multiple arguments as a single comma-separated
779       word, for an example of such usage); or allow the option to
780       be specified multiple times by setting
781       <literal>action='append'</literal>. Both methods can be
782       supported at the same time.
783       </para>
784       </note>
786     </section>
788   </section>
790   <section id="sect-command-line-variables">
791   <title>Command-Line <varname>variable</varname>=<replaceable>value</replaceable> Build Variables</title>
793     <para>
795     You may want to control various aspects
796     of your build by allowing
797     <varname>variable</varname>=<replaceable>value</replaceable>
798     pairs to be specified on the command line.
799     For example, suppose you want to be able to
800     build a debug version of a program
801     by running &SCons; as follows:
803     </para>
805     <screen>
806 % <userinput>scons -Q debug=1</userinput>
807     </screen>
809     <para>
811     &SCons; provides an &ARGUMENTS; dictionary
812     that stores all of the
813     <varname>variable</varname>=<replaceable>value</replaceable>
814     assignments from the command line.
815     This allows you to modify
816     aspects of your build in response
817     to specifications on the command line.
819     </para>
821     <para>
823     The following code sets the &cv-link-CCFLAGS; &consvar;
824     in response to the <varname>debug</varname>
825     flag being set in the &ARGUMENTS; dictionary:
827     </para>
829     <scons_example name="commandline_ARGUMENTS">
830        <file name="SConstruct" printme="1">
831 env = Environment()
832 debug = ARGUMENTS.get('debug', 0)
833 if int(debug):
834     env.Append(CCFLAGS='-g')
835 env.Program('prog.c')
836        </file>
837        <file name="prog.c">
838 prog.c
839        </file>
840     </scons_example>
842     <para>
844     This results in the <varname>-g</varname>
845     compiler option being used when
846     <literal>debug=1</literal>
847     is used on the command line:
849     </para>
851     <scons_output example="commandline_ARGUMENTS" suffix="1">
852        <scons_output_command>scons -Q debug=0</scons_output_command>
853        <scons_output_command>scons -Q debug=0</scons_output_command>
854        <scons_output_command>scons -Q debug=1</scons_output_command>
855        <scons_output_command>scons -Q debug=1</scons_output_command>
856     </scons_output>
858     <note><para>
860     Two usage notes (both shown in the example above):
862     <itemizedlist>
863       <listitem>
864         <para>
865           No matter how you intend to use them, the values read from
866           a command line (i.e., external to the program) are
867           always strings. You may need to do type conversion.
868         </para>
869       </listitem>
870       <listitem>
871         <para>
872           When you retrieve from the &ARGUMENTS; dictionary,
873           it is useful to use the &Python; dictionary
874           <methodname>get</methodname> method,
875           so you can supply a default value if the variable is
876           not given on the command line. Otherwise, the build
877           will fail with a &KeyError;
878           if the variable is not set.
879         </para>
880       </listitem>
881     </itemizedlist>
885     </para></note>
887     <para>
889     &SCons; keeps track of the precise build command used to build each object file,
890     and as a result can determine that the object and executable files
891     need rebuilding when the value of the <parameter>debug</parameter>
892     argument has changed.
894     </para>
896     <para>
898     The &ARGUMENTS; dictionary has two minor drawbacks.
899     First, because it is a dictionary,
900     it can only map each keyword to one value,
901     and thus only "remembers" the last setting
902     for each keyword on the command line.
903     This makes the &ARGUMENTS; dictionary
904     less than ideal if you want to allow
905     specifying multiple values
906     on the command line for a given keyword.
907     Second, it does not preserve
908     the order in which the variable settings
909     were specified,
910     which is a problem if
911     you want the configuration to
912     behave differently in response
913     to the order in which the build
914     variable settings were specified on the command line
915     (&Python; versions since 3.6 now maintain dictionaries in
916     insertion order, so this problem is mitigated).
918     </para>
920     <para>
922     To accommodate these requirements,
923     &SCons; also provides an &ARGLIST; variable
924     that gives you direct access to build variable
925     settings from the command line,
926     in the exact order they were specified,
927     and without removing any duplicate settings.
928     Each element in the &ARGLIST; variable
929     is itself a two-element list
930     containing the keyword and the value
931     of the setting,
932     and you must loop through,
933     or otherwise select from,
934     the elements of &ARGLIST; to
935     process the specific settings you want
936     in whatever way is appropriate for your configuration.
937     For example,
938     the following code lets you
939     add to the &CPPDEFINES; &consvar;
940     by specifying multiple
941     <varname>define=</varname>
942     settings on the command line:
944     </para>
946     <scons_example name="commandline_ARGLIST">
947        <file name="SConstruct" printme="1">
948 cppdefines = []
949 for key, value in ARGLIST:
950     if key == 'define':
951         cppdefines.append(value)
952 env = Environment(CPPDEFINES=cppdefines)
953 env.Object('prog.c')
954        </file>
955        <file name="prog.c">
956 prog.c
957        </file>
958     </scons_example>
960     <para>
962     Yields the following output:
964     </para>
966     <scons_output example="commandline_ARGLIST" suffix="1">
967        <scons_output_command>scons -Q define=FOO</scons_output_command>
968        <scons_output_command>scons -Q define=FOO define=BAR</scons_output_command>
969     </scons_output>
971     <para>
973     Note that the &ARGLIST; and &ARGUMENTS;
974     variables do not interfere with each other,
975     but rather provide slightly different views
976     into how you specified
977     <varname>variable</varname>=<replaceable>value</replaceable>
978     settings on the command line.
979     You can use both variables in the same
980     &SCons; configuration.
981     In general, the &ARGUMENTS; dictionary
982     is more convenient to use,
983     (since you can just fetch variable
984     settings through &Python; dictionary access),
985     and the &ARGLIST; list
986     is more flexible
987     (since you can examine the
988     specific order in which
989     the command-line variable settings were given).
991     </para>
993     <section id="sect-controlling-cli-variables">
994     <title>Controlling Command-Line Build Variables</title>
996       <para>
998       Being able to use a command-line build variable like
999       <literal>debug=1</literal> is handy,
1000       but it can be a chore to write specific Python code
1001       to recognize each such variable,
1002       check for errors and provide appropriate messages,
1003       and apply the values to a &consvar;.
1004       To help with this,
1005       &SCons; provides a &Variables; container class to
1006       hold definitions of such build variables,
1007       and a mechanism to apply the
1008       build variables to a &consenv;.
1009       This allows you to control how the build variables affect
1010       &consenvs;.
1012       </para>
1014       <para>
1016       For example, suppose that you want to set
1017       a &RELEASE; &consvar; on the
1018       command line whenever the time comes to build
1019       a program for release,
1020       and that the value of this variable
1021       should be added to the build command
1022       with the appropriate define
1023       to pass the value to the C compiler.
1024       Here's how you might do that by setting
1025       the appropriate value in a dictionary for the
1026       &cv-link-CPPDEFINES; &consvar;:
1028       </para>
1030       <scons_example name="commandline_Variables1">
1031         <file name="SConstruct" printme="1">
1032 vars = Variables(None, ARGUMENTS)
1033 vars.Add('RELEASE', default=0)
1034 env = Environment(variables=vars, CPPDEFINES={'RELEASE_BUILD': '${RELEASE}'})
1035 env.Program(['foo.c', 'bar.c'])
1036         </file>
1037         <file name="foo.c">
1038 foo.c
1039         </file>
1040         <file name="bar.c">
1041 bar.c
1042         </file>
1043       </scons_example>
1045       <para>
1047       This &SConstruct; snippet first creates a &Variables; object which
1048       uses the values from the command-line variables dictionary &ARGUMENTS;.
1049       It then uses the object's &Add;
1050       method to indicate that the &RELEASE;
1051       variable can be set on the command line, and that
1052       if not set the default value is <literal>0</literal>.
1053       The newly created &Variables; object
1054       is passed to the &Environment; call
1055       used to create the &consenv;
1056       using a &variables; keyword argument.
1057       This then allows you to set the
1058       &RELEASE; build variable on the command line
1059       and have the variable show up in
1060       the command line used to build each object from
1061       a C source file:
1063       </para>
1065       <scons_output example="commandline_Variables1" suffix="1">
1066         <scons_output_command>scons -Q RELEASE=1</scons_output_command>
1067       </scons_output>
1069       <para>
1071       The <literal>Variables()</literal> call in this example looks
1072       a little awkward. The function takes two optional arguments:
1073       a script name and a dictionary.  In order to specify the
1074       dictionary as the second argument, you must provide the
1075       script argument as the first; since there's actually no script,
1076       use <constant>None</constant> as a sentinel value.
1077       However, if you omit all the arguments,
1078       the default behavior is to read from the &ARGUMENTS; dictionary anyway,
1079       which is what we want.  The example shows it this way because the arguments
1080       were introduced in this order, but you should feel free to just
1081       leave off the arguments if the default behavior is what you want.
1083       </para>
1085       <para>
1087       Historical note:  In old &SCons; (prior to 0.98.1 from 2008),
1088       these build variables were known as "command-line build options."
1089       At that time, the class was named &Options;
1090       and the predefined functions to construct options were named
1091       &BoolOption;, &EnumOption;, &ListOption;,
1092       &PathOption;, &PackageOption; and &AddOptions; (contrast
1093       with the current names in
1094       <xref linkend="sect-build-variable-functions"></xref>, below).
1095       Because the Internet has a very long memory,
1096       you may encounter these names in older
1097       &SConscript; files, wiki pages, blog entries, StackExchange
1098       articles, etc.
1099       These old names no longer work, but a mental substitution
1100       of <quote>Variable</quote> for <quote>Option</quote>
1101       allows the concepts to transfer to current usage models.
1103       </para>
1105     </section>
1107     <section id="sect-variables-help">
1108     <title>Providing Help for Command-Line Build Variables</title>
1110       <para>
1112       To make command-line build variables more useful,
1113       you may want to provide
1114       some help text to describe the available variables
1115       when you ask for help (run <userinput>scons -h</userinput>).
1116       You can write this text by hand,
1117       but &SCons; provides some assistance.
1118       Variables objects provide a
1119       &GenerateHelpText; method to
1120       generate text that describes
1121       the various variables that
1122       have been added to it. The default text includes
1123       the help string itself plus other information
1124       such as allowed values.
1125       (The generated text can also be customized by
1126       replacing the <methodname>FormatVariableHelpText</methodname>
1127       method).
1128       You then pass the output from this method to
1129       the &Help; function:
1131       </para>
1133       <scons_example name="commandline_Variables_Help">
1134         <file name="SConstruct" printme="1">
1135 vars = Variables()
1136 vars.Add('RELEASE', help='Set to 1 to build for release', default=0)
1137 env = Environment(variables=vars)
1138 Help(vars.GenerateHelpText(env))
1139         </file>
1140       </scons_example>
1142       <para>
1144       &scons; now displays some useful text
1145       when the <option>-h</option> option is used:
1147       </para>
1149       <scons_output example="commandline_Variables_Help" suffix="1">
1150         <scons_output_command>scons -Q -h</scons_output_command>
1151       </scons_output>
1153       <para>
1155       You can see the help output shows the default value
1156       as well as the current actual value of the build variable.
1158       </para>
1160     </section>
1162     <section id="sect-variables-file">
1163     <title>Reading Build Variables From a File</title>
1165       <para>
1167       Being able to specify the
1168       value of a build variable on the command line
1169       is useful,
1170       but can still become tedious
1171       if you have to specify the variable
1172       every time you run &SCons;.
1173       To make this easier,
1174       you can provide customized build variable settings
1175       in a &Python; script by providing a file name when the
1176       &Variables; object is created:
1178       </para>
1180       <scons_example name="commandline_Variables_custom_py_1">
1181         <file name="SConstruct" printme="1">
1182 vars = Variables('custom.py')
1183 vars.Add('RELEASE', help='Set to 1 to build for release', default=0)
1184 env = Environment(variables=vars, CPPDEFINES={'RELEASE_BUILD': '${RELEASE}'})
1185 env.Program(['foo.c', 'bar.c'])
1186 Help(vars.GenerateHelpText(env))
1187         </file>
1188         <file name="foo.c">
1189 foo.c
1190         </file>
1191         <file name="bar.c">
1192 bar.c
1193         </file>
1194         <file name="custom.py">
1195 RELEASE = 1
1196         </file>
1197       </scons_example>
1199       <para>
1201       This then allows you to control the &RELEASE;
1202       variable by setting it in the &custom_py; script:
1204       </para>
1206       <scons_example_file example="commandline_Variables_custom_py_1" name="custom.py"></scons_example_file>
1208       <para>
1210       Note that this file is actually executed
1211       like a &Python; script.
1212       Now when you run &SCons;:
1214       </para>
1216       <scons_output example="commandline_Variables_custom_py_1" suffix="1">
1217         <scons_output_command>scons -Q</scons_output_command>
1218       </scons_output>
1220       <para>
1222       And if you change the contents of &custom_py; to:
1224       </para>
1226       <scons_example name="commandline_Variables_custom_py_2">
1227         <file name="SConstruct">
1228 vars = Variables('custom.py')
1229 vars.Add('RELEASE', help='Set to 1 to build for release', default=0)
1230 env = Environment(variables=vars, CPPDEFINES={'RELEASE_BUILD': '${RELEASE}'})
1231 env.Program(['foo.c', 'bar.c'])
1232 Help(vars.GenerateHelpText(env))
1233         </file>
1234         <file name="foo.c">
1235 foo.c
1236         </file>
1237         <file name="bar.c">
1238 bar.c
1239         </file>
1240         <file name="custom.py" printme="1">
1241 RELEASE = 0
1242         </file>
1243       </scons_example>
1245       <para>
1247       The object files are rebuilt appropriately
1248       with the new variable:
1250       </para>
1252       <scons_output example="commandline_Variables_custom_py_2" suffix="1">
1253         <scons_output_command>scons -Q</scons_output_command>
1254       </scons_output>
1256       <para>
1258       Finally, you can combine both methods with:
1260       </para>
1262       <screen>
1263 vars = Variables('custom.py', ARGUMENTS)
1264       </screen>
1266       <para>
1268       If both a variables script and a dictionary are supplied,
1269       the dictionary is evaluated last, so values from the
1270       command line "win" if there are any duplicate keys.
1271       This rule allows you to move some common settings
1272       to a variables script, but still be able to override those
1273       for a given build without changing the script.
1275       </para>
1277       <!-- TODO: maybe show a variable used to select between variable scripts? -->
1279     </section>
1281     <section id="sect-build-variable-functions">
1282     <title>Pre-Defined Build Variable Functions</title>
1284       <para>
1286       &SCons; provides a number of convenience functions
1287       that provide behavior definitions
1288       for various types of command-line build variables.
1289       These functions all return a tuple which is ready
1290       to be passed to the &Add; or &AddVariables; method call.
1291       You are of course free to define your own behaviors
1292       as well.
1294       </para>
1296       <section id="sect-variables-bool">
1297       <title>True/False Values:  the &BoolVariable; Build Variable Function</title>
1299         <para>
1301         It is often handy to be able to specify a
1302         variable that controls a simple Boolean variable
1303         with a &true; or &false; value.
1304         It would be even more handy to accommodate
1305         different preferences for how to represent
1306         &true; or &false; values.
1307         The &BoolVariable; function
1308         makes it easy to accommodate these
1309         common representations of
1310         &true; or &false;.
1312         </para>
1314         <para>
1316         The &BoolVariable; function takes three arguments:
1317         the name of the build variable,
1318         the default value of the build variable,
1319         and the help string for the variable.
1320         It then returns appropriate information for
1321         passing to the &Add; method of a &Variables; object, like so:
1323         </para>
1325         <scons_example name="commandline_BoolVariable">
1326           <file name="SConstruct" printme="1">
1327 vars = Variables('custom.py')
1328 vars.Add(BoolVariable('RELEASE', help='Set to build for release', default=False))
1329 env = Environment(variables=vars, CPPDEFINES={'RELEASE_BUILD': '${RELEASE}'})
1330 env.Program('foo.c')
1331           </file>
1332           <file name="foo.c">
1333 foo.c
1334           </file>
1335         </scons_example>
1337         <para>
1339         With this build variable in place,
1340         the &RELEASE; variable can now be enabled by
1341         setting it to the value <literal>yes</literal>
1342         or <literal>t</literal>:
1344         </para>
1346         <scons_output example="commandline_BoolVariable" suffix="1">
1347           <scons_output_command>scons -Q RELEASE=yes foo.o</scons_output_command>
1348         </scons_output>
1350         <scons_output example="commandline_BoolVariable" suffix="2">
1351           <scons_output_command>scons -Q RELEASE=t foo.o</scons_output_command>
1352         </scons_output>
1354         <para>
1356         Other values that equate to &true; include
1357         <literal>y</literal>,
1358         <literal>1</literal>,
1359         <literal>on</literal>
1360         and
1361         <literal>all</literal>.
1363         </para>
1365         <para>
1367         Conversely, &RELEASE; may now be given a &false;
1368         value by setting it to
1369         <literal>no</literal>
1370         or
1371         <literal>f</literal>:
1373         </para>
1375         <scons_output example="commandline_BoolVariable" suffix="3">
1376           <scons_output_command>scons -Q RELEASE=no foo.o</scons_output_command>
1377         </scons_output>
1379         <scons_output example="commandline_BoolVariable" suffix="4">
1380           <scons_output_command>scons -Q RELEASE=f foo.o</scons_output_command>
1381         </scons_output>
1383         <para>
1385         Other values that equate to &false; include
1386         <literal>n</literal>,
1387         <literal>0</literal>,
1388         <literal>off</literal>
1389         and
1390         <literal>none</literal>.
1392         </para>
1394         <para>
1396         Lastly, if you try to specify
1397         any other value,
1398         &SCons; supplies an appropriate error message:
1400         </para>
1402         <scons_output example="commandline_BoolVariable" suffix="5">
1403           <scons_output_command>scons -Q RELEASE=bad_value foo.o</scons_output_command>
1404         </scons_output>
1406       </section>
1408       <section id="sect-variables-enum">
1409       <title>Single Value From a Selection:  the &EnumVariable; Build Variable Function</title>
1411         <para>
1413         Suppose that you want to allow
1414         setting a &COLOR; variable
1415         that selects a background color to be
1416         displayed by an application,
1417         but that you want to restrict the
1418         choices to a specific set of allowed colors.
1419         You can set this up quite easily
1420         using the &EnumVariable; function,
1421         which takes a list of &allowed_values;
1422         in addition to the variable name,
1423         default value,
1424         and help text arguments:
1426         </para>
1428         <scons_example name="commandline_EnumVariable">
1429           <file name="SConstruct" printme="1">
1430 vars = Variables('custom.py')
1431 vars.Add(
1432     EnumVariable(
1433         'COLOR',
1434         help='Set background color',
1435         default='red',
1436         allowed_values=('red', 'green', 'blue'),
1437     )
1439 env = Environment(variables=vars, CPPDEFINES={'COLOR': '"${COLOR}"'})
1440 env.Program('foo.c')
1441 Help(vars.GenerateHelpText(env))
1442           </file>
1443           <file name="foo.c">
1444 foo.c
1445           </file>
1446         </scons_example>
1448         <para>
1450         You can now explicitly set the &COLOR; build variable
1451         to any of the specified allowed values:
1453         </para>
1455         <scons_output example="commandline_EnumVariable" suffix="1">
1456           <scons_output_command>scons -Q COLOR=red foo.o</scons_output_command>
1457           <scons_output_command>scons -Q COLOR=blue foo.o</scons_output_command>
1458           <scons_output_command>scons -Q COLOR=green foo.o</scons_output_command>
1459         </scons_output>
1461         <para>
1463         But, importantly,
1464         an attempt to set &COLOR;
1465         to a value that's not in the list
1466         generates an error message:
1468         </para>
1470         <scons_output example="commandline_EnumVariable" suffix="2">
1471           <scons_output_command>scons -Q COLOR=magenta foo.o</scons_output_command>
1472         </scons_output>
1474         <para>
1476         This example can also serve to further illustrate help
1477         generation: the help message here picks up not only the
1478         <parameter>help</parameter> text, but augments it with
1479         information gathered from <parameter>allowed_values</parameter>
1480         and <parameter>default</parameter>:
1482         </para>
1484         <scons_output example="commandline_EnumVariable" suffix="3">
1485           <scons_output_command>scons -Q -h</scons_output_command>
1486         </scons_output>
1488         <para>
1490         The &EnumVariable; function also provides a way
1491         to map alternate names to allowed values.
1492         Suppose, for example, you want to allow
1493         the word <literal>navy</literal> to be used as a synonym for
1494         <literal>blue</literal>.
1495         You do this by adding a &map; dictionary
1496         that maps its key values
1497         to the desired allowed value:
1499         </para>
1501         <scons_example name="EnumVariable_map">
1502           <file name="SConstruct" printme="1">
1503 vars = Variables('custom.py')
1504 vars.Add(
1505     EnumVariable(
1506         'COLOR',
1507         help='Set background color',
1508         default='red',
1509         allowed_values=('red', 'green', 'blue'),
1510         map={'navy': 'blue'},
1511     )
1513 env = Environment(variables=vars, CPPDEFINES={'COLOR': '"${COLOR}"'})
1514 env.Program('foo.c')
1515           </file>
1516           <file name="foo.c">
1517 foo.c
1518           </file>
1519         </scons_example>
1521         <para>
1523         Now you can supply
1524         <literal>navy</literal> on the command line,
1525         and &SCons; translates that into <literal>blue</literal>
1526         when it comes time to use the &COLOR;
1527         variable to build a target:
1529         </para>
1531         <scons_output example="EnumVariable_map" suffix="1">
1532           <scons_output_command>scons -Q COLOR=navy foo.o</scons_output_command>
1533         </scons_output>
1535         <para>
1537         By default, when using the &EnumVariable; function,
1538         the allowed values are case-sensitive:
1540         </para>
1542         <scons_output example="commandline_EnumVariable" suffix="4">
1543           <scons_output_command>scons -Q COLOR=Red foo.o</scons_output_command>
1544           <scons_output_command>scons -Q COLOR=BLUE foo.o</scons_output_command>
1545           <scons_output_command>scons -Q COLOR=nAvY foo.o</scons_output_command>
1546         </scons_output>
1548         <para>
1550         The &EnumVariable; function can take an additional
1551         &ignorecase; keyword argument that,
1552         when set to <literal>1</literal>,
1553         tells &SCons; to allow case differences
1554         when the values are specified:
1556         </para>
1558         <scons_example name="commandline_EnumVariable_ic1">
1559           <file name="SConstruct" printme="1">
1560 vars = Variables('custom.py')
1561 vars.Add(
1562     EnumVariable(
1563         'COLOR',
1564         help='Set background color',
1565         default='red',
1566         allowed_values=('red', 'green', 'blue'),
1567         map={'navy': 'blue'},
1568         ignorecase=1,
1569     )
1571 env = Environment(variables=vars, CPPDEFINES={'COLOR': '"${COLOR}"'})
1572 env.Program('foo.c')
1573           </file>
1574           <file name="foo.c">
1575 foo.c
1576           </file>
1577         </scons_example>
1579         <para>
1581         Which yields the output:
1583         </para>
1585         <scons_output example="commandline_EnumVariable_ic1" suffix="1">
1586           <scons_output_command>scons -Q COLOR=Red foo.o</scons_output_command>
1587           <scons_output_command>scons -Q COLOR=BLUE foo.o</scons_output_command>
1588           <scons_output_command>scons -Q COLOR=nAvY foo.o</scons_output_command>
1589           <scons_output_command>scons -Q COLOR=green foo.o</scons_output_command>
1590         </scons_output>
1592         <para>
1594         Notice that an &ignorecase; value of <literal>1</literal>
1595         preserves the case-spelling supplied,
1596         only ignoring the case for matching.
1597         If you want &SCons; to translate the names
1598         into lower-case,
1599         regardless of the case used by the user,
1600         specify an &ignorecase; value of <literal>2</literal>:
1602         </para>
1604         <scons_example name="commandline_EnumVariable_ic2">
1605           <file name="SConstruct" printme="1">
1606 vars = Variables('custom.py')
1607 vars.Add(
1608     EnumVariable(
1609         'COLOR',
1610         help='Set background color',
1611         default='red',
1612         allowed_values=('red', 'green', 'blue'),
1613         map={'navy': 'blue'},
1614         ignorecase=2,
1615     )
1617 env = Environment(variables=vars, CPPDEFINES={'COLOR': '"${COLOR}"'})
1618 env.Program('foo.c')
1619           </file>
1620           <file name="foo.c">
1621 foo.c
1622           </file>
1623         </scons_example>
1625         <para>
1627         Now &SCons; uses values of
1628         <literal>red</literal>,
1629         <literal>green</literal> or
1630         <literal>blue</literal>
1631         regardless of how those values are spelled
1632         on the command line:
1634         </para>
1636         <scons_output example="commandline_EnumVariable_ic2" suffix="1">
1637           <scons_output_command>scons -Q COLOR=Red foo.o</scons_output_command>
1638           <scons_output_command>scons -Q COLOR=nAvY foo.o</scons_output_command>
1639           <scons_output_command>scons -Q COLOR=GREEN foo.o</scons_output_command>
1640         </scons_output>
1642       </section>
1644       <section id="sect-variables-list">
1645       <title>Multiple Values From a List:  the &ListVariable; Build Variable Function</title>
1647         <para>
1649         Another way in which you might want to control a build variable is to
1650         specify a list of allowed values, of which one or more can be chosen
1651         (where &EnumVariable; allows exactly one value to be chosen).
1652         &SCons; provides this through the &ListVariable; function.
1653         If, for example, you want to be able to set a
1654         &COLORS; variable to one or more of the allowed values:
1656         </para>
1658         <scons_example name="commandline_ListVariable">
1659           <file name="SConstruct" printme="1">
1660 vars = Variables('custom.py')
1661 vars.Add(
1662     ListVariable(
1663         'COLORS', help='List of colors', default=0, names=['red', 'green', 'blue']
1664     )
1666 env = Environment(variables=vars, CPPDEFINES={'COLORS': '"${COLORS}"'})
1667 env.Program('foo.c')
1668           </file>
1669           <file name="foo.c">
1670 foo.c
1671           </file>
1672         </scons_example>
1674         <para>
1676         You can now specify a comma-separated list of allowed values,
1677         which get translated into a space-separated
1678         list for passing to the build commands:
1680         </para>
1682         <scons_output example="commandline_ListVariable" suffix="1">
1683           <scons_output_command>scons -Q COLORS=red,blue foo.o</scons_output_command>
1684           <scons_output_command>scons -Q COLORS=blue,green,red foo.o</scons_output_command>
1685         </scons_output>
1687         <para>
1689         In addition, the &ListVariable; function
1690         lets you specify explicit keywords of
1691         &all; or &none;
1692         to select all of the allowed values,
1693         or none of them, respectively:
1695         </para>
1697         <scons_output example="commandline_ListVariable" suffix="2">
1698           <scons_output_command>scons -Q COLORS=all foo.o</scons_output_command>
1699           <scons_output_command>scons -Q COLORS=none foo.o</scons_output_command>
1700         </scons_output>
1702         <para>
1704         And, of course, an illegal value
1705         still generates an error message:
1707         </para>
1709         <scons_output example="commandline_ListVariable" suffix="3">
1710           <scons_output_command>scons -Q COLORS=magenta foo.o</scons_output_command>
1711         </scons_output>
1713         <para>
1715         You can use this last characteristic as a way to enforce at least
1716         one of your valid options being chosen by specifying the valid
1717         values with the <parameter>names</parameter> parameter and then
1718         giving a value not in that list as the <parameter>default</parameter>
1719         parameter - that way if no value is given on the command line,
1720         the default is chosen, &SCons; errors out as this is invalid.
1721         The example is, in fact, set up that way by using
1722         <literal>0</literal> as the default:
1724         </para>
1726         <scons_output example="commandline_ListVariable" suffix="4">
1727           <scons_output_command>scons -Q foo.o</scons_output_command>
1728         </scons_output>
1730         <para>
1732         This technique works for &EnumVariable; as well.
1734         </para>
1736       </section>
1738       <section id="sect-variables-path">
1739       <title>Path Names:  the &PathVariable; Build Variable Function</title>
1741         <para>
1743         &SCons; provides a &PathVariable; function
1744         to make it easy to create a build variable
1745         to control an expected path name.
1746         If, for example, you need to
1747         define a preprocessor macro
1748         that controls the location of a
1749         configuration file:
1751         </para>
1753         <scons_example name="commandline_PathVariable">
1754           <file name="SConstruct" printme="1">
1755 vars = Variables('custom.py')
1756 vars.Add(
1757     PathVariable(
1758         'CONFIG', help='Path to configuration file', default='__ROOT__/etc/my_config'
1759     )
1761 env = Environment(variables=vars, CPPDEFINES={'CONFIG_FILE': '"$CONFIG"'})
1762 env.Program('foo.c')
1763           </file>
1764           <file name="foo.c">
1765 foo.c
1766           </file>
1767           <file name="__ROOT__/etc/my_config">
1768 /opt/location
1769           </file>
1770           <file name="__ROOT__/usr/local/etc/other_config">
1771 /opt/location
1772           </file>
1773         </scons_example>
1775         <para>
1777         This allows you to
1778         override the &CONFIG; build variable
1779         on the command line as necessary:
1781         </para>
1783         <scons_output example="commandline_PathVariable" suffix="1">
1784           <scons_output_command>scons -Q foo.o</scons_output_command>
1785           <scons_output_command>scons -Q CONFIG=__ROOT__/usr/local/etc/other_config foo.o</scons_output_command>
1786         </scons_output>
1788         <para>
1790         By default, &PathVariable; checks to make sure
1791         that the specified path exists and generates an error if it
1792         doesn't:
1794         </para>
1796         <scons_output example="commandline_PathVariable" suffix="2">
1797           <scons_output_command>scons -Q CONFIG=__ROOT__/does/not/exist foo.o</scons_output_command>
1798         </scons_output>
1800         <para>
1802         &PathVariable; provides a number of methods
1803         that you can use to change this behavior.
1804         If you want to ensure that any specified paths are,
1805         in fact, files and not directories,
1806         use the &PathVariable_PathIsFile; method as the validation function:
1808         </para>
1810         <scons_example name="commandline_PathIsFile">
1811           <file name="SConstruct" printme="1">
1812 vars = Variables('custom.py')
1813 vars.Add(
1814     PathVariable(
1815         'CONFIG',
1816         help='Path to configuration file',
1817         default='__ROOT__/etc/my_config',
1818         validator=PathVariable.PathIsFile,
1819     )
1821 env = Environment(variables=vars, CPPDEFINES={'CONFIG_FILE': '"$CONFIG"'})
1822 env.Program('foo.c')
1823           </file>
1824           <file name="foo.c">
1825 foo.c
1826           </file>
1827           <file name="__ROOT__/etc/my_config">
1828 /opt/location
1829           </file>
1830         </scons_example>
1832         <para>
1834         Conversely, to ensure that any specified paths are
1835         directories and not files,
1836         use the &PathVariable_PathIsDir; method as the validation function:
1838         </para>
1840         <scons_example name="commandline_PathIsDir">
1841           <file name="SConstruct" printme="1">
1842 vars = Variables('custom.py')
1843 vars.Add(
1844     PathVariable(
1845         'DBDIR',
1846         help='Path to database directory',
1847         default='__ROOT__/var/my_dbdir',
1848         validator=PathVariable.PathIsDir,
1849     )
1851 env = Environment(variables=vars, CPPDEFINES={'DBDIR': '"$DBDIR"'})
1852 env.Program('foo.c')
1853           </file>
1854           <file name="foo.c">
1855 foo.c
1856           </file>
1857           <file name="__ROOT__/var/my_dbdir">
1858 /opt/location
1859           </file>
1860         </scons_example>
1862         <para>
1864         If you want to make sure that any specified paths
1865         are directories,
1866         and you would like the directory created
1867         if it doesn't already exist,
1868         use the &PathVariable_PathIsDirCreate; method as the validation function:
1870         </para>
1872         <scons_example name="commandline_PathIsDirCreate">
1873           <file name="SConstruct" printme="1">
1874 vars = Variables('custom.py')
1875 vars.Add(
1876     PathVariable(
1877         'DBDIR',
1878         help='Path to database directory',
1879         default='__ROOT__/var/my_dbdir',
1880         validator=PathVariable.PathIsDirCreate,
1881     )
1883 env = Environment(variables=vars, CPPDEFINES={'DBDIR': '"$DBDIR"'})
1884 env.Program('foo.c')
1885           </file>
1886           <file name="foo.c">
1887 foo.c
1888           </file>
1889           <file name="__ROOT__/var/my_dbdir">
1890 /opt/location
1891           </file>
1892         </scons_example>
1894         <para>
1896         Lastly, if you don't care whether the path exists,
1897         is a file, or a directory,
1898         use the &PathVariable_PathAccept; method
1899         to accept any path you supply:
1901         </para>
1903         <scons_example name="commandline_PathAccept">
1904           <file name="SConstruct" printme="1">
1905 vars = Variables('custom.py')
1906 vars.Add(
1907     PathVariable(
1908         'OUTPUT',
1909         help='Path to output file or directory',
1910         default=None,
1911         validator=PathVariable.PathAccept,
1912     )
1914 env = Environment(variables=vars, CPPDEFINES={'OUTPUT': '"$OUTPUT"'})
1915 env.Program('foo.c')
1916           </file>
1917           <file name="foo.c">
1918 foo.c
1919           </file>
1920         </scons_example>
1922       </section>
1924       <section id="sect-variables-package">
1925       <title>Enabled/Disabled Path Names: the &PackageVariable; Build Variable Function</title>
1927         <para>
1929         Sometimes you want to give
1930         even more control over a path name variable,
1931         allowing them to be explicitly enabled or disabled
1932         by using <literal>yes</literal> or <literal>no</literal> keywords,
1933         in addition to allowing supplying an explicit path name.
1934         &SCons; provides the &PackageVariable;
1935         function to support this:
1937         </para>
1939         <scons_example name="commandline_PackageVariable">
1940           <file name="SConstruct" printme="1">
1941 vars = Variables("custom.py")
1942 vars.Add(
1943     PackageVariable("PACKAGE", help="Location package", default="__ROOT__/opt/location")
1945 env = Environment(variables=vars, CPPDEFINES={"PACKAGE": '"$PACKAGE"'})
1946 env.Program("foo.c")
1947           </file>
1948           <file name="foo.c">
1949 foo.c
1950           </file>
1951           <file name="__ROOT__/opt/location">
1952 /opt/location
1953           </file>
1954           <file name="__ROOT__/usr/local/location">
1955 /opt/location
1956           </file>
1957         </scons_example>
1959         <para>
1961         When the &SConscript; file uses the &PackageVariable; function,
1962         you can still use the default
1963         or supply an overriding path name,
1964         but you can now explicitly set the
1965         specified variable to a value
1966         that indicates the package should be enabled
1967         (in which case the default should be used)
1968         or disabled:
1970         </para>
1972         <scons_output example="commandline_PackageVariable" suffix="1">
1973           <scons_output_command>scons -Q foo.o</scons_output_command>
1974           <scons_output_command>scons -Q PACKAGE=__ROOT__/usr/local/location foo.o</scons_output_command>
1975           <scons_output_command>scons -Q PACKAGE=yes foo.o</scons_output_command>
1976           <scons_output_command>scons -Q PACKAGE=no foo.o</scons_output_command>
1977         </scons_output>
1979       </section>
1981     </section>
1983     <section id="sect-variables-multiple">
1984     <title>Adding Multiple Command-Line Build Variables at Once</title>
1986       <para>
1988       Lastly, &SCons; provides a way to add
1989       multiple build variables to a &Variables; object at once.
1990       Instead of having to call the &Add; method
1991       multiple times, you can call the &AddVariables;
1992       method with the build variables to be added to the object.
1993       Each build variable is specified
1994       as either a tuple of arguments,
1995       or as a call to one of the pre-defined
1996       functions for pre-packaged command-line build variables,
1997       which returns such a tuple. Note that an individual tuple
1998       cannot take keyword arguments in the way that a call to
1999       &Add; or one of the build variable functions can.
2000       The order of variables given to &AddVariables; does not
2001       matter.
2003       </para>
2005       <scons_example name="commandline_AddVariables_1">
2006         <file name="SConstruct" printme="1">
2007 vars = Variables()
2008 vars.AddVariables(
2009     ('RELEASE', 'Set to 1 to build for release', 0),
2010     ('CONFIG', 'Configuration file', '/etc/my_config'),
2011     BoolVariable('warnings', help='compilation with -Wall and similar', default=True),
2012     EnumVariable(
2013         'debug',
2014         help='debug output and symbols',
2015         default='no',
2016         allowed_values=('yes', 'no', 'full'),
2017         map={},
2018         ignorecase=0,
2019     ),
2020     ListVariable(
2021         'shared',
2022         help='libraries to build as shared libraries',
2023         default='all',
2024         names=list_of_libs,
2025     ),
2026     PackageVariable(
2027         'x11', help='use X11 installed here (yes = search some places)', default='yes'
2028     ),
2029     PathVariable('qtdir', help='where the root of Qt is installed', default=qtdir),
2031         </file>
2032       </scons_example>
2034       <para>
2035       </para>
2037     </section>
2039     <section id="sect-variables-unknown">
2040     <title>Handling Unknown Command-Line Build Variables:  the &UnknownVariables; Function</title>
2042       <para>
2044       Humans, of course,
2045       occasionally misspell variable names in their command-line settings.
2046       &SCons; does not generate an error or warning
2047       for any unknown variables specified on the command line,
2048       because it can not reliably tell
2049       whether a given "misspelled" variable is
2050       really unknown and a potential problem or not.
2051       After all, you might be processing arguments directly
2052       using &ARGUMENTS; or &ARGLIST; with some Python
2053       code in your &SConscript; file.
2055       </para>
2057       <para>
2059       If, however, you are using a &Variables; object to
2060       define a specific set of command-line build variables
2061       that you expect to be able to set,
2062       you may want to provide an error
2063       message or warning of your own
2064       if a variable setting is specified
2065       that is <emphasis>not</emphasis> among
2066       the defined list of variable names known to the &Variables; object.
2067       You can do this by calling the &UnknownVariables;
2068       method of the &Variables; object to get the
2069       settings &Variables; did not recognize:
2071       </para>
2073       <scons_example name="commandline_UnknownVariables">
2074         <file name="SConstruct" printme="1">
2075 vars = Variables(None)
2076 vars.Add('RELEASE', help='Set to 1 to build for release', default=0)
2077 env = Environment(variables=vars, CPPDEFINES={'RELEASE_BUILD': '${RELEASE}'})
2078 unknown = vars.UnknownVariables()
2079 if unknown:
2080     print("Unknown variables: %s" % " ".join(unknown.keys()))
2081     Exit(1)
2082 env.Program('foo.c')
2083         </file>
2084         <file name="foo.c">
2085 foo.c
2086         </file>
2087       </scons_example>
2089       <para>
2091       The &UnknownVariables; method returns a dictionary
2092       containing the keywords and values
2093       of any variables specified on the command line
2094       that are <emphasis>not</emphasis>
2095       among the variables known to the &Variables; object
2096       (from having been specified using
2097       the &Variables; object's &Add; method).
2098       The example above,
2099       checks whether the dictionary
2100       returned by &UnknownVariables; is non-empty,
2101       and if so prints the Python list
2102       containing the names of the unknown variables
2103       and then calls the &Exit; function
2104       to terminate &SCons;:
2106       </para>
2108       <scons_output example="commandline_UnknownVariables" suffix="1">
2109         <scons_output_command>scons -Q NOT_KNOWN=foo</scons_output_command>
2110       </scons_output>
2112       <para>
2114       Of course, you can process the items in the
2115       dictionary returned by the &UnknownVariables; function
2116       in any way appropriate to your build configuration,
2117       including just printing a warning message
2118       but not exiting,
2119       logging an error somewhere,
2120       etc.
2122       </para>
2124       <para>
2126       Note that you must delay the call of &UnknownVariables;
2127       until after you have applied the &Variables; object
2128       to a &consenv;
2129       with the <parameter>variables=</parameter>
2130       keyword argument of an &Environment; call: the variables
2131       in the object are not fully processed until this has happened.
2133       </para>
2135     </section>
2137   </section>
2139   <section id="sect-command-line-targets">
2140   <title>Command-Line Targets</title>
2142     <section id="sect-var-COMMAND-LINE-TARGETS">
2143     <title>Fetching Command-Line Targets: the &COMMAND_LINE_TARGETS; Variable</title>
2145       <para>
2147       &SCons; provides a &COMMAND_LINE_TARGETS; variable
2148       that lets you fetch the list of targets that were
2149       specified on the command line.
2150       You can use the targets to manipulate the
2151       build in any way you wish.
2152       As a simple example,
2153       suppose that you want to print a reminder
2154       whenever a specific program is built.
2155       You can do this by checking for the
2156       target in the &COMMAND_LINE_TARGETS; list:
2158       </para>
2160       <scons_example name="commandline_COMMAND_LINE_TARGETS">
2161         <file name="SConstruct" printme="1">
2162 if 'bar' in COMMAND_LINE_TARGETS:
2163     print("Don't forget to copy `bar' to the archive!")
2164 Default(Program('foo.c'))
2165 Program('bar.c')
2166         </file>
2167         <file name="foo.c">
2168 foo.c
2169         </file>
2170         <file name="bar.c">
2171 foo.c
2172         </file>
2173       </scons_example>
2175       <para>
2177       Now, running &SCons; with the default target
2178       works as usual,
2179       but explicitly specifying the &bar; target
2180       on the command line generates the warning message:
2182       </para>
2184       <scons_output example="commandline_COMMAND_LINE_TARGETS" suffix="1">
2185         <scons_output_command>scons -Q</scons_output_command>
2186         <scons_output_command>scons -Q bar</scons_output_command>
2187       </scons_output>
2189       <para>
2191       Another practical use for the &COMMAND_LINE_TARGETS; variable
2192       might be to speed up a build
2193       by only reading certain subsidiary &SConscript;
2194       files if a specific target is requested.
2196       </para>
2198     </section>
2200     <section id="sect-default-targets-function">
2201     <title>Controlling the Default Targets:  the &Default; Function</title>
2203       <para>
2205       You can control
2206       which targets &SCons; builds by default - that is,
2207       when there are no targets specified on the command line.
2208       As mentioned previously,
2209       &SCons; normally builds every target
2210       in or below the current directory unless you
2211       explicitly specify one or more targets
2212       on the command line.
2213       Sometimes, however, you may want
2214       to specify that only
2215       certain programs, or programs in certain directories,
2216       should be built by default.
2217       You do this with the &Default; function:
2219       </para>
2221       <scons_example name="commandline_Default1">
2222          <file name="SConstruct" printme="1">
2223 env = Environment()
2224 hello = env.Program('hello.c')
2225 env.Program('goodbye.c')
2226 Default(hello)
2227          </file>
2228          <file name="hello.c">
2229 hello.c
2230          </file>
2231          <file name="goodbye.c">
2232 goodbye.c
2233          </file>
2234       </scons_example>
2236       <para>
2238       This &SConstruct; file knows how to build two programs,
2239       &hello; and &goodbye;,
2240       but only builds the
2241       &hello; program by default:
2243       </para>
2245       <scons_output example="commandline_Default1" suffix="1">
2246          <scons_output_command>scons -Q</scons_output_command>
2247          <scons_output_command>scons -Q</scons_output_command>
2248          <scons_output_command>scons -Q goodbye</scons_output_command>
2249       </scons_output>
2251       <para>
2253       Note that, even when you use the &Default;
2254       function in your &SConstruct; file,
2255       you can still explicitly specify the current directory
2256       (<literal>.</literal>) on the command line
2257       to tell &SCons; to build
2258       everything in (or below) the current directory:
2260       </para>
2262       <scons_output example="commandline_Default1" suffix="2">
2263          <scons_output_command>scons -Q .</scons_output_command>
2264       </scons_output>
2266       <para>
2268       You can also call the &Default;
2269       function more than once,
2270       in which case each call
2271       adds to the list of targets to be built by default:
2273       </para>
2275       <scons_example name="commandline_Default2">
2276          <file name="SConstruct" printme="1">
2277 env = Environment()
2278 prog1 = env.Program('prog1.c')
2279 Default(prog1)
2280 prog2 = env.Program('prog2.c')
2281 prog3 = env.Program('prog3.c')
2282 Default(prog3)
2283          </file>
2284          <file name="prog1.c">
2285 prog1.c
2286          </file>
2287          <file name="prog2.c">
2288 prog2.c
2289          </file>
2290          <file name="prog3.c">
2291 prog3.c
2292          </file>
2293       </scons_example>
2295       <para>
2297       Or you can specify more than one target
2298       in a single call to the &Default; function:
2300       </para>
2302       <programlisting>
2303 env = Environment()
2304 prog1 = env.Program('prog1.c')
2305 prog2 = env.Program('prog2.c')
2306 prog3 = env.Program('prog3.c')
2307 Default(prog1, prog3)
2308       </programlisting>
2310       <para>
2312       Either of these last two examples
2313       build only the
2314       <application>prog1</application>
2315       and
2316       <application>prog3</application>
2317       programs by default:
2319       </para>
2321       <scons_output example="commandline_Default2" suffix="1">
2322          <scons_output_command>scons -Q</scons_output_command>
2323          <scons_output_command>scons -Q .</scons_output_command>
2324       </scons_output>
2326       <para>
2328       You can list a directory as
2329       an argument to &Default;:
2331       </para>
2333       <scons_example name="commandline_Default3">
2334          <file name="SConstruct" printme="1">
2335 env = Environment()
2336 env.Program(['prog1/main.c', 'prog1/foo.c'])
2337 env.Program(['prog2/main.c', 'prog2/bar.c'])
2338 Default('prog1')
2339          </file>
2340          <directory name="prog1"></directory>
2341          <directory name="prog2"></directory>
2342          <file name="prog1/main.c">
2343 int main() { printf("prog1/main.c\n"); }
2344          </file>
2345          <file name="prog1/foo.c">
2346 int foo() { printf("prog1/foo.c\n"); }
2347          </file>
2348          <file name="prog2/main.c">
2349 int main() { printf("prog2/main.c\n"); }
2350          </file>
2351          <file name="prog2/bar.c">
2352 int bar() { printf("prog2/bar.c\n"); }
2353          </file>
2354       </scons_example>
2356       <para>
2358       In which case only the target(s) in that
2359       directory are built by default:
2361       </para>
2363       <scons_output example="commandline_Default3" suffix="1">
2364          <scons_output_command>scons -Q</scons_output_command>
2365          <scons_output_command>scons -Q</scons_output_command>
2366          <scons_output_command>scons -Q .</scons_output_command>
2367       </scons_output>
2369       <para>
2371       Lastly, if for some reason you don't want
2372       any targets built by default,
2373       you can use the Python <constant>None</constant>
2374       variable:
2376       </para>
2378       <scons_example name="commandline_Default4">
2379          <file name="SConstruct" printme="1">
2380 env = Environment()
2381 prog1 = env.Program('prog1.c')
2382 prog2 = env.Program('prog2.c')
2383 Default(None)
2384          </file>
2385          <file name="prog1.c">
2386 prog1.c
2387          </file>
2388          <file name="prog2.c">
2389 prog2.c
2390          </file>
2391       </scons_example>
2393       <para>
2395       Which would produce build output like:
2397       </para>
2399       <scons_output example="commandline_Default4" suffix="1">
2400          <scons_output_command>scons -Q</scons_output_command>
2401          <scons_output_command>scons -Q .</scons_output_command>
2402       </scons_output>
2404       <section id="sect-var-DEFAULT-TARGETS">
2405       <title>Fetching the List of Default Targets: the &DEFAULT_TARGETS; Variable</title>
2407         <para>
2409         &SCons; provides a &DEFAULT_TARGETS; variable
2410         that lets you get at the current list of default targets
2411         specified by calls to the &Default; function or method.
2412         The &DEFAULT_TARGETS; variable has
2413         two important differences from the &COMMAND_LINE_TARGETS; variable.
2414         First, the &DEFAULT_TARGETS; variable is a list of
2415         internal &SCons; nodes,
2416         so you need to convert the list elements to strings
2417         if you want to print them or look for a specific target name.
2418         You can do this easily by calling the <function>str</function>
2419         on the elements in a list comprehension:
2421         </para>
2423         <scons_example name="commandline_DEFAULT_TARGETS_1">
2424            <file name="SConstruct" printme="1">
2425 prog1 = Program('prog1.c')
2426 Default(prog1)
2427 print("DEFAULT_TARGETS is %s" % [str(t) for t in DEFAULT_TARGETS])
2428            </file>
2429            <file name="prog1.c">
2430 prog1.c
2431            </file>
2432         </scons_example>
2434         <para>
2436         (Keep in mind that the manipulation of the
2437         &DEFAULT_TARGETS; list takes place during the
2438         first phase when &SCons; is reading up the &SConscript; files,
2439         which is obvious if
2440         you leave off the <option>-Q</option> flag when you run &SCons;:)
2442         </para>
2444         <scons_output example="commandline_DEFAULT_TARGETS_1" suffix="1">
2445            <scons_output_command>scons</scons_output_command>
2446         </scons_output>
2448         <para>
2450         Second,
2451         the contents of the &DEFAULT_TARGETS; list changes
2452         in response to calls to the &Default; function,
2453         as you can see from the following &SConstruct; file:
2455         </para>
2457         <scons_example name="commandline_DEFAULT_TARGETS_2">
2458            <file name="SConstruct" printme="1">
2459 prog1 = Program('prog1.c')
2460 Default(prog1)
2461 print("DEFAULT_TARGETS is now %s" % [str(t) for t in DEFAULT_TARGETS])
2462 prog2 = Program('prog2.c')
2463 Default(prog2)
2464 print("DEFAULT_TARGETS is now %s" % [str(t) for t in DEFAULT_TARGETS])
2465            </file>
2466            <file name="prog1.c">
2467 prog1.c
2468            </file>
2469            <file name="prog2.c">
2470 prog2.c
2471            </file>
2472         </scons_example>
2474         <para>
2476         Which yields the output:
2478         </para>
2480         <scons_output example="commandline_DEFAULT_TARGETS_2" suffix="1">
2481            <scons_output_command>scons</scons_output_command>
2482         </scons_output>
2484         <para>
2486         In practice, this simply means that you
2487         need to pay attention to the order in
2488         which you call the &Default; function
2489         and refer to the &DEFAULT_TARGETS; list,
2490         to make sure that you don't examine the
2491         list before you have added the default targets
2492         you expect to find in it.
2494         </para>
2496       </section>
2498     </section>
2500     <section id="sect-var-BUILD-TARGETS">
2501     <title>Fetching the List of Build Targets, Regardless of Origin: the &BUILD_TARGETS; Variable</title>
2503       <para>
2505       You have already seen the
2506       &COMMAND_LINE_TARGETS; variable,
2507       which contains a list of targets specified on the command line,
2508       and the &DEFAULT_TARGETS; variable,
2509       which contains a list of targets specified
2510       via calls to the &Default; method or function.
2511       Sometimes, however,
2512       you want a list of whatever targets
2513       &SCons; tries to build,
2514       regardless of whether the targets came from the
2515       command line or a &Default; call.
2516       You could code this up by hand, as follows:
2518       </para>
2520       <sconstruct>
2521 if COMMAND_LINE_TARGETS:
2522     targets = COMMAND_LINE_TARGETS
2523 else:
2524     targets = DEFAULT_TARGETS
2525       </sconstruct>
2527       <para>
2529       &SCons;, however, provides a convenient
2530       &BUILD_TARGETS; variable
2531       that eliminates the need for this by-hand manipulation.
2532       Essentially, the &BUILD_TARGETS; variable
2533       contains a list of the command-line targets,
2534       if any were specified,
2535       and if no command-line targets were specified,
2536       it contains a list of the targets specified
2537       via the &Default; method or function.
2539       </para>
2541       <para>
2543       Because &BUILD_TARGETS; may contain a list of &SCons; nodes,
2544       you must convert the list elements to strings
2545       if you want to print them or look for a specific target name,
2546       just like the &DEFAULT_TARGETS; list:
2548       </para>
2550       <scons_example name="commandline_BUILD_TARGETS_1">
2551         <file name="SConstruct" printme="1">
2552 prog1 = Program('prog1.c')
2553 Program('prog2.c')
2554 Default(prog1)
2555 print("BUILD_TARGETS is %s" % [str(t) for t in BUILD_TARGETS])
2556         </file>
2557         <file name="prog1.c">
2558 prog1.c
2559         </file>
2560         <file name="prog2.c">
2561 prog2.c
2562         </file>
2563       </scons_example>
2565       <para>
2567       Notice how the value of &BUILD_TARGETS;
2568       changes depending on whether a target is
2569       specified on the command line - &BUILD_TARGETS;
2570       takes from  &DEFAULT_TARGETS;
2571       only if there are no &COMMAND_LINE_TARGETS;:
2573       </para>
2575       <scons_output example="commandline_BUILD_TARGETS_1" suffix="1">
2576         <scons_output_command>scons -Q</scons_output_command>
2577         <scons_output_command>scons -Q prog2</scons_output_command>
2578         <scons_output_command>scons -Q -c .</scons_output_command>
2579       </scons_output>
2581     </section>
2583   </section>
2585 </chapter>