Build Systems

Modules introduce compilation-order dependencies — a build tool should track them.

35.1 Manual compilation & module order

Modules introduce compilation-order dependencies — a build tool should track them.

gfortran -c constants.f90           # produces constants.o and constants.mod
gfortran -c physics.f90             # uses constants → must come after
gfortran -c main.f90
gfortran constants.o physics.o main.o -o sim

35.2 Make

Tools to generate dependencies: makedepf90, fortdepend.

FC = gfortran
FFLAGS = -O2 -Wall -std=f2018
OBJS = constants.o physics.o main.o

sim: $(OBJS)
	$(FC) $(FFLAGS) -o $@ $^

physics.o: constants.o
main.o: physics.o constants.o

%.o: %.f90
	$(FC) $(FFLAGS) -c $<

clean:
	rm -f *.o *.mod sim

35.3 CMake (handles Fortran module dependencies automatically)

Also: Meson, SCons, Autotools, FoBiS.py.

cmake_minimum_required(VERSION 3.20)
project(Sim LANGUAGES Fortran)
set(CMAKE_Fortran_STANDARD 2018)
find_package(OpenMP REQUIRED)
find_package(LAPACK REQUIRED)
add_library(physics src/constants.f90 src/physics.f90)
add_executable(sim app/main.f90)
target_link_libraries(sim PRIVATE physics OpenMP::OpenMP_Fortran LAPACK::LAPACK)
target_compile_options(sim PRIVATE $<$<CONFIG:Debug>:-fcheck=all -g>)
cmake -B build -DCMAKE_BUILD_TYPE=Release && cmake --build build -j

35.4 fpm (Fortran Package Manager)

fpm resolves module dependencies automatically and fetches packages (registry at fpm.fortran-lang.org).

my_project/
├── fpm.toml
├── src/        (library modules)
├── app/        (main programs)
├── test/       (tests)
└── example/
name = "my_project"
version = "0.1.0"
license = "MIT"

[build]
auto-executables = true

[dependencies]
stdlib = "*"
json-fortran = { git = "https://github.com/jacobwilliams/json-fortran.git" }

[dev-dependencies]
test-drive = { git = "https://github.com/fortran-lang/test-drive.git" }
fpm build --profile release --flag "-march=native"
fpm run --compiler ifx
fpm test
fpm install --prefix ~/.local