<!--  vim: set sw=2 sts=2 et ft=docbk:

  Part of the A-A-P recipe executive: How it all works.

  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

-->

<bridgehead>How Recipes Are Executed</bridgehead>

<para>
Executing recipes is a two step process:
<orderedlist>
<listitem><para>
recipe processing
</para>
<para>
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.
</para></listitem>
<listitem><para>
target building
</para>
<para>
Build each of the specified targets, following dependencies.
Build commands are executed.
</para></listitem>
</orderedlist>
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.
</para>

<para>
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.
</para>

<programlisting>
      :print executed during the first step

      target1 : source1 source2
            :print executed during the second step
</programlisting>

<para>
An exception is when &Aap; 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:
</para>
<literallayout>    % <userinput>aap -c ':print $BDIR'</userinput>
    executed during the first step
    build-FreeBSD4_5_RELEASE
    %
</literallayout>

<bridgehead>Common Recipe Structure</bridgehead>

<para>
A recipe used for building an application often has these parts:
<orderedlist>
<listitem><para>
    global settings, include recipes with project and/or user settings
</para></listitem>
<listitem><para>
    automatic configuration
</para></listitem>
<listitem><para>
    specify variants (e.g., debug/release)
</para></listitem>
<listitem><para>
    build rules and actions
</para></listitem>
<listitem><para>
    explicit dependencies
</para></listitem>
<listitem><para>
    high level build commands (
    <link linkend="cmd-program">:program</link>, 
    <link linkend="cmd-dll">:dll</link>, etc.)
</para></listitem>
</orderedlist>
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.
</para>

<para>
Now let us look into each part in more detail.
<orderedlist>
  <listitem>
    <para>
      global settings, include recipes with project and/or user settings
    </para>
    <para>
      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
      <literal>:include</literal> command in every recipe that can be used to build
      something.
    </para>
    <para>
      User preferences (e.g. configuration choices) should be in a separate
      file that the user edits (using a template).
    </para>
  </listitem>
  <listitem>
    <para>
      automatic configuration
    </para>
    <para>
      Find out properties of the system and handle user preferences.  This
      may result in building the application in a different way.
      See <xref linkend="user-autoconf"/>.
    </para>
  </listitem>
  <listitem>
    <para>
      specify variants
    </para>
    <para>
      Usually debug and release, but can include many more choices (type of
      GUI, small or big builds, etc.).
      This changes the value of <literal>BDIR</literal>.
    See <xref linkend="user-variant"/>.
    </para>
  </listitem>
  <listitem>
    <para>
      build rules and actions
    </para>
    <para>
      Rules that define dependencies and build commands that apply to
      several files, defined with <literal>:rule</literal> 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.
    </para>
  </listitem>
  <listitem>
    <para>
      explicit dependencies
    </para>
    <para>
      Dependencies and build commands that apply to specific files.
      Use these where the automatic dependency checking doesn't work and
      for exceptions.
    </para>
  </listitem>
  <listitem>
    <para>
      high level build commands
    </para>
    <para>
      <literal>:program</literal>, <literal>:dll</literal>, 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.
    </para>
  </listitem>
</orderedlist>
</para>

<para>
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.
</para>


<bridgehead>Building A Target In The First Step</bridgehead>

<para>
Since commands at the recipe level are executed in the first step, some
building may already be done.  Especially the <literal>:update</literal> 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.
</para>

<para>
A good use for the <literal>:update</literal> 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:
</para>

<programlisting>
      config.aap : config.aap.in
          :print executing the configuration script...
          :sys ./conf.sh &lt; $source &gt; $target

      :update config.aap
      :include config.aap
</programlisting>

<para>
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 <literal>:update config.aap</literal> 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 <literal>:include config.aap</literal> includes the up-to-date "config.aap"
recipe.
</para>


<bridgehead>Nesting The Steps</bridgehead>

<para>
In the second step commands of dependencies are executed.  One of these
commands may be <literal>:execute</literal>.  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:
</para>

<programlisting>
      docfile.html :
          :execute docs/main.aap $target
</programlisting>

<para>
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:
</para>

<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
</programlisting>

<para>
The <literal>:execute</literal> 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:
</para>

<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
</programlisting>


<bridgehead>Using Multiple Recipes</bridgehead>

<para>
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 <link linkend="cmd-child">:child</link> command.
</para>
<para>
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 <link linkend="cmd-include">:include</link> command to
use this recipe.  You need to take care that the recipe is not included twice,
because commands
like <link linkend="cmd-route">:route</link> give an error when
repeated and appending to variables must only be done once.
&Aap; will read a recipe only the first time it is included when you add the 
<literal>{once}</literal> argument
to the <link linkend="cmd-include">:include</link> command.
</para>

<bridgehead id="recipe-execution">Recipe Execution Details</bridgehead>

