Sophie

Sophie

distrib > Mandriva > 2010.0 > i586 > media > contrib-release > by-pkgid > a6d417e36f6bb1154f4c003e6717e298 > files > 149

a-a-p-1.090-2mdv2009.0.noarch.rpm

<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>Chapter 12. How it all works</title><meta name="generator" content="DocBook XSL Stylesheets V1.71.1"><link rel="start" href="index.html" title="A-A-P Recipe Executive"><link rel="up" href="user.html" title="Part II. User Manual"><link rel="prev" href="user.html" title="Part II. User Manual"><link rel="next" href="user-depend.html" title="Chapter 13. Dependencies, Rules and Actions"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><table width="100%" id="navtable"><tbody><tr><td align="left" class="left" width="33%"><b><a href="http://www.a-a-p.org">A-A-P home page</a></b></td><td align="center" class="center" width="34%"><b><a href="index.html">A-A-P Recipe Executive</a></b></td><td align="right" class="right" width="33%"></td></tr><tr><td align="left" class="left"><a accesskey="p" href="user.html">Prev</a></td><td align="center" class="center">User Manual</td><td align="right" class="right"><a accesskey="n" href="user-depend.html">Next</a></td></tr></tbody></table><hr><div class="chapter" lang="en"><div class="titlepage"><div><div><h2 class="title"><a name="user-basics"></a>Chapter 12. How it all works</h2></div></div></div><h2><a name="id2633931"></a>How Recipes Are Executed</h2><p>
Executing recipes is a two step process:
</p><div class="orderedlist"><ol type="1"><li><p>
recipe processing
</p><p>
Read and parse the toplevel recipe, child recipes and included recipes.
Commands at the recipe level are executed.
Build commands (commands for dependencies, rules, actions, etc.) are stored.
</p></li><li><p>
target building
</p><p>
Build each of the specified targets, following dependencies.
Build commands are executed.
</p></li></ol></div><p>
Generally, one can say that in the first step the specification for the
building is read and stored.  In the second step the actual building is done.
</p><p>
In a simple recipe the first step is used to set variables and define
dependencies.  In the second step the dependencies are followed and their
commands are executed to build the specified target.
</p><pre class="programlisting">
      :print executed during the first step

      target1 : source1 source2
            :print executed during the second step
</pre><p>
An exception is when <span class="application">Aap</span> was started to execute a command directly.
The recipe processing step will still be done, but instead of building a
target the specified command is executed.  Example, using the recipe above:
</p><div class="literallayout"><p>    % <strong class="userinput"><code>aap -c ':print $BDIR'</code></strong><br>
    executed during the first step<br>
    build-FreeBSD4_5_RELEASE<br>
    %<br>
</p></div><h2><a name="id2634060"></a>Common Recipe Structure</h2><p>
A recipe used for building an application often has these parts:
</p><div class="orderedlist"><ol type="1"><li><p>
    global settings, include recipes with project and/or user settings
</p></li><li><p>
    automatic configuration
</p></li><li><p>
    specify variants (e.g., debug/release)
</p></li><li><p>
    build rules and actions
</p></li><li><p>
    explicit dependencies
</p></li><li><p>
    high level build commands (
    <a href="ref-commands.html#cmd-program">:program</a>, 
    <a href="ref-commands.html#cmd-dll">:dll</a>, etc.)
