(Imported from MoinMoin)
m (1 revision(s))
Revision as of 16:27, 24 May 2008
|This is an incomplete, rough draft.|
[This page needs a lot more work]
- 1 Packaging Fortran Libraries
- 2 Design of Library Interfaces
- 3 Location and Naming of INCLUDE Files
- 4 Location of Compiled Module Interface Files
Packaging Fortran Libraries
Packaging Fortran libraries poses several issues, because Fortran Standards specifically avoid compiler and file management standards, and because the design of Modules is particularly unaccommodating towards a proper API design.
Fortran compilers generally produce a compiler-specific files to define the interface to members of the module. These data files are essentially precompiled headers. But, unlike C precompiled headers, they are generated while compiling module source code, and therefore must be packaged with the library distribution.
Ideally, portable Fortran libraries would avoid the use of modules. The good news is that a Sub-module specification has been defined which will allow the interface specification part of a module to be separate from the procedure source code. One this is implemented in Fortran compilers, it should be utilized by all packaged libraries.
Design of Library Interfaces
The most logical organization of libraries is to use Modules, but this not yet possible to do cleanly due to the lack of a proper ABI for Fortran module procedures.
Several approaches are possible. How much diversity should be allowed for standardized packages? Note that C++ has multiple design approaches, like templates, so this is not unique to Fortran.
Libraries with no Public Modules
The least problematic approach is to completely avoid using Modules. This takes extra effort by the library creator to work efficiently, but eliminates the module-packaging problems. With this method, all procedures should have explicit interfaces defined in one or more INCLUDE files (see below for name/location). All procedures and other public symbols must have a common prefix to avoid name-space conflicts.
This method takes away some of the convenience of modules, but much of this can be regained by encouraging library users to incorporate the interface into a local module file.
This approach also requires that all public variables be contained in common blocks, and that all derived types include the SEQUENCE specification. For both of these objects, it is important for the library designer to define the order of member items to avoid binary mis-alignment.
Libraries with Interface-Only Modules
This approach is similar in many respects to the non-module approach, but also benefits from some features of modules. In general, the main difference is that the INCLUDE file contents are incorporated into public INTERFACE modules. This is the method used by Intel Fortran. Each Interface module should be distributed as source code, and as a pre-compiled .mod file.
Fully Module-Based Libraries
What a pain.
SubModule Based Libraries
Sub-modules are a recently defined feature, not yet available. It will (supposedly) solve many of these problems. If it actually ends up working sensibly, this should become the primary method for public Fortran Libraries.
Use of ISO_C_BINDING for Improved Binary Compatibility
One of the big disadvantages of Fortran modules is that binary objects are incompatible among different compilers.
Fortran77 (external) interfaces have become fairly standardized, although only by popular convention. It is quite easy to create libraries that can be used by more than one compiler, as long as the routines are PURE (and a few other restrictions), which is easy to do for purely mathematical libraries.
Location and Naming of INCLUDE Files
Fortran can utilize INCLUDE files, similar to C headers. The most common filename suffix is '.inc', although '.fh' has been used for files that are designed to function as public headers. Many people have put these files in /usr/include, but that is wrong. FHS defines this directory for C language headers.
Location of Compiled Module Interface Files
Module (.mod) files function to define the module's interface, similar to headers.