1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
|
<!-- vim: set sw=2 sts=2 et ft=docbk:
Part of the A-A-P recipe executive: Tutorial - Variants
Copyright (C) 2002-2003 Stichting NLnet Labs
Permission to copy and use this file is specified in the file COPYING.
If this file is missing you can find it here: http://www.a-a-p.org/COPYING
-->
<para>
A-A-P provides a way to build two variants of the same application. You
just need to specify what is different about them. A-A-P will then take care
of putting the resulting files in a different directory, so that you don't
have to recompile everything when you toggle between two variants.
</para>
<para>
For the details see
<link linkend="cmd-variant">:variant</link> in the reference manual.
</para>
<bridgehead id="build-variant">One Choice</bridgehead>
<para>
Quite often you want to compile an application for release with maximal
optimizing. But the optimizer confuses the debugger, thus when stepping
through the program to locate a problem, you want to recompile without
optimizing. Here is an example:
</para>
<programlisting>
1 Source = main.c version.c gui.c
2
3 :variant Build
4 release
5 OPTIMIZE = 4
6 Target = myprog
7 debug
8 DEBUG = yes
9 Target = myprogd
10
11 :program $Target : $Source
</programlisting>
<para>
Write this recipe as "main.aap" and run &Aap; without arguments. This will
build "myprog" and use a directory for the object files that ends in
"-release". The release variant is the first one mentioned, that makes it the
default choice.
</para>
<para>
The first argument for the <computeroutput>:variant</computeroutput> command is
<literal>Build</literal>. This is
the name of the variable that specifies what variant will be selected. The
names of the alternatives
are specified with a bit more indent in lines 4 and 7. For each alternative
two commands are given, again with more indent. Note that the indent not only
makes it easy for you to see the parts of the <computeroutput>:variant</computeroutput> command, they are
essential for &Aap; to recognize them.
</para>
<para>
To select the "debug" variant the <literal>Build</literal> variable must be set to "debug". A
convenient way to do this is by specifying this on the command line:
</para>
<literallayout> % <userinput>aap Build=debug</userinput>
</literallayout>
<para>
This will build the "myprogd" program for debugging instead of for release.
The <literal>DEBUG</literal> variable is recognized by &Aap;.
The object files are stored in a directory ending in
"-debug". Once you finished debugging and fixed the problem in, for example,
"gui.c", running &Aap; to build the release variant will only compile the
modified file. There is no need to compile all the C files, because the object
files for the "release" variant are still in the "-release" directory.
</para>
<bridgehead>Two Choices</bridgehead>
<para>
You can extend the <literal>Build</literal> variant with more items, for example
"profile". This is useful for alternatives that exclude each other. Another
possibility is to add a second <computeroutput>:variant</computeroutput> command. Let us
extend the example with a selection of the user interface type.
</para>
<programlisting>
1 Source = main.c version.c gui.c
2
3 :variant Build
4 release
5 OPTIMIZE = 4
6 Target = myprog
7 debug
8 DEBUG = yes
9 Target = myprogd
10
11 Gui ?= motif
12 :variant Gui
13 console
14 motif
15 Source += motif.c
16 gtk
17 Source += gtk.c
18
19 DEFINE += -DGUI=$Gui
20
21 :program $Target : $Source
</programlisting>
<para>
The <computeroutput>:variant</computeroutput> command in line 12 uses the <literal>Gui</literal>
variable to select one of "console", "motif" or "gtk". Together with the
earlier <computeroutput>:variant</computeroutput> command this offers six alternatives:
"release" with "console", "debug" with "console", "release" with "motif", etc.
To build "debug" with "gtk" use this command:
</para>
<literallayout> % <userinput>aap Build=debug Gui=gtk</userinput>
</literallayout>
<para>
In line 11 an optional assignment "?=" is used. This assignment is skipped if
the <literal>Gui</literal> variable already has a value. Thus if <literal>Gui</literal> was
given a value on the command line, as in the example above, it will keep this
value. Otherwise it will get the value "motif".
</para>
<note>
<title>Environment variables</title>
<para>
Environment variables are not used for variables in the recipe, like
<literal>make</literal> does. When you happen to have a <literal>Gui</literal> environment
variable, this will not influence the variant in the recipe. This is
especially useful if you are not aware of what environment variables are set
and/or which variables are used in the recipe. If you intentionally want to
use an environment variable this can be specified with a Python expression (see the next chapter).
</para>
</note>
<para>
In line 15, 17 and 19 the append assignment "+=" is used. This appends the argument
to an existing variable. A space is inserted if the value was not empty. For
the variant "motif" the result of line 15 is that
<literal>Source</literal> becomes "main.c version.c gui.c motif.c".
</para>
<para>
The "motif" and "gtk" variants each add a source file in line 15 and 17. For
the console version no extra file is needed. The object files for each
combination of variants end up in a different directory. Ultimately you get
object files in each of the six directories ("SYS" stands for the platform
being used):
<informaltable frame="none">
<tgroup cols="2">
<colspec colwidth="250"/>
<thead>
<row><entry>directory</entry> <entry>contains files</entry></row>
</thead>
<tbody>
<row><entry>build-SYS-release-console</entry> <entry>main, version, gui</entry></row>
<row><entry>build-SYS-debug-console</entry> <entry>main, version, gui</entry></row>
<row><entry>build-SYS-release-motif</entry> <entry>main, version, gui, motif</entry></row>
<row><entry>build-SYS-debug-motif</entry> <entry>main, version, gui, motif</entry></row>
<row><entry>build-SYS-release-gtk</entry> <entry>main, version, gui, gtk</entry></row>
<row><entry>build-SYS-debug-gtk</entry> <entry>main, version, gui, gtk</entry></row>
</tbody>
</tgroup>
</informaltable>
</para>
<para>
See the <link linkend='user-variant'>user manual</link>
for more examples of using variants.
</para>
|