</p></li></ol></div><p>
You are free to use this structure or something else, of course.
This is an explanation that you can use as a base.
Many times you will be able to use this structure as a starting point and make
small modifications where it is needed.
</p><p>
Now let us look into each part in more detail.
</p><div class="orderedlist"><ol type="1"><li><p>
      global settings, include recipes with project and/or user settings
    </p><p>
      When the recipe is part of a project, it's often useful to move settings
      (and rules) that apply to the whole project to one file.  Then use the
      <code class="literal">:include</code> command in every recipe that can be used to build
      something.
    </p><p>
      User preferences (e.g. configuration choices) should be in a separate
      file that the user edits (using a template).
    </p></li><li><p>
      automatic configuration
    </p><p>
      Find out properties of the system and handle user preferences.  This
      may result in building the application in a different way.
      See <a href="user-autoconf.html" title="Chapter 24. Using Autoconf">Chapter 24, <i>Using Autoconf</i></a>.
    </p></li><li><p>
      specify variants
    </p><p>
      Usually debug and release, but can include many more choices (type of
      GUI, small or big builds, etc.).
      This changes the value of <code class="literal">BDIR</code>.
    See <a href="user-variant.html" title="Chapter 14. Variants">Chapter 14, <i>Variants</i></a>.
    </p></li><li><p>
      build rules and actions
    </p><p>
      Rules that define dependencies and build commands that apply to
      several files, defined with <code class="literal">:rule</code> commands. 
      Actions can be defined for what is not included in the default actions
      or to overrule the defaults actions to do a different way of building.
    </p></li><li><p>
      explicit dependencies
    </p><p>
      Dependencies and build commands that apply to specific files.
      Use these where the automatic dependency checking doesn't work and
      for exceptions.
    </p></li><li><p>
      high level build commands
    </p><p>
      <code class="literal">:program</code>, <code class="literal">:dll</code>, etc. can be used for standard
      programs, libraries, etc.  This comes last, so that explicitly defined
      dependencies for building some of the items can be used.
    </p></li></ol></div><p>
</p><p>
For larger projects sections can be moved to other recipes.  How you want to
do this depends on whether these sub-recipes need to be executed by
themselves and who is going to maintain each recipe.  More about that below.
</p><h2><a name="id2635661"></a>Building A Target In The First Step</h2><p>
Since commands at the recipe level are executed in the first step, some
building may already be done.  Especially the <code class="literal">:update</code> command
gives you a powerful mechanism.  This means you can already build a target
halfway the first step.  Note that only dependencies that have already been
encountered will be used then.
</p><p>
A good use for the <code class="literal">:update</code> command at the recipe level is to
generate a recipe that you want to include.  Useful for automatic
configuration.  You would do something like this:
</p><pre class="programlisting">
      config.aap : config.aap.in
          :print executing the configuration script...
          :sys ./conf.sh &lt; $source &gt; $target

      :update config.aap
      :include config.aap
</pre><p>
First a dependency is specified with build commands for the included recipe.
In this case the "config.aap.in" file is used as a template.
The command <code class="literal">:update config.aap</code> invokes building "config.aap".  If
it is outdated (config.aap.in was changed since config.aap was last build) the
build commands are executed.  If "config.aap" is up-to-date nothing happens.
Then the <code class="literal">:include config.aap</code> includes the up-to-date "config.aap"
recipe.
</p><h2><a name="id2635703"></a>Nesting The Steps</h2><p>
In the second step commands of dependencies are executed.  One of these
commands may be <code class="literal">:execute</code>.  This means another recipe is read and
targets are build.  These are again the first and second step mentioned before,
but now nested inside the second step.  Here is an example
that executes a recipe when "docfile.html" is to be build:
</p><pre class="programlisting">
      docfile.html :
          :execute docs/main.aap $target
</pre><p>
This construction is useful when you do not want to read the other recipe in
the first step.  Either because it is a large recipe that is not always
needed, because the recipe does not always exist, or because the recipe must
first be build by other commands.  Here is an example of using a depencency on
a recipe:
</p><pre class="programlisting">
      docfile.html : docs/main.aap
          :execute docs/main.aap $target

      docs/main.aap: docs/main.aap.in
          :cd docs
          :sys ./conf.sh &lt; main.aap.in &gt; main.aap
</pre><p>
The <code class="literal">:execute</code> command can also be used at the recipe level.  This
means another recipe is executed during the first step.  A good example for
this is building an application in different variants:
</p><pre class="programlisting">
      # build the GTK version
      :execute main.aap Gui=GTK myprog
      :move myprog myprog-GTK

      # build the Motif version
      :execute main.aap Gui=Motif myprog
      :move myprog myprog-Motif
