Modern Fortran tooling is limited by the fact that module information is stored in compiler-specific .mod files, which are not portable or externally usable. This makes it difficult to build reliable wrappers, IDEs, and static analysis tools.
It may be worth considering a requirement in the Fortran standard for compilers to support exporting a semantic module interface in a portable format (e.g., JSON). For example:
compiler --emit-module-interface mpi.mod
This export would contain only the public semantic API of a module:
public procedures and their full signatures
derived types and their components
generic interfaces and operators
constants and parameters
use dependencies
bind(C) interoperability info
The goal is not to standardize .mod internals, but to provide a stable, compiler-generated semantic interface layer derived from existing compiler knowledge.
This would greatly improve Fortran interoperability with:
wrapper generators (Python/C/Rust)
language servers and IDEs
static analysis tools
package managers
Today, compilers already have this semantic information internally; this proposal simply makes it accessible in a standardized and portable way.
Of course, much like the .mod files, these outputs are compiler specific.
AFAIK, the mod files are not even part of the standard, so standardization is unlikely to happen in a reasonable time. You are better off trying to work with flang or lfortran. @certik, maybe the ast parser of LFortran could be proposed as a separate dependency (.dll) to make the integration as 3rd party easier/lighter than relying on the entire LLVM framework.
You would need it to include more than just the public aspects of the module, because submodules have access to the private entities as well. Some compilers also put representations of the executable code in there as well for possible in-lining/optimization in later uses. Honestly, the standardized format already exists. It’s the Fortran source code. That’s why I designed fpm around source distributions and not binary distributions.
I agree that .mod files may contain additional compiler-specific information for submodules, inlining, and optimizations. My suggestion is not to standardize or expose all compiler internals, but only the semantic interface information relevant for tooling: public procedures, types, interfaces, dependencies, etc.
Also, source code is not always available, and rebuilding/reanalyzing large dependency trees can be expensive. In practice, users often only have the .so/.a libraries together with the .mod files, so exposing this semantic information in a portable form could greatly help tooling.
People who have never been tasked to maintain multiple copies of the Fortran interfaces to say an MPI distribution just because the the mod files for compilers are different don’t appear to understand or care about the time and resources wasted by not having a single transportable mod file format that can be used by multiple compilers. Sorry but “having the source file” is not enough. This is true for a lot of software particularly libraries where the Fortran part is just an interface to underlying C code.
I had been tasked with maintaining a commercial parallel software library, written in Fortran and based on MPI (with its 3 levels of interface sophistication), for various platforms, for some years in the 2000s and 2010s. If I didn’t have to worry about .mod file structure being different among compilers, I would still have 95% to 99.5% of the workload.
I’m not entirely convinced that tools would benefit much from .mod compatibility itself. Even if they were standardized in some way, they would still be tightly coupled to compiler internals, which limits their usefulness outside the build process.
Where I do see a clearer structural issue is at the ABI layer rather than the module layer. But even there, most practical interoperability needs are already covered via bind(C). So I tend to see .mod compatibility as less central than it might first appear in terms of ecosystem interoperability. These are just a build system friction point.
This misses many useful features of modern fortran, such as optional arguments, allocatable arguments, derived type arguments, and so on. If you want a general library that uses those features that is fortran compiler agnostic, then it seems like going down to the API/ABI level would be necessary.
Only a partial solution but I always wished more loaders would search archive (.a) files for .mod files like the Sun compiler. This eliminated multiple bookkeeping issues. Combined with the ability of gmake to maintain an archive file directly this meant instead of dozens of .mod files in an include/ directory and build directories full of hundreds of .o files you could maintain just a single file per compiler. The file could even contain documentation and scripts and source files although I rarely have seen that done outside of a few places I worked..
Long ago the CDC NOS operating system had the concept of a library file that was designed so it could contain an entire project in such a manner (text, object files, source files, scripts, …) that you could “activate” and make part of the environment. When it was active the scripts in it became commands in your environment and object files in it were available to the loader as if they were intrinsics.
files created with ar were the closest to that in subsequent Unix-Like-Systems although not nearly as easy to integrate into the environment as NOS libraries. But that previous history with “super” libaries made it feel natural to use ar to contain an entire project including source when combined with a few scripts that would expand out such “project” files into directories for building and editing. It was great for bookkeeping and distribution (give someone just a single file) and tar and zip were never a very satisfying replacement. The rest of the world did not follow this path so we gradually moved away from that model and llike the rest of the world used a combination of tar/cpio/zip and git/mercury/scsc/… .
But just being able to keep the .mod files in an archive file along with the .o files would still be useful, but as far as I know very few if any remaining loaders look for .mod files in archive files. A shame, as it was useful and simplified some of the issues being discussed here, albeit not a complete solution.
Maybe one of the bright young people here can develop a Fortran Archive Manager (FARM maybe ? ) to supplement FPM that will allow inclusion of .mod files in an archive. Would probably have to modify the linker/loader too but maybe thats something we could get the LLVM based compilers to look at.
I remember long ago that early versions of what is now the intel compiler also did not create *.mod files. I forget exactly when this was, I think it was after the team had moved from DEC, but I don’t remember if it was under the Compaq or HP or Intel banner. I think all the module information was placed in a single local file, which was then automatically searched by the compiler.
As mentioned previously, one problem with module files is that they are automatically created by the compiler, so the programmer has no (or little) control over their name, upper- or lower-case naming conventions, and so on. I remember writing Makefiles that tried to account for both *.mod and *.MOD file names being created. Somewhere along the timeline, everyone more or less agreed on lower-case file names and lower case *.mod extensions. However, one aspect of that “feature” was that it became clear that you could write Makefiles that do not reference the mod files directly as targets or as dependencies in the build process. You can instead just reference the *.o files, and the associated *.mod files, which are created at the same time, can just ride along for free. The only remaining *.mod file references are in the clean targets.