I have been thinking recently about the current state of Fortran library distribution, especially for modern Fortran libraries exposing module-based APIs (not based on bind(C)). As far as I understand, there are currently two main distribution models.
1. Source distribution + build system
The library author distributes: source code, and build system (fpm, CMake, Makefiles, etc.). The user then compiles the library locally using the same compiler and flags as the main project.
Advantages:
- full use of modern Fortran semantics,
- no
.modfile/ABI mismatch.
Disadvantages:
- users must integrate the build system,
- all dependencies must use homogeneous compiler settings.
Although extended, this model feels cumbersome for reusable general-purpose libraries.
2. Binary library + .mod distribution
The library author distributes: .a / .so, and compiler-generated .mod files.
Advantages:
- users can consume the library directly,
- native Fortran APIs remain available.
Disadvantages:
.modfiles are compiler(version)-specific,- users are effectively forced to use the same compiler.
This model scales poorly across compilers and distributions.
Main friction points
1. .mod files are compiler-specific
This issue is widely known already. However, submodules seem to offer an elegant partial solution. Instead of distributing compiler-generated .mod files, a library could distribute interface-only .F90 module source files together with a library archive. The user would compile only the interface modules locally, generating native .mod files compatible with their compiler. Submodules make this especially attractive because they cleanly separate interface from implementation. Making parallels between module files and C header files.
2. ABI instability
This seems to be the harder problem. Even if .mod incompatibility disappears, compilers still differ in symbol mangling, calling conventionsā¦
This led me to wonder whether Fortran could eventually benefit from something similar to:
subroutine solve(A) bind(F)
bind(C) means āinteroperable with C ABIā. In this context, bind(F) would mean āinteroperable with a standardized native Fortran ABIā. This has been discussed before in other contexts.
The goal would not necessarily be to standardize all compiler internals, but perhaps:
- symbol naming,
- calling conventions,
- descriptor layouts,
- non-polymorphic derived type ABI,
- allocatable conventions.
This could potentially allow for binary-distributed native Fortran libraries and compiler-independent linking.
I think this is worth discussing because Modern Fortran already has many of the right language features such as encapsulation, explicit interfaces, and rich array semantics. In many ways, the language itself is already better suited for large numerical libraries than, for example, C. However, C still has a much simpler and more stable binary ecosystem.
Still, I wonder whether at least a partially standardized native ABI could be feasible without sacrificing too much compiler freedom. Especially because:
ISO_Fortran_binding.halready standardizes descriptors for C interoperability,- submodules now provide clean interface/implementation separation.
Curious to hear thoughts from compiler developers and library authors here.