Sophie

Sophie

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

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 2. Compiling a Program</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="tutorial.html" title="Part I. Tutorial"><link rel="prev" href="tutor-start.html" title="Chapter 1. Getting Started"><link rel="next" href="tutor-website.html" title="Chapter 3. Publishing a Web Site"></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="tutor-start.html">Prev</a></td><td align="center" class="center">Tutorial</td><td align="right" class="right"><a accesskey="n" href="tutor-website.html">Next</a></td></tr></tbody></table><hr><div class="chapter" lang="en"><div class="titlepage"><div><div><h2 class="title"><a name="tutor-compile"></a>Chapter 2. Compiling a Program</h2></div></div></div><a name="sec-hello"></a><h2><a name="id2569996"></a>A "Hello world" (of sorts)</h2><p>
Most programming languages start with a short example that prints a "hello
world" message.  With <span class="application">Aap</span>, this is also possible.
In a file called <code class="filename">main.aap</code>,
enter the following:
</p><pre class="programlisting">
    :print Hello, World!
</pre><p>
Now run <span class="application">Aap</span> by entering <strong class="userinput"><code>aap</code></strong> at the
command line. <span class="application">Aap</span> will respond something like this:
</p><div class="literallayout"><p>    % <strong class="userinput"><code>aap</code></strong><br>
    <code class="computeroutput">Hello, World!</code><br>
    <code class="computeroutput">Aap: No target on the command line and no $TARGET, build rules or "all" target in a recipe</code><br>
</p></div><p>
As you can see, <span class="application">Aap</span> outputs the desired text, but also prints an error message.
This is because <span class="application">Aap</span> is not a programming language, but a language
for describing how to
<span class="emphasis"><em>compile and build</em></span> programs (written in other languages).
In other words, if you have written a "hello world" program in some language,
then you can use <span class="application">Aap</span> to compile that program.
</p><h2><a name="id2571585"></a>Using <span class="application">Aap</span> to compile "hello.c"</h2><p>
Suppose you have written a "hello world" program in C, and the
sources are stored in a file called <code class="filename">hello.c</code>.
<span class="application">Aap</span> already knows about the C language (and several others),
so the instructions to <span class="application">Aap</span> about how to compile this program are very
short.
Instructions for <span class="application">Aap</span> are stored in a file with the extension
<code class="filename">.aap</code>.  Such a file is called a recipe.
</p><p>
<a class="indexterm" name="id2623305"></a>
This is the recipe for compiling such a program with <span class="application">Aap</span>:
</p><pre class="programlisting">
    :program hello : hello.c
</pre><p>
Write this text in a file <code class="filename">main.aap</code>, in the same directory as
<code class="filename">hello.c</code>.
Now invoke <span class="application">Aap</span> to compile <code class="filename">hello.c</code> into the program
<code class="filename">hello</code>:
<a class="indexterm" name="id2623355"></a>
</p><div class="literallayout"><p>    % <strong class="userinput"><code>ls</code></strong><br>
    hello.c             main.aap<br>
    % <strong class="userinput"><code>aap</code></strong><br>
1   Aap: Creating directory "/home/mool/tmp/build-FreeBSD4_5_RELEASE"<br>
2   Aap: cc -I/usr/local/include -g -O2 -E -MM hello.c &gt; build-FreeBSD4_5_RELEASE/hello.c.aap<br>
3   Aap: cc -I/usr/local/include -g -O2 -c -o build-FreeBSD4_5_RELEASE/hello.o hello.c<br>
4   Aap: cc -L/usr/local/lib -g -O2 -o hello build-FreeBSD4_5_RELEASE/hello.o<br>
</p></div><p>
You see the commands <span class="application">Aap</span> uses to compile the program:
</p><div class="orderedlist"><ol type="1"><li><p>
    A directory is created to write the intermediate results in.  This
    directory is different for each platform, thus you can compile the same
    program for different systems without cleaning up.
    </p></li><li><p>
    Dependencies are figured out for the source file.
    <span class="application">Aap</span> will automatically detect
    dependencies on included files and knows that if one of the included files
    changed compilation needs to be done, even when the file itself didn't
    change.
    In this example, <span class="application">Aap</span> uses the C compiler with the <code class="literal">-MM</code>
    option to determine the included files.
    </p></li><li><p>
    The "hello.c" program file is compiled into the "hello.o" object file
    (on MS-Windows that would be "hello.obj").
    </p></li><li><p>
    The "hello.o" object file is linked to produce the "hello" program
    (on MS-Windows this would be "hello.exe", the ".exe" is added
    automatically).
    </p></li></ol></div><p>
