Automake and Qmerge

Minimal Re-Compilation for Fortran and C

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. Invoke AUTOMAKE, typically by typing “AM”, and it updates your executable by compiling the minimum possible set of source files, and re-linking. In doing this, it takes account not only of changes or additions to source files, but also changes to INCLUDEd files and Fortran 95 modules. For example, if you change a file which is included in half a dozen source files, AUTOMAKE ensures that these files are re-compiled, even though they were not themselves changed.


No make-file – just type “AM”.

AUTOMAKE can be regarded as a fully automatic alternative to the Linux style MAKE utility. Unlike MAKE, AUTOMAKE builds and maintains the dependency database (or “make-file”) itself. This removes a major source of error: users of a conventional MAKE may omit a dependency or specify it wrongly. If that happens, MAKE may appear to update a program correctly, while in fact building a corrupt hybrid of new and old code. The consequences may not be immediately apparent, and can be extremely hard to trace. This is precisely the sort of problem that MAKE is supposed to avoid.

AUTOMAKE users do not have that problem because dependency data is maintained automatically by AUTOMAKE. AUTOMAKE checks for new or deleted source files, and scans source code as necessary to update INCLUDE file dependencies.


To put it another way, AUTOMAKE handles the one dependency that conventional MAKE utilities choke on – that of the make-file on the source code.


Usually, the only data required from the user are the executable file name, and the compile and link commands; these are specified in a simple configuration file. Complex systems, perhaps involving different compilers, and source code spread across many directories can also be handled with minimal customisation effort.

AUTOMAKE is compatible with all common Fortran compilers, including those from Intel, GNU, PGI, Absoft, Oracle, Silverfrost and Lahey, and with C++ compilers from Intel and Microsoft, as well as common compilers on Linux and Mac.

 

QMERGE – Version Selection

QMERGE is a small tool which tackles a common problem – how to keep control of programs which exist in a number of different versions. Some common examples are programs which run on a variety of different machines, and require slight changes to the source code for each one. For example, changes may be necessary because of different file naming conventions, word length, or different ways of accessing the system.

QMERGE allows the user to keep all the code variants within the master version of the source code. It comments and un-comments sections of code depending on the settings of user-defined logical flags. Unlike a macro pre-processor or conditional compilation tool, QMERGE does not require that you deviate in any way from standard Fortran, or that you pre-process code before submitting it to a compiler – the master version is legal Fortran and can be compiled directly. QMERGE is needed only when you create a version for porting to a different machine.

The operation of QMERGE can be understood by reference to a simple example, such as that shown belowe. This program fragment consists of one section which is activated if the the user defined condition named LINUX is TRUE, and another which is activated if LINUX is FALSE, and at least one of the conditions MAC, VMS and WINDOWS is TRUE (the commas between them may be read as ‘OR’). Inside the LINUX section is a nested !-IF construct containing sections which may be activated depending on the values of the DEMO and DEBUG conditions. The condition names are not case sensitive, and may be
up to 32 characters long. They are defined simply by using them.

Version 1 of the program fragment is consistent with the condition LINUX being FALSE, and one of MAC, VMS or WINDOWS being TRUE. The values of DEMO and DEBUG are irrelevant in this case. Version 2 could be obtained by passing version 1 through QMERGE and specifying LINUX as TRUE, DEMO as FALSE, and DEBUG as TRUE (the ‘-‘ in front of DEBUG may be read as ‘NOT’). In fact, the result does not depend on which lines are commented out in version 1, but only on values of the conditions. It is quite possible to convert version 2 back to version 1 (by running QMERGE with LINUX set to FALSE and MAC set to TRUE).

 

Version 1

Version 2

!-IF LINUX
!-      PRINT *,'LINUX'
!-IF DEMO
!-      PRINT *
!-      PRINT *,'Demo'
!-ELSEIF -DEBUG
!-      PRINT *
!-      PRINT *,'Debug off'
!-ELSE
!-      PRINT *
!-      PRINT *,'Debug on'
!-ENDIF
!-      X = Y
!-      A = B
!-ELSEIF MAC,VMS,WINDOWS
      PRINT *,'Default'
!-ENDIF
!-IF LINUX
      PRINT *,'LINUX'
!-IF DEMO
!-      PRINT *
!-      PRINT *,'Demo'
!-ELSEIF -DEBUG
!-      PRINT *
!-      PRINT *,'Debug off'
!-ELSE
      PRINT *
      PRINT *,'Debug on'
!-ENDIF
      X = Y
      A = B
!-ELSEIF MAC,VMS,WINDOWS
!-      PRINT *,'Default'
!-ENDIF


 

Conditions may be specified in a configuration file, or specified on the command line:

e.g. QMERGE *.f90 SELECT=+LINUX,-DEMO

means that LINUX is true and DEMO is false. If QMERGE needs to know the value of a condition which is not specified, it issues a prompt

Is MAC true? (Y or N) ==>

Other QMERGE facilities allow you to specify defaults, select from a list of alternatives, concatenate and nest conditions etc.