Pierre de Buyl's homepage

Fortran, CMake and git

There is an interesting peak of activity around Fortran: a new website for the Fortran standards committee, a GitHub organisation around Fortran FOSS, Fortran libraries for convenience functionality (command-line arguments parsing, strings, JSON file handling, I probably miss others). Still, it is troublesome to find practical information on how to use modern tools of software developments with Fortran. I focus only on open-source tools.

In this blog post, I present a solution using CMake and git for building and distributing Fortran libraries and programs. I do not specifically advocate for my setup but I wish to document the practice that I developed. I use the method presented below for my own work with satisfaction since several years and it has become transparent and friction-free for me.

Distributing Fortran libraries and programs

Looking back, an accepted method to distribute Fortran programs is to have an entry on Netlib, allowing users to download *.f files (sometimes a Makefile is provided). Other locations include personal websites, supplementary material of scientific articles, etc.

This is however not satisfactory solution for a number of reasons as it

  1. does not a priori provide an historical reference of the versions or version information.
  2. is difficult to automate, as every package might have a different structure.
  3. does not provide automated build instructions.

As there is no requirement of binary compability between Fortran compilers, there is also the need to compile every library for a specific compiler.

Building Fortran programs with CMake

CMake is an open-source, cross-platform family of tools designed to build, test and package software (copied from their page).

CMake supports out-of-the-box C, C++ and Fortran. A simplistic CMakeLists.txt (the primary configuration file for CMake) can be:

cmake_minimum_required(VERSION 2.6)

Project(fortran_project Fortran)

set(CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/modules)

add_executable(fortran_program fortran_program.f90)

and can be executed as

mkdir build
cd build
cmake ..
make
./fortran_program

The need for a build directory comes from the ability of CMake to use several build directories. Most projects include those same lines in their build instructions.

Until now, this could be accomplished by a single line in a shell script gfortran -o fortran_program src/fortran_program.f90 or a simple Makefile. CMake comes in handy for most other use cases, though. The example program does not do much (spoiler: it prints "Hello, world!" to the terminal), yet.

Distributing Fortran program with git

Using a version control system (VCS) is, I believe, considered good practice (see for instance Best Practices for Scientific Computing, G. Wilson et al doi).

I use git, one of the reference VCS, and the GitHub hosting service. It is possible to use git for the sole purpose of downloading a project, a process called "cloning".

git clone https://github.com/pdebuyl/fortran_project
cd fortran_project

If you need a specific revision, you can select it with the git checkout command, provided that the project maintainer has set up a tag for it.

Given the compiler-specific build of Fortran libraries and programs, it is interesting to reference all your dependencies within the git repository. This is possible thanks to the "submodule" feature.

I'll add a suitably set up (i.e. it has a CMakeLists.txt file) library by Milan Curcic, datetime-fortran.

git add submodule https://github.com/wavebitscientific/datetime-fortran

The "submodules" I referred to above appear as extra directories in a project. Now, if those submodules have been configured with CMake, it is trivial to use their libraries from your project. That is what the add_subdirectory command does:

add_subdirectory(datetime-fortran)
include_directories(${CMAKE_BINARY_DIR}/datetime-fortran/include)

And to link the library

target_link_libraries(fortran_program datetime)

I have to admit that the include_directories line look a bit more magical than the rest. The library datetime-fortran stores the module files *.mod into the datetime-fortran/include within the build directory ${CMAKE_BINARY_DIR}. This must be specified to CMake for proper building of code that depends on the library.

Gluing it all

Now, either you have not cloned the repository, in which case you can type directly

git clone --recurse-submodules  https://github.com/pdebuyl/fortran_project

or you have not and you must type

git submodule init
git submodule update

to fetch the submodule.

The rest of the procedure is identical to the one given in the first paragraph (from the fortran_project directory)

mkdir build
cd build
cmake ..
make
./fortran_program

Comments

The example I have given a of course simplistic. I comment now on the interest of the method:

  1. Allows mixed C/Fortran codebases.
  2. Provides unified build instructions.
  3. CMake has utility modules to find and link libraries, to locate the binary for git, to define and execute tests, among others.
  4. For yourself and others, it is easy to automate in a cross-platform way the download and build of complex projects.

There are limitations to my system

  1. GitHub is not an archive. Removal of a package by an author is possible, as well as a "force-push" that modifies the repository and its history.
  2. Git submodules are frowned upon by many people and their use can be intimidating.

Comments on the method and the text are very welcome! Just keep in mind that I don't advocate the method as a universal solution :-)

Comments !

Comments are temporarily disabled.

Generated with Pelican. Theme based on MIT-licensed Skeleton.