</p><h2><a name="id2623513"></a>Other things to do with "hello world"</h2><p>
The same simple recipe not only specifies how to build the "hello" program, it
can also be used to install the program:
<a class="indexterm" name="id2623520"></a>
</p><div class="literallayout"><p>    % <strong class="userinput"><code>aap install PREFIX=try</code></strong><br>
    Aap: Creating directory "try/bin/"<br>
    Aap: Copied "test/hello" to "try/bin/hello"<br>
    Aap: /usr/bin/strip 'try/bin/hello'<br>
</p></div><p>
The <code class="literal">PREFIX</code> variable specifies where to install the program.
The default is <code class="filename">/usr/local</code>.
For the example we use the <code class="filename">try</code> directory,
which doesn't exist.  <span class="application">Aap</span> creates  it for you.
</p><p>
Other ways that this recipe can be used:
</p><div class="literallayout"><p>    <strong class="userinput"><code>aap uninstall</code></strong>    undo installing the program<br>
    <strong class="userinput"><code>aap clean</code></strong>          cleanup the generated files<br>
    <strong class="userinput"><code>aap cleanALL</code></strong>     cleanup all files (careful!)<br>
</p></div><p>
</p><p>
  See the reference manual for details about
  <a href="ref-commands.html#cmd-program">:program</a>.
</p><h2><a name="id2623609"></a>Several Source Files</h2><p>
When you have several files with source code you can specify them as a list:
</p><pre class="programlisting">
    :program myprogram : main.c
                         version.c
                         help.c
</pre><p>
There are three source files: <code class="filename">main.c</code>,
<code class="filename">version.c</code> and <code class="filename">help.c</code>.
Notice that it is not necessary to use a line continuation character, as you
would have to do in a Makefile.  The list ends at a line where the indent is
equal to or less than what the assignment started with.
The amount of indent for the continuation lines is irrelevant, so long as it's
more than the indent of the first line.
</p><p>
  The Makefile-style line continuation with a backslash just before the line
  break can also be used, by the way.
</p><p>
<a class="indexterm" name="id2623645"></a>
Indents are very important, just like in a Python script.  Make sure your
tabstop is always set to the standard value of eight, otherwise you might run
into trouble when mixing tabs and spaces!
</p><p>
When you give a list of files to <a href="ref-commands.html#cmd-program">:program</a>,
<span class="application">Aap</span> will determine dependencies and compile each of the source
files in turn, and then link them all together into an executable.
</p><h2><a name="id2623668"></a>Variables and Assignments</h2><p>
Sometimes it is convenient to have an abbreviation for a long list
of files.
<span class="application">Aap</span> supports this through variables (just like
the <span class="application">make</span> command and the shell).
</p><p>
An assignment has the form:
</p><div class="literallayout"><p>    variablename = expression<br>
</p></div><p>
The variable name is the usual combination of letters, digits and underscore.
It must start with a letter.  Upper and lower case letters can be used and case
matters.  To see this in action, write this recipe in a file with the name
<code class="filename">try.aap</code>:
</p><pre class="programlisting">
    foo = one
    Foo = two
    FOO = three
    :print $foo $Foo $FOO
</pre><p>
<span class="application">Aap</span> normally reads the recipe from <code class="filename">main.aap</code>,
but you can tell it to read a different file if you want to.
Use the <strong class="userinput"><code>-f</code></strong> flag for this.
Now execute the recipe:
<a class="indexterm" name="id2623796"></a>
</p><div class="literallayout"><p>    % <strong class="userinput"><code>aap -f try.aap</code></strong><br>
    one two three<br>
    Aap: No target on the command line and no build rules or "all" target in a recipe<br>
