7 AUTOMAKE - Automated Compile & Link for Fortran and C

7.1 Introduction

7.1.1 What does it do?

AUTOMAKE is a simple-to-use tool for re-building object and executable code after you have made changes to the Fortran and/or C source code. It examines the creation times of all the source, object and module files, and recompiles wherever it finds that an object or module file is non-existent, empty or out of date. In doing this, it takes account not only of changes or additions to the source code files, but also changes or additions to MODULEs and INCLUDEd files - even when nested. For example, if you change a file which is INCLUDEd in half a dozen source files, AUTOMAKE ensures that these files are re-compiled. In the case of Fortran 95, AUTOMAKE ensures that modules are recompiled from the bottom up, taking full account of module dependencies.

7.1.2 How does it do that?

AUTOMAKE stores details of the dependencies in your program (e.g. file A INCLUDEs file B) in a dependency file, usually called automake.dep. AUTOMAKE uses this data to deduce which files need to be compiled when you make a change. Unlike conventional MAKE utilities, which require the user to specify dependencies explicitly, AUTOMAKE creates and maintains this data itself. To do this, AUTOMAKE periodically scans source files to look for INCLUDE and USE statements. This is a very fast process, which adds very little to the overall time taken to complete the update.

7.1.3 How do I set it up?

The operation of AUTOMAKE is controlled by a configuration file which contains the default compiler name and options, INCLUDE file search rule etc. For simple situations, where the source code to be compiled is in a single directory, and builds into a single executable, it will probably be possible to use the system default configuration file. In that case there is no need for any customization of AUTOMAKE - just type am to update both your program and the dependency file.

In other cases, you may wish to change the default compiler name or options, add a special link command, or change the INCLUDE file search rule; this can be achieved by customizing a local copy of the AUTOMAKE configuration file. More complex systems, perhaps involving source code spread across several directories, can also be handled in this way.

7.1.4 What can go wrong?

Not much. AUTOMAKE is very forgiving. For example, you can mix manual and AUTOMAKE controlled updates without any ill effects. You can even delete the dependency file without causing more than a pause while AUTOMAKE regenerates the dependency data. In fact, this is the recommended procedure if you do manage to get into a knot.

7.2 Running AUTOMAKE

To run AUTOMAKE, simply type am. If there is a configuration file (automake.fig) in the current directory, AUTOMAKE reads it. Otherwise the search rules defined in section 1.4 are followed.

The default configuration assumes that the target program is called target.exe, and is to be built using Intel's ifort compiler. Files in the current directory with the .F90 extension are assumed to contain the source code. Object and module files are also assumed to be in the current directory.

7.3 The AUTOMAKE Configuration File

The AUTOMAKE configuration file is used to specify the compile and link procedures, and other details required by AUTOMAKE. It consists of a series of records of the form

keyword = value

or

keyword

where keyword is an alphanumeric keyword name, and value is the string of characters assigned to the keyword. The keyword name may be preceded by spaces if required. Any record with a #, ! or * as the first non-blank character is treated as a comment.

Lines in the configuration file can be by continued placing the character "^" at the end of all except the last line.

      link=slink %ob ^
           -file:%ex ^
           -stack:0x600000

The keywords which may be inserted in the configuration file are:

FILES=

specifies the names of files which are candidates for re-compilation. The value field should contain a single filename optionally including wild-cards.

      FILES=*.f90

You can also have multiple FILES= specifications, separated by AND keywords.

      FILES=F90\*.F90
      AND
      FILES=F77\*.FOR
      AND
      ...
COMPILE=

specifies the command to be used to compile a source file. The command may contain place markers, which are expanded as necessary before the command is executed.

      COMPILE=@ifort -c %fi

The string %fi in the above example is a place marker, which expands to the full name of the file to be compiled. Other place markers that can be used within the compile command are:

%SD

expands to the name of the directory containing the source file - including a trailing '\'.

%SF

expands to the source file name, excluding the directory and extension.

%SE

expands to the source file extension - including a leading '.'. For example if the file to be compiled is f:\source\main.for, %SD expands to f:\source\, %SF to main, and %SE to .for.

%OD

expands to the name of the directory containing object code, as specified using the OBJDIR= command (see below), including a trailing '\'.

%OE

expands to the object file extension, as specified using the OBJEXT= command (see below), including a leading '.'.

%ID

expands to the INCLUDE file search list, as specified using INCLUDE= (see below)

%MO

expands to the name of directory containing modules, as specified using MODULE= (see below)

%RF

expands to the name of a response file, created by AUTOMAKE, containing a list of source files. If %RF is present, the compiler is invoked only once.

%FI

is equivalent to %SD%SF%SE.

