Search code examples
fortrangfortrancircular-dependency

Fortran Submodules - Can't open module file »mod_globals.smod«


I started to program a little Fortran program organized in modules. Each module consists of an initialize and finalize subroutine for allocations and deallocations.

Now I get circular dependencies with a subroutine called "Abort" in the module globals. This subroutine should call each modules finalize subroutines if an error occurs. The call of the "Abort" subroutine is placed in all modules after some calculations.

My plan was it to use the submodules, introduced with Fortran 2008(2003). But it don't get the problem solved. Do I have understood the Submodules functionality wrong?

My Fortran compiler tells me:

Can't open module file »mod_globals.smod« for reading at (1): No such file or directory

And here is a part of the module globals:

! Module Globals
MODULE MOD_GLOBALS
    IMPLICIT NONE
    PRIVATE

    INTERFACE
        MODULE SUBROUTINE doAbort()
        END SUBROUTINE doAbort
    END INTERFACE

CONTAINS

    SUBROUTINE setAbortFlag(fileString,errorLine)
        ... fill variables with the fileString and errorLine
        CALL doAbort()
    END SUBROUTINE setAbortFlag

END MODULE MOD_GLOBALS

! Submodule 
SUBMODULE (MOD_GLOBALS) S_MOD_GLOBALS
    IMPLICIT NONE

CONTAINS

    MODULE PROCEDURE doAbort
        USE MOD_TEST, ONLY: finalizeTEST

        CALL finalizeTEST()

        EXIT(-1)
    END PROCEDURE doAbort

END SUBMODULE S_MOD_GLOBALS

and here the respective code part of the test module:

! Module Test
MODULE MOD_TEST
    IMPLICIT NONE
    PRIVATE
    PUBLIC finalizeTEST, doSomeStuff

CONTAINS

    SUBROUTINE finalizeTEST()
        ... do some deallocations
    END SUBROUTINE finalizeTEST

    SUBROUTINE doSomeStuff()
        USE MOD_GLOBALS, ONLY: setAbortFlag

        ... maybe error in some calculations
        CALL setAbortFlag(__FILE__,__LINE__)
    END SUBROUTINE doSomeStuff

END MODULE MOD_TEST

Solution

  • More of a comment than an answer, but the comment box offers so little in the way of formatting ...

    Your code compiles without a hitch if you take out the PRIVATE statement. I can't track this to the standard and my experience with submodules is limited so I'm not sure if this behaviour is correct or not. However the gfortran documentation states

    Submodules are supported. It should noted that MODULEs do not produce the smod file needed by the descendent SUBMODULEs unless they contain at least one MODULE PROCEDURE interface. The reason for this is that SUBMODULEs are useless without MODULE PROCEDUREs. See http://j3-fortran.org/doc/meeting/207/15-209.txt for a discussion and a draft interpretation. Adopting this interpretation has the advantage that code that does not use submodules does not generate smod files.

    I suspect that PRIVATE causes the interface to be not 'exported' from the module, which therefore contains nothing (useful) and is caught by the gotcha explained in the preceding paragraph. Adding the line

    public :: doAbort
    

    also fixes the compilation.

    I only have gfortran installed here, so can't test this with other compilers.

    And I don't see, from what you've posted, any issue with circular dependencies.