How to use mkmf with g95

mkmf is a tool written in perl5 that will construct a Makefile. It is available from <http://www.gfdl.noaa.gov/fms/pubrel/k/am2/bin/mkmf.html>. mkmf understands dependencies in f90 (modules and use), the fortran include statement, and the cpp #include statement in any type of source. Detailed information on using mkmf is provided at the link provided above.

Perl 5 must be installed in order to use mkmf. If using Windows, Perl is included in the msysDTK package. Download and install both "msys" and "msysDTK" from www.mingw.org. Include the mingw\bin and Msys\1.0\bin directories in your PATH.

1. Download the mkmf script and save it somewhere in your system (e.g. c:\mingw\bin).

2. mkmf currently only distinguishes .f, .F, .f90, and .F90 source filename extensions. If you wish to add support other Fortran extensions, change lines 59 to 82 in the mkmf perl script as follows, otherwise skip to step 3.

#some constants
my $endline = $/;
my @src_suffixes = ( q/\.F/, q/\.FOR/, q/\.F90/, q/\.F95/, q/\.F03/, q/\.c/, q/\.f/, q/\.for/,q/\.f90/, q/\.f95/, q/\.f03/ );
my @inc_suffixes = ( q/\.H/, q/\.fh/, q/\.h/, q/\.inc/ );
# push @inc_suffixes, @src_suffixes; # sourcefiles can be includefiles too: DISALLOW, 6 May 2004
my %compile_cmd = ( # command to create .o file from a given source file suffix
q/.F/ => q/$(FC) $(CPPDEFS) $(CPPFLAGS) $(FFLAGS) -c/,
q/.FOR/ => q/$(FC) $(CPPDEFS) $(CPPFLAGS) $(FFLAGS) -c/,
q/.F90/ => q/$(FC) $(CPPDEFS) $(CPPFLAGS) $(FFLAGS) -c/,
q/.F95/ => q/$(FC) $(CPPDEFS) $(CPPFLAGS) $(FFLAGS) -c/,
q/.F03/ => q/$(FC) $(CPPDEFS) $(CPPFLAGS) $(FFLAGS) -c/,
q/.c/ => q/$(CC) $(CPPDEFS) $(CPPFLAGS) $(CFLAGS) -c/,
q/.f/ => q/$(FC) $(FFLAGS) -c/,
q/.for/ => q/$(FC) $(FFLAGS) -c/,
q/.f90/ => q/$(FC) $(FFLAGS) -c/,
q/.f95/ => q/$(FC) $(FFLAGS) -c/,
q/.f03/ => q/$(FC) $(FFLAGS) -c/ );
my %delim_match = ( q/'/ => q/'/, # hash to find include file delimiter pair
q/"/ => q/"/,
q/</ => q/>/ );
#formatting command for MAKEFILE, keeps very long lines to 256 characters

3. Create a template file for your compiler to adapt to user environment.

Below is an example template file for g95:

FC = g95
LD = g95
FFLAGS = -I c:/mingw/include
LDFLAGS = $(LIBS)
# add your libraries after LIBS= , e.g. -lblas
LIBS = c:/mingw/lib

Give a name to the above template file (e.g. g95_args) and save it as c:\mingw\bin\g95_args

4. The syntax for using mkmf is:

mkmf [-a abspath] [-c cppdefs] [-d] [-f] [-m makefile] [-p program] [-t template] [-v] [-x] [args]
-a abspath attaches the abspath at the front of all relative paths to source files;
cppdefs is a list of cpp #defines to be passed to the source files: affected object files will be selectively removed if there has been a change in this state;
-d is a debug flag to mkmf (much more verbose than -v, but probably of use only if you are modifying mkmf itself);
-f is a formatting flag to restrict lines in the makefile to 256 characters. This allows editing makefiles using vi. Lines longer than that will use continuation lines as needed;
makefile is the name of the makefile written (default Makefile);
template is a file containing a list of make macros or commands written to the beginning of the makefile;
program is the name of the final target (default a.out, change to a.exe for Windows systems);
-v is a verbosity flag to mkmf;
-x executes the makefile immediately;
args are a list of directories and files to be searched for targets and dependencies.

5. Usage

5.1. To use mkmf with the g95 compiler to create a Makefile, go to the directory containing your source files and issue the following command:

Perl c:\mingw\bin\mkmf -t c:\mingw\bin\g95_args

5.2. To create a makefile and execute it immediately with an optional target name, do as follows:

mkmf -t c:\mingw\bin\g95_args -p myproj.exe -x

Here "myproj.exe" is the name of the final target (output)

6. To make using mkmf much easier, create a script file (e.g. mkmf-g95.bat on Windows) and put it in c:\mingw\bin. (Make sure you have this in your PATH.) The script file should contain the following (modify to fit your setup):

Echo off
REM This file can be called from anywhere to create a Makefile
REM based on the Fortran source files in that location.
REM a.exe is the name of final output. Change it to fit your needs.
REM If ignored, the mkmf script will use a.out by default.
REM g95_args is the name of a template file used to set user
REM environment variables. Change it as you wish.
REM
REM Perl c:\mingw\bin\mkmf -t c:\mingw\bin\g95_args -p a.exe
If (%1)==() (
Perl c:\mingw\bin\mkmf -t c:\mingw\bin\g95_args -p a.exe
) Else (
Perl c:\mingw\bin\mkmf -t c:\mingw\bin\g95_args -p %1
)
REM The above allows the target name to be passed as an argument

In the above code, if you pass a target name as an argument to mkmf-g95.bat, it will generate a Makefile with the target name as its output. Otherwise the script will produce a Makefile with a.exe as the output target.

7.  Change a.out to a.exe [Only on Windows machines]. The mkmf script creates Makefiles with a.out as the target, which is not suitable for Windows so it is necessary to modify the mkmf to produce "a.exe" as default output instead of "a.out". To do this, open the mkmf script file in a text editor and replace all a.out with a.exe.