Compiling and Running Fortran Programs - a basic guide


  1. Introduction
  2. File name convention
  3. Compiling a program
  4. Compiler Options
  5. Compiling subprogram source files
  6. Creating and linking object and library files
  7. KIND types for REALs and INTEGERs
  8. Running programs under Linux

1. Introduction
This guide is for Fortran programmers using central Linux servers such as gul3, gul4 and gul5, where the g95 compiler is installed. This guide covers at a basic level topics relating to the compilation of program sources; it is not a guide to the Fortran programming language (I have however included a section on KIND types is given at the end of this guide.

2. File name Convention
File names ending in .f90 and .f95 are assumed to be free source form - suitable for Fortran 90/95 compilation.
File names ending in .f and .for are assumed to be assumed fixed form source - compatible with old Fortran 77 compilation.

3. Compiling a program
The role of g95 Fortran compiler is to compile your Fortran source code into an executable program. Consider that you have a Fortran 95 source file called myprog.f90. The simplest command for creation of an executable is then:

  g95 myprog.f90

This creates the executable program called a.out

You can give a more meaningful name to your executable by using the -o option:

  g95 myprog.f90 -o myprog

This creates the executable program called myprog

The path of include files can be given with the -I option, for example:

  g95 myprog.f90 -o myprog -I/home/fred/fortran/inc
  g95 myprog.f90 -o myprog -I$MYINC

where the environment variable MYINC is set with:


4. Compiler Options
As for any Fortran compiler, g95 provides many options that control its behaviour. The basic and recommended options are given here, a more detailed description can be found at

Speed optimisation
The -Olevel option performs some optimisation of the executable and can lead to significant increases in executation speed. Example:

  g95 myprog.f90 -o myprog -O2

Warning options
The -Wlevel option enables most warning messages that can be switched on by the programmer. Such messages are generated at compile-time warning the programmer of, for example, unused or unset variables. Example:

  g95 myprog.f90 -o myprog -O2 -Wall

It is advisable to use -Olevel option as some warning options rely on flow analysis provided by this option.

Runtime options
Various run-time options can be selected, these options cause extra code to be added to the executable and so can cause significant decreases in execution speed. However these options can be very useful during program development and debugging. Example

  g95 myprog.f90 -o myprog -O2 -fbounds-check

This causes the executable to check for "array index out of bounds conditions".

Recommended options
For teaching students Fortran programming, and during program development in the research environment, I advise something like the following options as they help the programmer to program with safety in mind.

  g95 myprog.f90 -o myprog -Wuninitialized -Wimplicit-none -Wunused-vars -Wunset-vars -fbounds-check -ftrace=full -O2

If speed of executation is important then the following options will improve speed:

  g95 myprog.f90 -o myprog -Wuninitialized -Wimplicit-none -Wunused-vars -Wunset-vars -O2

On central interactive Linux servers in the university, the fortran command (or simply f) provides these options by default, example:

  fortran myprog.f90

is equivalent to

  g95 myprog.f90 -o myprog -Wuninitialized -Wimplicit-none -Wunused-vars -Wunset-vars -fbounds-check -ftrace=full -O2

Type fortran with no arguments to find the up-to-date list of default arguments.

5. Compiling subprogram source files
It is sometimes useful to place sub-programs into separate source files especially if the sub-programs are large or shared with other programmers. If a Fortran 90/95 project contains more than one program source file, then to compile all source files to an executable program you can use the following command:

  g95 main.f90 sub1.f90 sub2.f90 sub3.f90 -o myprog

In this example main.f90 is the main program source and sub1.f90, sub2.f90, sub3.f90 are files contain subprogram sources.

A working example:
Consider the following main program source main.f90 and three sub-program sources sub1.f90, sub2.f90, sub3.f90.

The sources are:

  real :: a
  call sub1(a)
  call sub2(a)
  call sub3(a)

  sub1.f90                 sub2.f90                 sub3.f90
  ------------------       ------------------       ------------------
  subroutine sub1(x)       subroutine sub2(x)       subroutine sub3(x)
  real :: x                real :: x                real :: x
  print *, x               print *, x**2            print *, x**3
  end                      end                      end
The four sources can be compiled together with the command:

  g95 main.f90 sub1.f90 sub2.f90 sub3.f90 -o myprog

The program is run by simply typing its name:

Note that in this example the subroutines are external (as in Fortran 77).
In Fortran 90/95 subroutines can also be written in a module.
In this case the program sources are:
  main2.f90                      mod.f90
  ------------------             --------------------------
  USE mod                        MODULE mod
  real :: a
  a=2.0                           CONTAINS
  call sub1(a)
  call sub2(a)                     subroutine sub1(x)
  call sub3(a)                     real :: x
  end                              print *, x
                                   end subroutine sub1

                                   subroutine sub2(x)
                                   real :: x
                                   print *, x**2
                                   end subroutine sub2 

                                   subroutine sub3(x)
                                   real :: x
                                   print *, x**3
                                   end subroutine sub3

                                 END MODULE mod
The two sources can be compiled together with the command:

  g95 mod.f90 main2.f90 -o myprog

Note that in this command the module appears before the main program so that the functions are defined before they are referenced in the main program.

6. Creating and linking object and library files
When working on large projects, especially projects that are shared between a number of programmers/users, it is useful to create object files or libraries of object files that can be shared between programmers and users. In part 5 the compilation of multiple source files is described. For example:

  g95 main.f90 sub1.f90 sub2.f90 sub3.f90 -o myprog

If a subprogram is complete it is not necessary to recompile it again and again during the development of other parts of the project. Completed subprograms can be compiled into object files that can be linked during the compilation of the whole program, for example:

  g95 main.f90 sub1.o sub2.o sub3.o -o myprog

Here, sub1.o sub2.o sub3.o are object files created with:

  g95 -c  sub1.f90
  g95 -c  sub2.f90
  g95 -c  sub3.f90

Note that the -c option is lowercase ("compile to object (.o) only, do not link").

If many object files are to be linked then it is convenient to place them in a library. Libraries can be created using the ar command (see man ar ). Object files can be placed in a library for example as follows:

  ar rcvf libsubs.a sub1.o sub2.o sub3.o

The library created is called libsubs.a , it contains the three objects sub1.o sub2.o sub3.o.
Note that the name of the library must begin with lib and end with .a.

More objects can be added to the library with:

  ar rcvf libsubs.a another.o

The contents of a library can be listed with:

  ar tv libsubs.a

Subroutines and functions in the library can be listed with:

  nm libsubs.a

Objects can be deleted from the library with:

  ar dv libsubs.a sub.o

Once a library has been created, it can be linked in a compilation as follows:

  g95 main.f90 -o myprog -L. -lsubs

The -L. options tells the linker that the library can be found in the current directory.
If the library is not in the current directory then you should give the path, for example:

  g95 main.f90 -o myprog -L/home/fred/fortran/lib/ -lsubs
  g95 main.f90 -o myprog -L$MYLIB -lsubs

where the environment variable MYLIB is set with:


7. KIND types for REALs and INTEGERs
Real type data can be declared as single-, double-, or quad-precision. The default is single-precision (KIND=4) where each data is stored in 4 bytes of memory. Double precision data are allocated 8 bytes and quad precision in 16 bytes. Double precision has about twice the precision as single precision and a much larger range in the exponent, Quad precision has more than four times the precision and a very large range in the exponent.

Similarly, integer type data can be stored in 1, 2, 4 or 8 bytes, each giving a larger range of values that can be represented by them. The default is 4 bytes (KIND=4).

KIND types available in the g95 compiler (at the time of writing quad precisison is not yet available).

 | Kind             | Memory   | Precision        | Smallest value, TINY()   | Largest value, HUGE()    |
 | REAL (KIND=4 )*  |  4 bytes |  7 s.f. (Single) | 1.1754944E-38            | 3.4028235E+38            |
 | REAL (KIND=8 )   |  8 bytes | 15 s.f. (Double) | 2.2250738585072014E-308  | 1.7976931348623157E+308  |
 | REAL (KIND=16)   | 16 bytes | 34 s.f. (Quad)   |                          |                          |

 | Kind             | Memory   | Range                      |
 | INTEGER (KIND=1) | 1 byte   |        -128 to 127         |
 | INTEGER (KIND=2) | 2 bytes  |      -32768 to 32767       |
 | INTEGER (KIND=4)*| 4 bytes  | -2147483648 to 2147483647  |    * means default kind.
 | INTEGER (KIND=8) | 8 bytes  |     about +- 9.2x10^18     |    s.f. means "significant figures".
To assign double and quad precision correctly use the _8 and _16 notations:

 In single precision:       A = 1.2345678E38  or  1.2345678E38_4
 In double precision:       A = 1.234567890123456E308_8
 In   quad precision:       A = 1.2345678901234567890123456789012345E4931_16
To specify the kind type, the KIND attribute is given in the declaration of data.
Examples declarations of real types:
  REAL          :: A  ! default (single precision)
  REAL(KIND=4)  :: B  ! single precision
  REAL(KIND=8)  :: C  ! double precision
  REAL(KIND=16) :: D  ! quad precision
In assignments, constants can be given the required precision as follows:
 A=1.2345678_4   or simply  1.2345678           (Single)
 A=1.234567890123456_8                          (Double)
 A=1.2345678901234567890123456789012345_16      (Quad)
The E symbol can be used for exponentiation:
  A = 1.234568E38
  B = 1.234568E38_4
  C = 1.23456789012346E308_8
  D = 1.234567890123456789012345678901235E4931_16 

Double and quad precision greatly reduces round-off errors in many numerical methods.

Example declarations of integer types:

  INTEGER            :: E ! default (KIND=4)
  INTEGER  (KIND=1)  :: F
  INTEGER  (KIND=2)  :: G
  INTEGER  (KIND=4)  :: H
  INTEGER  (KIND=8)  :: I

8. Running programs under Linux
There are two modes of running programs under Linux, the first is interactively, and the second in background. Running interactively means you execute the program and your command prompts waits for it to complete:

 $ mybigjob
the command prompt will not return until the job is complete:

Alternatively, the job can be run in background; in this case the command prompt is returned to you and the job continues to run. You may log off the system, and the job will continue to run. This is a great convenience especially for long-running programs.

A program is placed into background by appending the & symbol at the end of the execution command; for example:

 $ mybigjob &
It usual to require screen output to be redirected to a file; this is acheived using output redirection:
 $ mybigjob >mybigjob.log &
In this method error messages are not included in the output file; there are two methods to record also error messages in a file:
 $ mybigjob 1>mybigjob.output 2>mybigjob.error &
 $ mybigjob 1>mybigjob.log 2>&1 &
In the first method the two outputs go to separate files, in the second method the two outputs go to the same file.

With an interactive login, the progress of a job can be viewed with the top command. Jobs can be listed with the jobs command and terminated with the kill command. System resources can be viewed with the df and free commands.
small update 04/11/2008