Examples:-

      COMPILE=@ifort -c %fi -module:%mo
      COMPILE=@nagfor -c @%rf -mdir %mo

It is possible to invoke the compiler using a command file (batch file, shell script etc.). However, on PCs, it is necessary to preface the batch file name with CALL or COMMAND/C.

      COMPILE=CALL fcomp %fi
TARGET=

specifies the name of the program or library file which is to be built from the object code. Note that you will also have to tell the linker the name of the target file. You can do this using a %EX place marker (which expands to the file name specified using TARGET=).

      TARGET=f:\execs\MYPROG.EXE

If there is no TARGET= keyword, AUTOMAKE will update the program object code, but will not attempt to re-link.

LINK=

specifies a command which may be used to update the program or library file once the object code is up to date:

      LINK=@ifort %ob -exe:%ex -module:%mo
      LINK=@lf95  %od*%oe -exe %ex -mod %mo
      LINK=@pgf90 @%rf -o %ex -module %mo

You could use a batch file called l.bat by specifying

      LINK=CALL L

The following place markers are allowed in the command specified using LINK=.

%OD

expands to the name of the directory containing object code, as specified using the OBJDIR= command (see below), including a trailing '\'.

%OE

expands to the object file extension, as specified using the OBJEXT= command (see below), including a leading '.'.

%OB

expands to a list of object files corresponding to source files specified using all FILES= commands.

%LI

expands to a list of all library files specified using LIBRARY= commands.

%EX

expands to the executable file name, as specified using TARGET=.

%MO

expands to the name of directory containing modules, as specified using MODULE= (see below)

%RF

expands to the name of a response file, created by AUTOMAKE, containing a list of object files.

%LL

expands to the name of a response file, created by AUTOMAKE, containing a list of library files (specified using LIBRARY=).

%VX

expands to the name of a command file, generated by AUTOMAKE, which will perform the required LINK on a VMS system.

INCLUDE=

may be used to specify the INCLUDE file search list. If no path is specified for an INCLUDEd file, AUTOMAKE looks first in the directory which contains the source file, and after that, in the directories specified using this keyword. The directory names must be separated by semicolons. For example, on a PC, we might have:

      INCLUDE=C:\include;C:\include\sys

Note that the compiler will also have to be told where to look for INCLUDEd files. You can do this using a %ID place marker (which expands to the list of directories specified using INCLUDE=).

SYSINCLUDE=

may be used to specify the search list for system INCLUDE files (i.e. any enclosed in angled brackets), as in

      #include <stat.h>

If no path is specified, AUTOMAKE looks in the directories specified using this keyword. It does not look in the current directory for system INCLUDE files unless explicitly instructed to. The directory names following SYSINCLUDE= must be separated by semicolons.

OBJDIR=

may be used to specify the name of the directory in which object files are stored.

      OBJDIR=OBJ\

The trailing '\' is optional. If OBJDIR= is not specified, AUTOMAKE assumes that source and object files are in the same directory. Note that if source and object files are not in the same directory, the compiler will also have to be told where to put object files. You can do this using a %OD place marker (which expands to the directory specified using OBJDIR=).

OBJEXT=

may be used to specify a non-standard object file extension. For example to specify that object files have the extension .abc, specify

      OBJEXT=abc

This option may be useful for dealing with unusual compilers, but more commonly to allow AUTOMAKE to deal with processes other than compilation (for example, you could use AUTOMAKE to ensure that all altered source files are run through a preprocessor prior to compilation).

LIBRARY=

may be used to specify the path name of a library which will be linked into the target file. AUTOMAKE checks the modification time of the library, and forces a re-link if it was created after the target file. Each library must be specified using a separate LIBRARY= keyword.

      LIBRARY=Q:\libs\math02.lib
      LIBRARY=Q:\libs\graphin.lib

Note that LIBRARY= tells AUTOMAKE about the dependency, but the linker must also be told. In general, the library names must be specified in the LINK= command. You can do this explictily, or avoid re-typing the names by using a %LI or %LL place marker (see LINK= above).

MODULE=

may be used to specify the name of the directory in which module files are stored.

      MODULE=MODS\

The trailing '\' is optional. If MODULE= is not specified, AUTOMAKE assumes that source and module files are in the same directory. Note that if source and module files are not in the same directory, the compiler will also have to be told where to put module files. You can do this using a %MO place marker (which expands to the directory specified using MODULE=).

DEP=

may be used to over-ride the default dependency file name.

      DEP=THISPROG.DEP

causes AUTOMAKE to store dependency data in thisprog.dep instead of automake.dep. This may be useful if there are several AUTOMAKE projects in a single directory.

LF95

Equivalent to specifying the default LF95 compile and link commands.

      COMPILE=@lf95 -c "%fi"
      LINK=@lf95 @%rf -exe %ex
