Compiling process

Yutaka Masuda

February 2020

Back to index.html.

Compiling process

Separate compilation

Basics

When using multiple program units, including the main program, external procedures, and modules, all the units d not have to be in a single file. You can separate the file so that each unit resides in a separate file. In this case, you can compile each file separately, and then the object files are combined with being the executable by a linker. The figure shows the separate compilation with 2 files.

Separate compilation with 2 files

In this process, the user should prepare all object files by compiling each source file one by one. Then, the compiler calls a linker to unify the files to generate an executable.

Example

Here we use 2 separate files: mymod.f90 with a module and main.f90 with the main program. The code was introduced in the previous chapter. Note that the file name is not necessarily the same as the name of the module or program.

! mymod.f90
module mymod
   implicit none
   real,parameter :: pi=3.1415926
   real :: number_of_traits=0
contains
function mean(x) result(m)
   real,intent(in) :: x(:)
   real :: m
   m = sum(x)/size(x)
end function mean
end module mymod
! main.f90
program main
   use mymod
   implicit none
   real :: x(5)=[1,2,3,4,5]
   print *,sqrt(2*pi)
end program main

As mentioned before, a module should be compiled before the compilation of a program unit that uses the module. So, the module should be compiled first. Using GFortran, the sequence of commands looks like this.

gfortran -c mymod.f90
gfortran -c main.f90
gfortran mymod.o main.o

Library

When you have a collection of reusable procedures and modules, you will have to manage tons of files. If these programs are stable enough, the source files will not be modified so often. You may have only the object files to link the main program.

You can put the object files to a single file, library. A library is a collection of functions and subroutines. At the same time, a library means a file, including several object files. It is also referred to as an archive file. In Linux/Unix, the library file has a suffix, .a, in practice.

An archive file is created using a command, ar. The following command creates a library file, mylib.a, out of 3 object files, obj1.o, obj2.o, and obj3.o.

ar cr mylib.a obj1.o obj2.o obj3.o

This command follows an old, Unix-style option system, so there is no - to specify the option. The option cr is intended to create a library or to replace the object files in the library if needed, without showing any messages. Although the command has many other options, cr is the only option you have to know to create and to update your library.

An archive file can be used like object files. Here is an example of using such a file.

gfortran main.o mylib.a

Common compiler options

There are many Fortran compilers. Although each compiler has unique options, some options are common to major compilers in Linux and macOS. Here we look at some useful options that help to find bugs and issues in your program.

Name change of output file

The option -o specifies the name of the output file. By default, the object file is the same as the source file except for replacing .f90 with .o, and the executable is a.out. Using -o, you can put an arbitrary name on the output file. The example generates prog.x instead of a.out.

gfortran prog.f90 -o prog.x

Compilation only

Use -c to compile a source file to generate an object file.

gfortran -c prog.f90

You can combine it with -o.

gfortran -c prog.f90 -o myprogram.o

Module directory

When using a module, you have to have .mod file in the same directory as the source file (or its object file). If .mod files are stored in a separate directory, use -I to specify the location. This option does not need any spaces for the directory name (see below).

gfortran -I../modfiles -c prog.f90 

Adding debug information

Using -g to add some debug information to the object file. It is useful when you look into a source of a program crash. This option increases the size of the executable.

gfortran -g prog.f90

Optimization

A compiler can generate a faster program by modifying the original code. Using -O (by default in many compilers), the compiler chooses the safest option for optimization. With -O2, the optimization level is higher, and it is generally recommended in stable programs. The most aggressive optimization is available with -O3, which is often used in very stable, reusable programs (like external procedures and modules).

gfortran -O2 prog.f90

If you want to remove all optimization, use -O0. The executable becomes very slow, and it is useful only in debug.

Other useful options

Some useful options are compiler-specific, and we show the options for GFortran and Intel Fortran Compiler only.

Warning in the compilation

The source file may contain risky code, which could result in bugs. A compiler partially recognizes such code and show warnings if found.

It checks all possible risks in the source file. If you want to get specific warnings only, please see the manual of each compiler.

Checking run-time errors

The executable would not fail even if there is a logical error, and it finishes without any errors, but the results would be nonsense. The following option checks details while the program is running. The option makes the program significantly slow, so you should use it for testing only.

Showing back-trace

When the executable stops with an error, a backtrace shows some hints where the error occurs in the source file.

Adding “implicit none”

There is an option to force apply implicit none to the source code. When you forget to write implicit none and you accidentally use some variables with no declaration, this option gives you a warning. You must write implicit none in your code.

Intel Fortran has an option to give you a warning if there is no implicit none. It is covered by -warn all.

Back to index.html.