</p></div><p>
<a class="indexterm" name="id2623820"></a>
<a class="indexterm" name="id2623827"></a>
The
<a href="ref-commands.html#cmd-print">:print</a>
command prints its argument.  You can see that a variable name
preceded with a dollar is replaced by the value of the variable.
The three variables that only differ by case each have a different value.
<span class="application">Aap</span> also complains that there is nothing to build, just like
in the <a href="tutor-compile.html#sec-hello">hello world example</a>.
</p><p>
If you want text directly after the variable's value, for example,
to append an extension to the value of a variable,
the text may be impossible to distinguish from a variable name.
In these cases you must put
parenthesis around the variable name, so that <span class="application">Aap</span> knows where it ends:
</p><pre class="programlisting">
    all:
      MakeName = Make
      :print $(MakeName)file    # 'f' can be in a variable name
      :print $(MakeName).txt    # '.' can be in a variable name
      :print $MakeName-more     # '-' is not in a variable name
</pre><div class="literallayout"><p>    % <strong class="userinput"><code>aap -f try.aap</code></strong><br>
    Makefile<br>
    Make.txt<br>
    Make-more<br>
    %<br>
</p></div><p>
All <span class="application">Aap</span> commands, except the assignment, start with a colon.  That makes
them easy to recognize.
</p><p>
  Some characters in the expression have a special meaning.  The
  <a href="ref-commands.html#cmd-print">:print</a>
command also handles a few arguments in a special way.  To avoid the special
meaning use the $(x) form, where "x" is the special character.  For example,
to print a literal dollar use $($).  See
<a href="user-basics.html#special-characters">the user manual</a> for 
a complete list.
</p><h2><a name="id2623902"></a>Comments</h2><p>
Someone who sees this recipe would like to know what it's for.  This requires
adding comments.  These start with a "#" character and extend until the end of
the line (like in a Makefile and Python script).
</p><p>
It is also possible to associate a comment with a specific item:
</p><pre class="programlisting">
    # A-A-P recipe for compiling "myprogram"
    :program myprogram { comment = MyProgram is really great } :
            main.c            # startup stuff
            version.c         # just the date stamp
            help.c            # display a help message
</pre><p>
Now run <span class="application">Aap</span> with a "comment" argument:
</p><div class="literallayout"><p>    % <strong class="userinput"><code>aap comment</code></strong><br>
    <code class="computeroutput">target "myprogram": MyProgram is really great</code><br>
    <code class="computeroutput">target "clean": delete generated files that are not distributed</code><br>
    <code class="computeroutput">target "cleanmore": delete all generated files</code><br>
    <code class="computeroutput">target "cleanALL": delete all generated files, AAPDIR and build-* directories</code><br>
    <code class="computeroutput">target "install": install files</code><br>
    <code class="computeroutput">target "uninstall": delete installed files</code><br>
    %<br>
</p></div><p>
<a class="indexterm" name="id2623977"></a>
The text inside curly braces is called an attribute.
In this case the attribute name is "comment" and the attribute value is 
"MyProgram is really great".
An attribute can be used to attach extra information to a file name.  We will
encounter more attributes later on.
</p><h2><a name="id2623985"></a>Dependencies</h2><p>
Let's go back to the "Hello world" example and find out what happens when
you change a source file.  Use this <code class="filename">hello.c</code> file:
</p><pre class="programlisting">
    #include &lt;stdio.h&gt;
    #include "hello.h"
    main()
    {
        printf("Hello %s\n", world);
    }
</pre><p>
The included "hello.h" file defines "world":
</p><pre class="programlisting">
    #define world "World!"
</pre><p>
If you run <span class="application">Aap</span>, the "hello" program will be built as before.  If you run
<span class="application">Aap</span> again you will notice that nothing happens.  <span class="application">Aap</span> remembers that
"hello.c" was already compiled.  Now try this:
</p><div class="literallayout"><p>    % <strong class="userinput"><code>touch hello.c</code></strong><br>
    % <strong class="userinput"><code>aap</code></strong><br>
    %<br>