LGF

Equivalent to specifying the default LGF compile and link commands.

      COMPILE=@lgf -c "%fi"
      LINK=@lgf @%rf -exe %ex
Intel

Equivalent to specifying the default Intel Fortran compile and link commands.

      COMPILE=@ifort -c "%fi"
      LINK=@ifort %ob -exe:%ex
ABSOFT

Equivalent to specifying the default Absoft Pro Fortran compile and link commands.

      COMPILE=@af90 -c "%fi"
      LINK=@af90 %ob -o %ex
PGI

Equivalent to specifying the default PGI compile and link commands.

      COMPILE=@pgf90 -c "%fi"
      LINK=@pgf90 %ob -o %ex
NAG

Equivalent to specifying the default NAG Fortran compile and link commands.

      COMPILE=@nagfor -c "%fi"
      LINK=@nagfor %ob -o %ex
GFORTRAN

Equivalent to specifying the default gfortran compile and link commands.

      COMPILE=@gfortran -c "%fi"
      LINK=@gfortran %ob -o %ex
FTN95

Equivalent to specifying the default Salford FTN95 compile and link commands.

      COMPILE=@FTN95 %fi /binary %od%sf%oe
      LINK='@slink %ob -file:%ex'
KEEPOBJDIR

Specifies that the value specified using the OBJDIR= keyword should retain its value until it is explicitly reset. By default the object directory is reset at the start of each compilation phase (i.e. after an AND) to the directory containing the source files. KEEPOBJDIR should be used if object files are in a single directory which is not the same as the source directory.

SCANONLY

Specifies that files in the current section (i.e. since the previous AND) may be scanned, but not compiled. This may cause files in other sections to be re-compiled. For example, a Fortran 95 module in the current section may be USEd by a file in another section, and the latter may be re-compiled when the module is changed.

COMPILEONLY

Specifies that files in the current section (i.e. since the previous AND) may be compiled if needed, but should not be included in the list of object files (generated using %RF in the LINK= command) to be linked. This may be useful if the files are part of a library.

QUITONERROR

Specifies that AUTOMAKE should halt immediately if there is a compilation error.

NOQUITONERROR

Specifies that AUTOMAKE should not halt if there is a compilation error.

MAKEMAKE

Specifies that AUTOMAKE should create a text file called automake.mak containing dependency information.

DEBUG

Causes AUTOMAKE to write debugging information to a file called automake.dbg.

LATESCAN

Delays scanning of source files until the last possible moment, and can, in some cases, remove the need for some scans. However this option is NOT compatible with Fortran 95 modules.

SALFORDOBJ

If this keyword is specified, AUTOMAKE checks for empty object files which are the result of a failed compilation using some older compilers. If it is not specified, AUTOMAKE may assume the object code is up-to-date, even if some compilations failed.

CHECK=

may be used to specify a command to be inserted after each compilation. A typical application would be to check for compilation errors. For example, under DOS/Windows:

      CHECK=IF ERRORLEVEL 2 GOTO QUIT

would cause the update procedure to abort if there is a compilation error.

$INSERT=

specifies that further directives should be read from the specified file. AUTOMAKE returns to read the remainder of the current file after the end of the inserted file.

      $INSERT=Q:\prog1\standard.fig

An inserted file may itself contain a $INSERT= keyword, but further nesting is not allowed.

7.4 Multi-Phase Compilation

Sometimes, more than one compilation phase is required. For example, if source files are stored in more than one directory, you will need a separate compilation phase for each directory. Multiple phases are also required if you have mixed C and Fortran source, or if you need special compilation options for particular source files.

The AND keyword may be inserted in your configuration file to add a new compilation phase. You can reset the values of FILES=, COMPILE=, INCLUDE=, OBJDIR=, OBJEXT= and MODULE= for each phase. All default to the value used in the previous phase, except that OBJDIR= defaults to the new source directory.

The following example shows how this feature might be used with the ifort compiler. The same principles apply to other compilers and other platforms.

Sample Configuration File for Multi-Phase Compilation

# Example Configuration file for Multi-Phase 
# Compilation

# Compilation 1 - files in current directory

INCLUDE=\include
FILES=*.f90
OBJDIR=obj
COMPILE=@ifort -c %fi -include:%id -object:%od%sf%oe -fast -traceback

AND

# Compilation 2 - files in utils\
# INCLUDE= defaults to previous value (\include)
# if OBJDIR= were not set, it would default
# to utils (NOT obj)

FILES=utils\*.f90
OBJDIR=utils\obj
COMPILE=ifort -c %fi -include:%id -object:%od%sf%oe -fast -traceback -noauto

# Relink

TARGET=current.exe
LINK=ifort %ob -exe:%ex

7.5 Notes