Makefile and CMake

Software written in Fortran can be build by executing the compiler from the command-line. Various tools are available to automate this build process. A common way on Unix is the creation of Makefiles, which specify all steps for compilation, linking, and installation. CMake can be used to generate Makefiles, making the build process compiler-independent.

Makefile

The build process of Fortran projects can automated by writing a Makefile. Makefiles are an easy way to maintain the dependencies of a programme. Once written, the file can be executed by the make utility, which then does the compilation, linking, and installation.

The very simplistic Makefile below is used to compile an example Fortran programme example.f90 with Flang. Please note the hard tabs in the source.

FC = flang

SOURCES    = example.f90
EXECUTABLE = example

all: $(EXECUTABLE)

$(EXECUTABLE):
	$(FC) -o $(EXECUTABLE) $(SOURCES)

clean:
	rm $(EXECUTABLE)

The Makefile has to be placed in the same directory as the source code. Execute make or make all inside the directory to compile the example:

$ make
flang -o example example.f90

Running make clean will delete the built executable.

Linking

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

CC = clang
FC = flang

CFLAGS     = -c -Wall
LDFLAGS    = -lncurses
OBJECTS    = macros.o ncurses.o
SOURCES    = main.f90
EXECUTABLE = main

all: $(EXECUTABLE)

$(EXECUTABLE): $(OBJECTS)
	$(FC) $(LDFLAGS) -o $(EXECUTABLE) $(SOURCES) $(OBJECTS)

macros.o: macros.c
	$(CC) $(CFLAGS) macros.c

ncurses.o: ncurses.f90
	$(FC) $(CFLAGS) ncurses.f90

clean:
	rm *.o *.mod $(EXECUTABLE)

CMake

Makefiles can be generated automatically with build tools like CMake. This makes it possible to regard the used platform and set compiler-specific options. The example CMake project below requires GNU Fortran 7. The source file main.f90 will be compiled and statically linked against f90getopt.f90.

Please be aware that the file ending of a Fortran source file must either be .f90 or .f95 to be recognised by CMake.

cmake_minimum_required(VERSION 3.9)
project(Example)
set(VERSION 1.0)

set(CMAKE_Fortran_COMPILER      "gfortran7")
set(CMAKE_Fortran_FLAGS         "${CMAKE_Fortran_FLAGS} -Wl,-rpath=/usr/local/lib/gcc7 -ffree-form -std=f2008 -fbackslash -fimplicit-none -fall-intrinsics")
set(CMAKE_Fortran_FLAGS_DEBUG   "-Wall -O0 -g3 -fbounds-check")
set(CMAKE_Fortran_FLAGS_RELEASE "-Ofast -march=native")

enable_language(Fortran)

if(NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE "Release")
endif()

set(SOURCE_FILES main.f90)
add_library(f90getopt STATIC f90getopt.f90)

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

Create the Makefile and build the project with:

$ cmake .
$ make