</p></div><p>
If you have been using the "make" program you would expect something to happen.
But <span class="application">Aap</span> checks the <span class="emphasis"><em>contents</em></span> 
of the file, not the timestamp.  A signature of
"hello.c" is computed and if it is still the same as before <span class="application">Aap</span> knows that
it does not need to be compiled, even though "hello.c" is newer than the
"hello" program.
</p><p>
  <span class="application">Aap</span> uses the mechanism of dependencies.  When you use the
  <a href="ref-commands.html#cmd-program">:program</a>
  command
<span class="application">Aap</span> knows that the target depends on the sources.  When one of the
sources changes, the commands to build the target from the sources must be
executed.  This can also be specified explicitly:
</p><pre class="programlisting">
      hello$EXESUF : $BDIR/hello$OBJSUF
          :do build $source

      $BDIR/hello$OBJSUF : hello.c
          :do compile $source
</pre><p>
The generic form of a dependency is:
</p><div class="literallayout"><p>      target : list-of-sources<br>
           build-commands<br>
</p></div><p>
The colon after the target is important, it separates the target from the
sources.  It is not required to put a space before it, but there must be a
space after it.  We mostly put white space before the colon, so that it is
easy to spot.  There could be several targets, but that is unusual.
</p><p>
There are two dependencies in the example.
In the first one the target is "hello$EXESUF", the source file is
"$BDIR/hello$OBJSUF" and the build command is ":do build $source".  This
specifies how to build the "hello$EXESUF" program from the
"$BDIR/hello$OBJSUF" object file.
The second dependency specifies how to compile "hello.c" into
"$BDIR/hello$OBJSUF"
with the command ":do compile $source".
The "BDIR" variable holds the name of the platform-dependent directory for
intermediate results, as mentioned in the first example of this chapter.

In case you need it, the $EXESUF variable <span class="application">Aap</span> is empty
on Unix and ".exe" on MS-Windows.
</p><p>
The relation between the two dependencies in the example is that the
source of the first one is the target in the second one.  The logic is that
<span class="application">Aap</span> follows the dependencies and executes the associated build commands. In
this case "hello$EXESUF" depends on "$BDIR/hello$OBJSUF", which then depends on
"hello.c".  The last dependency is handled first, thus first hello.c is
compiled by the build command of the second dependency, and then linked into
"hello$EXESUF" by the build command of the first dependency.
</p><p>
Now change the "hello.h" file by replacing "World" with 'Universe":
</p><pre class="programlisting">
    #define world "Universe!"
</pre><p>
If you now run <span class="application">Aap</span> with "aap hello" or "aap hello.exe" the "hello" program
will be built.  But you never mentioned the "hello.h" file in the recipe.  How
did <span class="application">Aap</span> find out the change in this file matters?
When <span class="application">Aap</span> is run to update the "hello" program, this is what will happen:
</p><div class="orderedlist"><ol type="1"><li><p>
    The first dependency with "hello$EXESUF" as the target is found,
    it depends on "$BDIR/hello$OBJSUF".
    </p></li><li><p>
    The second dependency with "$BDIR/hello$OBJSUF" as the target is found.  The
    source file "hello.c" is recognized as a C program file.  It is inspected
    for included files.  This finds the "hello.h" file.  "stdio.h" is ignored,
    since it is a system file.  "hello.h" is added to the list of files that
    the target depends on.
    </p></li><li><p>
    Each file that the target depends on is updated.  In this case "hello.c"
    and "hello.h".  No dependency has been specified for them and the files
    exist, thus nothing happens.
    </p></li><li><p>
    <span class="application">Aap</span> computes signatures for "hello.c" and "hello.h".  It also computes a
    signature for the build commands.  If one of them changed since the last
    time the target was built, or the target was never built before, the
    target is considered "outdated" and the build commands are executed.
    </p></li><li><p>
    The second dependency is now finished, "$BDIR/hello$OBJSUF" is up-to-date.
    <span class="application">Aap</span> goes back to the first dependency.
    </p></li><li><p>
    <span class="application">Aap</span> computes a signature for "$BDIR/hello$OBJSUF".  Note that this happens
    after the second dependency was handled, it may have changed the file.
    It also computes a signature for the build command.
    If one of them changed since the last time the target was built, or the
    target was never built before, the target is considered "outdated" and the
    build commands are executed.
    </p></li></ol></div><p>