</pre><h2><a name="id2635812"></a>Using Multiple Recipes</h2><p>
There are many ways to split up a project into multiple recipes.  If you are
building one application, you mostly build the whole application, using a
toplevel recipe.  This recipe specifies the configuration, specifies variants
and sets variables for choices.  Separate recipes are used to handle specific
tasks.  For example, you can move related sources to a sub-directory and put a
recipe in that directory to build those sources.  For this situation you use
the <a href="ref-commands.html#cmd-child">:child</a> command.
</p><p>
When a project gets bigger, and especially when working together with several
people, you may want to be able to split the project up in smaller pieces,
which each can be build separately. To avoid replicating commands, you should
put the configuration, variants and setting variables in a separate recipe.
Each recipe can use the <a href="ref-commands.html#cmd-include">:include</a> command to
use this recipe.  You need to take care that the recipe is not included twice,
because commands
like <a href="ref-commands.html#cmd-route">:route</a> give an error when
repeated and appending to variables must only be done once.
<span class="application">Aap</span> will read a recipe only the first time it is included when you add the 
<code class="literal">{once}</code> argument
to the <a href="ref-commands.html#cmd-include">:include</a> command.
</p><h2><a name="recipe-execution"></a>Recipe Execution Details</h2><p>
The two-step processing of recipes is part of all the work that <span class="application">Aap</span> does.
There are a few other steps.
This is what happens when <span class="application">Aap</span> is run:
</p><div class="orderedlist"><ol type="1"><li><p>
Read the startup recipes, these define default rules and variables.  These
recipes are used:
</p><table class="simplelist" border="0" summary="Simple list"><tr><td> - <code class="filename">default.aap</code> from the distribution </td></tr><tr><td> - all recipes in system and user <span class="application">Aap</span> directories (see below)
   </td></tr></table><p>
</p></li><li><p>
Recipe processing: Read the recipe <code class="filename">main.aap</code> or the one specified with the
"-f" argument and check for obvious errors.
Then execute the toplevel items in the recipe.  Dependencies and rules are
stored.  Also read included and child recipes and execute the toplevel items
in them.
</p></li><li><p>
Apply the clever stuff to add missing dependencies and rules.  This adds a
"clean" rule only if the recipe didn't specify one, for example.
</p></li><li><p>
Target building.  The first of the following that exists is used:
</p><table class="simplelist" border="0" summary="Simple list"><tr><td> - targets specified on the command line </td></tr><tr><td> - items specified with
          <a href="ref-commands.html#cmd-program">:program</a>, 
          <a href="ref-commands.html#cmd-dll">:dll</a> and 
          <a href="ref-commands.html#cmd-lib">:lib</a> </td></tr><tr><td> - the "all" target </td></tr></table><p>
