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

  Part of the A-A-P recipe executive: Customiszing Automatic Dependencies

  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>
For various file types A-A-P can scan a source file for header files it
includes.  This implies that when a target depends on the source file, it also
depends on the header files it includes.  For example, a C language source
file uses #include lines to include code from header files.  The object file
generated from this C source needs to be rebuilt when one of the header files
changes.  Thus the inclusing of the header file has an implied dependency.
</para>

<para>
Aap defines a series of standard dependency checks.  You don't need to do
anything to use them.
</para>

<para>
The filetype used for the dependency check is detected automatically.  For
files with an ignored suffix like ".in" and ".gz" no dependency checking is
done.
</para>

<para>
To avoid all automatic dependency checks, set the variable "AUTODEPEND" to
"off":
</para>

<programlisting>
        AUTODEPEND = off
</programlisting>

<para>
To avoid automatic dependencies for a specific file, set the attribute
"autodepend" to "off":
</para>

<programlisting>
        foo.o : foo.c {autodepend = off}
</programlisting>


<bridgehead>Custom Dependency Checking</bridgehead>

<para>
  You can add your own dependency checks.  This is done with an
  <link linkend="cmd-action">:action</link>
command.  Its arguments are "depend" and the file types for which the check
works.  A block of commands follows, which is expected to inspect $source and
produce the detected dependencies in $target, which has the form of a
dependency.  Simplified example:
</para>

<programlisting>
        :action depend c,cpp
            :sys $CC $CFLAGS -MM $source > $target
</programlisting>

<para>
The build commands are expected to generate a file that specifies the
dependency:
</para>

<programlisting>
        foo.o : foo.c foo.h
</programlisting>

<para>
The first item (before the colon) is ignored.  The items after the colon are
used as implied dependencies.  The source file itself may appear, this is
ignored.  Thus these two results have the same meaning: a dependency on
"foo.h":
</para>

<programlisting>
        foo.xyz : foo.c foo.h
        foo.o : foo.h
</programlisting>

<para>
Comments starting with "#" are ignored.  Line continuation with "\" is
supported.  Only the first (continued) line is read.
</para>

<para>
Aap will take care of executing the dependency check when the source changes
or when the command changes (e.g., the value of $CC and $CFLAGS).  This can be
changed with a "buildcheck" attribute after "depend".  In the following
example only a change in $CFLAGS is noticed.  A change in $CC or the ":sys"
command does not cause generating the target.
</para>

<programlisting>
        :action depend {buildcheck = $CFLAGS} c
            :sys $CC $CFLAGS -MM $source > $target
</programlisting>

<para>
Aap expects the dependency checker to only inspect the source file.  If it
recursively inspects the files the source files include, this must be
indicated with a "recursive" attribute.  That avoids Aap will take care of
this and do much more work than is required.  Example:
</para>

<programlisting>
        :action depend {recursive}  c,cpp
            :sys $CC $CFLAGS -MM $source > $target
</programlisting>


<bridgehead>Missing Include Files</bridgehead>

<para>
It is possible that an include file is not typed in by the user, but is
generated with commands.  This file may then need to be generated to be able
to figure out the dependencies.
</para>

<para>
This can be complicated, because the generated include file may again include
other files.  Thus the dependency check needs to be repeated after the file
has been generated.
</para>

<para>
To make it easier to handle this situation, &Aap; provides the
<link linkend="cmd-sysdepend">:sysdepend</link> command.  It will take care of
executing a shell command to figure out the dependencies, catching the output
to check for error messages, build targets that can't be found and repeat
until it is done.
</para>

<para>
Here is an example for the imaginary 'f' language:
</para>

<programlisting>
        :action depend {recursive} f
	    :sysdepend {filepat = .*File "([^:]*)" Not found}
                       $FCC $FFLAGS --depend $source > $target
</programlisting>

<para>
The "filepat" option of 
<link linkend="cmd-sysdepend">:sysdepend</link>
specifies how the file name of a missing file can be located.  This is a
Python regular expression, where the file name matches in the first group in
parenthesis.
</para>

<para>
See the
<link linkend="cmd-sysdepend">:sysdepend</link> command for more details and
an option to specify the search path.
</para>
