Build Automation

Source code written in Fortran can be easily build by executing the compiler from the command-line. This build process can be automated by various tools. A common way on Unix are Makefiles, which specify all steps for compilation, linking, and installation of your project.

In many cases, Makefiles are not platform-independent. Therefore, it may be necessary to write distiguished Makefiles for each targeted system. Even if a POSIX standard for Makefiles exists, two implementations are used in the wild instead: BSD make and GNU make. Often, a Makefile written for BSD make won’t be accepted by GNU make, and vice versa. The CMake build system, for instance, bypasses these limitations by generating Makefiles with respect to the currently used environment and the compilers available.

Build utilities with Fortran support for Unix-like operating systems:


Makefiles are an easy way to maintain the build process of a Fortran project. Once written, the file can executed by the make utility (either BSD Make or GNU Make). The following very simplistic Makefile below is used to compile an example Fortran program example.f90 with GNU Fortran. Please note the hard tabs in the source.

FC     = gfortran10
SRC    = example.f90
TARGET = example

.PHONY: all clean

all: $(TARGET)

	$(FC) -o $(TARGET) $(SRC)

	rm $(OBJ)

Save the file as Makefile in the directory that locates your source code files. Execute make or make all inside the directory to compile the example:

$ make
gfortran10 -o example example.f90

To change the defined compiler to Flang, run:

$ make FC=flang

Running make clean will delete the built executable.


The example Makefile below also links the program against required dependencies. At first, the object files ncurses.o and macros.o will be compiled. Then, the main program is build and linked against the objects (see the ncurses section for a complete example).

CC      = clang
FC      = flang
CFLAGS  = -Wall
FFLAGS  = -Wall
LDLIBS  = -lncurses
OBJ     = macros.o ncurses.o
SRC     = main.f90
TARGET  = example

.PHONY: all clean

all: $(TARGET)

	$(FC) -o $@ $(SRC) $(OBJ) $(LDLIBS)

macros.o: $*.c
	$(CC) $(CFLAGS) -c $?

ncurses.o: $*.f90
	$(FC) $(FFLAGS) -c $?

	rm $(TARGET) *.o *.mod


Using CMake to generate a fresh Makefile allows to regard the used computer platform and to set compiler-specific options. In the following example, the source file main.f90 will be compiled and statically linked against a library in f90getopt.f90.

Please be aware that the ending of all Fortran source files must either be set to .f90 or .f95 to be recognised by CMake. The CMake configuration has to be saved to file CMakeLists.txt in your source code path:

cmake_minimum_required(VERSION 3.5)
set(VERSION 1.0)


if(CMAKE_Fortran_COMPILER MATCHES "gfortran*")
    set(CMAKE_SKIP_BUILD_RPATH            FALSE)

    set(CMAKE_Fortran_FLAGS         "${CMAKE_Fortran_FLAGS} -std=f2003 -fimplicit-none")
    set(CMAKE_Fortran_FLAGS_DEBUG   "-Wall -O0 -g3 -fbounds-check")
    set(CMAKE_Fortran_FLAGS_RELEASE "-O2")

set(TARGET example)
set(SOURCE_FILES main.f90)

add_library(f90getopt STATIC f90getopt.f90)

add_executable(${TARGET} ${SOURCE_FILES})
target_link_libraries(${TARGET} f90getopt)
set_target_properties(${TARGET} PROPERTIES LINKER_LANGUAGE Fortran)

Generate a Makefile and build the project with:

$ mkdir build
$ cd build/
$ cmake ..
$ make

You can force a specific compiler by using the -DCMAKE_Fortran_COMPILER flag:

$ cmake -DCMAKE_Fortran_COMPILER=gfortran10 -DCMAKE_INSTALL_RPATH=/usr/local/lib/gcc10/ ..


The platform-independend xmake build utility is based on Lua, and supports multiple programming languages, including Fortran since version 2.3.6. In comparision, xmake is a more lightweight build system, consisting of only a single executable with no further dependencies. On FreeBSD, simply compile the program from source:

$ git clone --recurse-submodules
$ cd xmake/
$ gmake build
$ gmake install PREFIX=/usr/local

The compiled xmake executable will be copied to /usr/local/bin/xmake. Inside the Fortran workspace directory, create a new build script named xmake.lua, for instance:


Then, just run xmake inside the directory:

$ xmake
[ 46%]: compiling.release src/util.f90
[ 60%]: compiling.release src/main.f90
[ 62%]: linking.release example
[100%]: build ok!

Static and shared libraries can be linked with xmake as well.