</p></li><li><p>
If the "finally" target is specified, execute its build commands.
Each recipe can have its own "finally" target, they are all executed.
</p></li></ol></div><p>
</p><p>
  The startup recipes are read from directories that depend on the system.
  For Unix systems files in two directories are used:
  </p><table class="simplelist" border="0" summary="Simple list"><tr><td> - <code class="filename">/usr/local/share/aap/startup/*.aap</code> </td></tr><tr><td> - <code class="filename">~/.aap/startup/*.aap</code></td></tr></table><p>
  For other systems one directory is used, the first one that can be found
  from this list:
  </p><table class="simplelist" border="0" summary="Simple list"><tr><td> - <code class="filename">$HOME/aap/startup/*.aap</code> </td></tr><tr><td> - <code class="filename">$HOMEDRIVE/$HOMEPATH/aap/startup/*.aap</code></td></tr><tr><td> - <code class="filename">c:/aap/startup/*.aap</code></td></tr></table><p>
  $HOME, $HOMEDRIVE and $HOMEPATH are environment variables, not <span class="application">Aap</span>
  variables.
</p><h2><a name="id2636026"></a>Use Of Variables</h2><p>
Variables with uppercase letters are generally used to pass choices and
options to actions.  For example, $CC is the name of the C compiler and
$CFLAGS optional arguments for the C compiler.  The list of predefined
variables is in the reference manual
<a href="ref-variables.html" title="Chapter 35. Common Variables">here</a>.
</p><p>
To avoid clashing with an existing or future variable that is defined by Aap,
use one or more lower case letters or prepend "MY".  Examples:
</p><pre class="programlisting">
        $n
        $sources
        $FooFlags
        $MYPROG
</pre><p>
Also be careful with chosing a name for a user scope, it must be different
from all variables used in recipes!  Prepending "s_" is recommended.
Examples:
</p><pre class="programlisting">
        $s_debug.CFLAGS
        $s_ovr.msg
</pre><h2><a name="id2636057"></a>Special Characters</h2><p> <a name="special-characters"></a>
  Some characters in expressions have a special meaning.  And a command like
  <a href="ref-commands.html#cmd-print">:print</a>
also handles a few arguments in a special way.  This table gives an
overview of which characters you need to watch out for when using the
<a href="ref-commands.html#cmd-print">:print</a>
command:
</p><div class="table"><a name="id2636078"></a><p class="title"><b>Table 12.1. Special characters in the ":print" command</b></p><div class="table-contents"><table summary='Special characters in the ":print" command' border="0"><colgroup><col width="200"><col></colgroup><thead><tr><th>
          <a href="ref-commands.html#cmd-print">:print</a> argument</th><th>resulting character</th></tr></thead><tbody><tr><td>$($)</td><td>$</td></tr><tr><td>$(`)</td><td>` (backtick)</td></tr><tr><td>$(#)</td><td>#</td></tr><tr><td>$(&gt;)</td><td>&gt;</td></tr><tr><td>$(&lt;)</td><td>&lt;</td></tr><tr><td>$(|)</td><td>|</td></tr></tbody></table></div></div><br class="table-break"><p>
Example:
</p><pre class="programlisting">
    all:
        :print tie $(#)2 $(`)green$(`) $(|) price: $($) 13 $(&lt;) incl vat $(&gt;)
</pre><p>
Write this in the file "try.aap".  Executing it results in:
</p><div class="literallayout"><p>    % <strong class="userinput"><code>aap -f try.aap</code></strong><br>
    tie #2 `green` | price: $ 13 &lt; incl vat &gt;<br>
    %<br>
</p></div><p>
</p><h2><a name="id2636339"></a>Line Syntax</h2><p>
<span class="application">Aap</span> parses the recipe into a sequence of lines.
A line is a sequence of characters terminated by a newline.
You can escape the newline with a backslash to continue
a logical line over more than one physical line,
as follows:
</p><pre class="programlisting">
1   One line
2   A longer line \
3   that continues \
4   over three physical lines.
</pre><p>
You can always use backslash continuations to continue
lines in <span class="application">Aap</span>. Indentation does not matter.
</p><p>
In many constructions, <span class="application">Aap</span> also supports Python-style
line continuations, where a line is continued by
increasing the indentation of subsequent physical lines.
The above example would look different with
Python-style continuation:
</p><pre class="programlisting">
1   One line
2   A longer line
3       that continues
4       over three physical lines.
</pre><p>
As you can see, the "block" of lines
with an increased amount of indentation is considered
to belong to the line above it.
</p><p>
Python-style line continuations are supported
in all <span class="application">Aap</span> constructions except when the command cannot be recognized if the
linebreak comes early.  For example,
in dependencies the colon separating the targets from the sources cannot be in
a continuation line.  This does not work:
</p><pre class="programlisting">
    myprog
            : mysource
        :print This Does Not Work!
</pre><p>
  It is also not possible to split a dependency by indent
  when it does not have build commands:
</p><pre class="programlisting">
    myprog :
          mysource
    this = Does Not Work
</pre><p>
  You must use a backslash in this situation:
</p><pre class="programlisting">
    myprog : \
          mysource
    this = OK
</pre></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="user.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="user.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="user-depend.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Part II. User Manual </td><td width="20%" align="center"><a accesskey="h" href="index.html">
		    Contents</a></td><td width="40%" align="right" valign="top"> Chapter 13. Dependencies, Rules and Actions</td></tr></table></div></body></html>