<para>
The two-step processing of recipes is part of all the work that &Aap; does.
There are a few other steps.
This is what happens when &Aap; is run:
<orderedlist>
<listitem><para>
Read the startup recipes, these define default rules and variables.  These
recipes are used:
<simplelist>
   <member> - <filename>default.aap</filename> from the distribution </member>
   <member> - all recipes in system and user &Aap; directories (see below)
   </member>
</simplelist>
</para></listitem>

<listitem><para>
Recipe processing: Read the recipe <filename>main.aap</filename> 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.
</para></listitem>

<listitem><para>
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.
</para></listitem>

<listitem><para>
Target building.  The first of the following that exists is used:
<simplelist>
        <member> - targets specified on the command line </member>
        <member> - items specified with
          <link linkend="cmd-program">:program</link>, 
          <link linkend="cmd-dll">:dll</link> and 
          <link linkend="cmd-lib">:lib</link> </member>
        <member> - the "all" target </member>
</simplelist>
</para></listitem>

<listitem><para>
If the "finally" target is specified, execute its build commands.
Each recipe can have its own "finally" target, they are all executed.
</para></listitem>
</orderedlist>
</para>

<para>
  The startup recipes are read from directories that depend on the system.
  For Unix systems files in two directories are used:
  <simplelist>
    <member> - <filename>/usr/local/share/aap/startup/*.aap</filename> </member>
    <member> - <filename>~/.aap/startup/*.aap</filename></member>
  </simplelist>
  For other systems one directory is used, the first one that can be found
  from this list:
  <simplelist>
    <member> - <filename>$HOME/aap/startup/*.aap</filename> </member>
    <member> - <filename>$HOMEDRIVE/$HOMEPATH/aap/startup/*.aap</filename></member>
    <member> - <filename>c:/aap/startup/*.aap</filename></member>
  </simplelist>
  $HOME, $HOMEDRIVE and $HOMEPATH are environment variables, not &Aap;
  variables.
</para>


<bridgehead>Use Of Variables</bridgehead>

<para>
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
<link linkend='ref-variables'>here</link>.
</para>

<para>
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:
</para>

<programlisting>
        $n
        $sources
        $FooFlags
        $MYPROG
</programlisting>

<para>
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:
</para>

<programlisting>
        $s_debug.CFLAGS
        $s_ovr.msg
</programlisting>


<bridgehead>Special Characters</bridgehead>

<para> <anchor id="special-characters"/>
  Some characters in expressions have a special meaning.  And a command like
  <link linkend="cmd-print">:print</link>
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
<link linkend="cmd-print">:print</link>
command:
</para>
<table frame="none">
  <title>Special characters in the ":print" command</title>
  <tgroup cols="2">
    <colspec colwidth="200"/>
    <thead>
      <row>
        <entry>
          <link linkend="cmd-print">:print</link> argument</entry>
        <entry>resulting character</entry>
      </row>
    </thead>
    <tbody>
      <row>
        <entry>$($)</entry>
        <entry>$</entry>
      </row>
      <row>
        <entry>$(`)</entry>
        <entry>` (backtick)</entry>
      </row>
      <row>
        <entry>$(#)</entry>
        <entry>#</entry>
      </row>
      <row>
        <entry>$(&gt;)</entry>
        <entry>&gt;</entry>
      </row>
      <row>
        <entry>$(&lt;)</entry>
        <entry>&lt;</entry>
      </row>
      <row>
        <entry>$(|)</entry>
        <entry>|</entry>
      </row>
    </tbody>
  </tgroup>
</table>
<para>
Example:
</para>
<programlisting>
    all:
        :print tie $(#)2 $(`)green$(`) $(|) price: $($) 13 $(&lt;) incl vat $(&gt;)
</programlisting>
<para>
Write this in the file "try.aap".  Executing it results in:
<literallayout>    % <userinput>aap -f try.aap</userinput>
    tie #2 `green` | price: $ 13 &lt; incl vat &gt;
    %
</literallayout>
</para>


<bridgehead>Line Syntax</bridgehead>

<para>
&Aap; 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:
<programlisting>
1   One line
2   A longer line \
3   that continues \
4   over three physical lines.
</programlisting>
You can always use backslash continuations to continue
lines in &Aap;. Indentation does not matter.
</para>

<para>
In many constructions, &Aap; 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:
<programlisting>
1   One line
2   A longer line
3       that continues
4       over three physical lines.
</programlisting>
As you can see, the &quot;block&quot; of lines
with an increased amount of indentation is considered
to belong to the line above it.
</para>

<para>
Python-style line continuations are supported
in all &Aap; 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:
</para>
<programlisting>
    myprog
            : mysource
        :print This Does Not Work!
</programlisting>
<para>
  It is also not possible to split a dependency by indent
  when it does not have build commands:
</para>
<programlisting>
    myprog :
          mysource
    this = Does Not Work
</programlisting>
<para>
  You must use a backslash in this situation:
</para>
<programlisting>
    myprog : \
          mysource
    this = OK
</programlisting>