</p><p>
Now try this: Append a comment to one of the lines in the "hello.c" file.
This means the file is changed, thus when invoking <span class="application">Aap</span> it will compile
"hello.c".  But the program is not built, because the produced intermediate
file "$BDIR/hello$OBJSUF" is still equal to what it was the last time.  When
compiling a large program with many dependencies this mechanism avoids that
adding a comment may cause a snowball effect. (Note: some compilers include
line numbers or a timestamp in the object file, in that case building the
program will happen anyway).
</p><h2><a name="id2624229"></a>Compiling Multiple Programs</h2><p>
Suppose you have a number of sources files that are used to build two
programs.  You need to specify which files are used for which program.  Here
is an example:
</p><pre class="programlisting">
1.    Common = help.c util.c
2.
3.    all : foo bar
4.
5.    :program foo : $Common foo.c
6.
7.    :program bar : $Common bar.c
</pre><p>
This recipe defines three targets: "all", "foo" and "bar".
"foo" and "bar are programs that <span class="application">Aap</span> can build from source files.
But the "all" target is not a file.  This is called a virtual target: A name
used for a target that does not exist as a file.  Let's list the terminology
of the items in a dependency:
</p><div class="table"><a name="id2624454"></a><p class="title"><b>Table 2.1. items in a dependency</b></p><div class="table-contents"><table summary="items in a dependency" border="0"><colgroup><col width="150"><col></colgroup><tbody><tr><td>source</td><td>item on the right hand side of a dependency</td></tr><tr><td>source file</td><td>source that is a file</td></tr><tr><td>virtual source</td><td>source that is NOT a file</td></tr><tr><td>target</td><td>on the left hand side of a dependency</td></tr><tr><td>target file</td><td>target that is a file</td></tr><tr><td>virtual target</td><td>target that is NOT a file</td></tr><tr><td>node</td><td>source or target</td></tr><tr><td>file node</td><td>source or target that is a file</td></tr><tr><td>virtual node</td><td>source or target that is NOT a file</td></tr></tbody></table></div></div><br class="table-break"><p>
<span class="application">Aap</span> knows the target with the name "all" is always used as a virtual
target.  There are a few other names which <span class="application">Aap</span> knows are virtual, see
<a href="ref-attributes.html#virtual-targets" title="Table 37.1. Virtual Targets">Table 37.1, &#8220;Virtual Targets&#8221;</a>.  For other
targets you need to specify it with the "{virtual}" attribute.
</p><p>
The first dependency has no build commands.  This only specifies that "all"
depends on "foo" and "bar".  Thus when <span class="application">Aap</span> updates the "all" target, this
dependency specifies that "foo" and "bar" need to be updated.  Since the "all"
target is the default target, this dependency causes both "foo" and "bar" to
be updated when <span class="application">Aap</span> is started without an argument.  You can use "aap foo"
to build "foo" only.  The dependencies for "all" and "bar" will not be used
then.
</p><p>
The two files <code class="filename">help.c</code> and <code class="filename">util.c</code> are used by both the "foo" and the "bar"
program.  To avoid having to type the file names twice, the "Common" variable
is used.  
</p><h2><a name="id2624679"></a>Kinds of things you can build</h2><p>
Not everything you want to build is a program.
Your recipe might need too build a library
or a libtool archive.
In these cases,
<a href="ref-commands.html#cmd-lib">:lib</a>,
<a href="ref-commands.html#cmd-dll">:dll</a> or
<a href="ref-commands.html#cmd-ltlib">:ltlib</a>
provide the same level of automation
as <a href="ref-commands.html#cmd-program">:program</a>
does for programs.  The <a href="ref-commands.html#cmd-produce">:produce</a> command is
more generic, you can use this to build various kinds of things.
</p><p>
If all else fails, you can use <span class="application">Aap</span> like the <span class="application">make</span>
program
and explicitly list the commands you need to build your project.
</p></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="tutor-start.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="tutorial.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="tutor-website.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 1. Getting Started </td><td width="20%" align="center"><a accesskey="h" href="index.html">
		    Contents</a></td><td width="40%" align="right" valign="top"> Chapter 3. Publishing a Web Site</td></tr></table></div></body></html>