Chapter 29. Customizing Automatic Depedencies

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.

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

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.

To avoid all automatic dependency checks, set the variable "AUTODEPEND" to "off":

        AUTODEPEND = off

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

        foo.o : foo.c {autodepend = off}

Custom Dependency Checking

You can add your own dependency checks. This is done with an :action 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:

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

The build commands are expected to generate a file that specifies the dependency:

        foo.o : foo.c foo.h

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":

        foo.xyz : foo.c foo.h
        foo.o : foo.h

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

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.

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

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:

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

Missing Include Files

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.

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.

To make it easier to handle this situation, Aap provides the :sysdepend 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.

Here is an example for the imaginary 'f' language:

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

The "filepat" option of :sysdepend 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.

See the :sysdepend command for more details and an option to specify the search path.