I’m using gfortran’s 95+ extensions. I have a library of utility modules I’d like to link to other projects, i.e. as a library or shared object / dll. However, in Fortran, I don’t understand how to split the interface from the implementation in Fortran without maintaining two copies of the module interface.
In C, I would separate the interface from the implementation like:
api.h ←includes← impl.h
↑ ↑
includes includes
↑ ↑
user.c impl.c
Is there a way to achieve the same effects in modern Fortran? Do I need to provide users my library with the .mod files?
- Single definition of an explicit interface
- Only interface definitions are exposed to the user code
Edit: To sum up (what I think is) the answer:
-
.mod files are needed, as they contain the explicit interface definition
-
There is no standard Fortran ABI for modules — .mod files will be compiler-specific
-
The only directly analgous approach to the implementation-hiding problem is submodules, which are defined in Fortran 2008, and which gfortran does not support.
-
The most practical approach, aside from avoiding modules, noted by @High-Performance-Mark and the Fedora page, is to distribute include files for interface-only modules along with precompiled .mods for the implementation.
-
Using includes has some well-known and annoying trip-ups, including the potential redefinition of common blocks.
I am a little surprised there is not actually a straightforward answer here.
I believe that you can do this with submodules using Fortran 2008 compilers. From FortranWiki:
From Wikipedia (emphasis mine)
I don’t have any experience with submodules, and they are not widely supported yet, but they are something to be aware of.
Edit Since many compilers don’t support submodules, it is probably helpful to discuss other options.
This page asks a similar question to this and has a number of nice links. Particularly useful in a discussion on Google Groups (see, in particular, this post). In summary, one option is to:
Group all the library functions/subroutines in a single file and by themselves (i.e. not being part of a module).
Create a module that only contains interfaces for those subroutines that you want to expose to the end user.
Provide end-users with the compiled module and the library. The user can then
usethe module in his/her programs and link against the library.This allows you to "hide" functions/subroutines that you don’t want to expose to the end user.
Lifted from the post I link to:
(final!) edit There is a useful page on the Fedora wiki: