Chapter 8. Filetypes and Actions

A-A-P can recognize what the type of a file is, either by looking at the file name or by inspecting the contents of the file. The filetype can then be used to decide how to perform an action with the file.

A New Type of File

Suppose you are using the "foo" programming language and want to use A-A-P to compile your programs. Once this is has been setup you can compile "" into the "hello" program with a simple recipe:

    :program hello :

You need to explain Aap how to deal with "foo" files. This is done with a recipe:

        suffix foo foo

    :action compile foo
        :sys foocomp $?FOOFLAGS $source -o $target

    :route  foo object

For Unix, write this recipe as "/usr/local/share/aap/startup/foo.aap" or "~/.aap/startup/foo.aap". The recipes in these "startup" directories are always read when Aap starts up.

Now try it out, using the simple recipe at the top as "main.aap":

    % aap
    Aap: foocomp -o build-FreeBSD4_5_RELEASE/hello.o
    Aap: cc -L/usr/local/lib -g -O2 -o hello build-FreeBSD4_5_RELEASE/hello.o

The "foo.aap" recipe does three things:

  1. The :filetype command is used to tell A-A-P to recognize your "" file as being a "foo" file.

  2. The :action command is used to specify how the "foocomp" compiler is used to compile a "foo" program into an object file. The user can set the FOOFLAGS variable to options he wants to use. The convention is that the option variable is in uppercase, starts with the filetype and ends in "FLAGS".

  3. The :route command is used to specify which actions are to be used to turn a "foo" file into an "object" file.

Defining a Filetype by Suffix

The :filetype command is followed by the line "suffix foo foo". The first word "suffix" means that recognizing is done by the suffix of the file name (the suffix is what comes after the last dot in the name). The second word is the suffix and the third word is the type. Quite often the type is equal to the suffix, but not always. Here are a few more examples of lines used with :filetype:

        suffix fooh foo
        suffix bash sh

It is also possible to recognize a file by matching the name with a pattern, checking the contents of the file or using a Python script. See the user manual.

Defining a Compile Action

The lower half of "foo.aap" specifies the compile action for the "foo" filetype:

    :action compile foo
        :sys foocomp $source -o $target

The :action command has two arguments. The first one specifies the kind of action that is being defined. In this case "compile". This action is used to make an object file from a source file. The second argument specifies the type of source file this action is used for, in this case "foo".

Below the :action line the build commands are specified. In this case just one, there could be more. The :sys command invokes an exteral program, "foocomp", and passes the arguments. In an action $source is expanded to the source of the action and $target to the target. These are obtained from the :do command that invokes the action. Example:

    :do compile {target = `src2obj("")`}

This :do command invokes the compile action, specified with its first argument. The target is specified as an attribute to the action, the source is the following argument "". When executing the :do command the filetype of "" is detected to be "foo", resulting in the compile action for "foo" to be invoked. In the build command of the action $source and $target are replaced, resulting in:

    :sys foocomp -o `src2obj("")`

Note that in many cases $target is passed implicitly from a dependency and does not appear in the :do command argument.

Another Use of Filetypes

When building a program you often want to include the date and time when it was built. A simple way of doing this is creating a source file "version.c" that contains the timestamp. This file needs to be compiled every time your program is built. Here is an example how this can be done:

1   :program prog : main.c work.c
3   :attr prog {filetype = myprog}
5   :action build myprog object
6        version_obj = `src2obj("version.c")`
7        :do compile {target = $version_obj} version.c
8        :do build {filetype = program} $source $version_obj

The target "prog" is explicitly given a different filetype in line 3. The default filetype for a program is "program", here it is set to "myprog". This allows us to specify a different build action for "prog".

Write the recipe as "main.aap" (without the line numbers) and execute it with aap. The first time all the files will be compiled and linked together. Executing aap again will do nothing. Thus the timestamp used in "version.c" will not be updated if the files were not changed. If you now make a change in "main.c" and run aap you will see that both "main.c" and "version.c" are compiled.

The :action command in line 5 has three arguments. The first one "build" is the kind of action, like before. The second argument "myprog" specifies the target filetype, the third one "object" the source filetype. Thus the template is:

    :action  kind-of-action  target-filetype  source-filetype

This order may seem a bit strange. Remember that putting the target left of the source also happens in a dependency and an assignment.

There are three commands for the build action, lines 6 to 8. The first one assigns the name of the object file for "version.c" to version_obj. "version.c" was not included in the :program command at the top, it is compiled here explicitly in line 7. This is what makes sure "version.c" is compiled each time "prog" is built. The other source files will be compiled with the default rules for :command.

Finally the :do build command in line 8 invokes the build action to link all the object files together. Note that the filetype for the build action is explicitly defined to "program". This is required for this :do command to use the default action for a program target. Otherwise the action would invoke itself, since the filetype for $target is "myprog".

For more information about customizing filetype detection and actions see Chapter 28, Customizing Filetype Detection and Actions.