The error message:
mod_matrices.o:(.data+0x1790): undefined reference to `allocator_rank_2_sub_'
The module mMatrices (in mod_matrices.f08) calls the function allocator_rank_2_sub
which is in a submodule smAllocations (in mod_sub_matrices_allocators.f08). The code worked before breaking the module mMatrices
into a module and a submodule.
The module:
module mMatrices
use mPrecisionDefinitions, only : ip, rp
implicit none
type :: matrices
real ( rp ), allocatable :: A ( : , : ), AS ( : , : ), ASAinv ( : , : )
contains
private
procedure, nopass, public :: allocator_rank_2 => allocator_rank_2_sub
procedure, public :: construct_matrices => construct_matrices_sub
end type matrices
private :: allocator_rank_2_sub
private :: construct_matrices_sub
interface
subroutine allocator_rank_2_sub ( array, rows, cols )
use mPrecisionDefinitions, only : ip, rp
real ( rp ), allocatable, intent ( out ) :: array ( : , : )
integer ( ip ), intent ( in ) :: rows, cols
end subroutine allocator_rank_2_sub
end interface
contains
subroutine construct_matrices_sub ( me, ints, mydof, measure )
...
call me % allocator_rank_2 ( me % A, m, mydof )
...
end subroutine construct_matrices_sub
end module mMatrices
The submodule:
submodule ( mMatrices ) smAllocations
contains
module subroutine allocator_rank_2_sub ( array, rows, cols )
...
end subroutine allocator_rank_2_sub
end submodule smAllocations
The compilation via make:
ftn -g -c -r s -o mod_precision_definitions.o mod_precision_definitions.f08
...
ftn -g -c -r s -o mod_matrices.o mod_matrices.f08
...
ftn -g -c -r s -o mod_sub_matrices_allocators.o mod_sub_matrices_allocators.f08
...
ftn -g -c -r s -o lsq.o lsq.f08
ftn -g -o lsq lsq.o --- mod_matrices.o --- mod_precision_definitions.o --- mod_sub_matrices_allocators.o ---
mod_matrices.o:(.data+0x1790): undefined reference to `allocator_rank_2_sub_'
make: *** [lsq] Error 1
The last portion of `makefile'
# Main program depends on all modules
$(PRG_OBJ) : $(MOD_OBJS)
# resolve module interdependencies
...
mod_matrices.o : mod_precision_definitions.o mod_parameters.o mod_intermediates.o
mod_sub_matrices_allocators.o : mod_matrices.o
...
The machine: Cray XC30
The compiler: Fortran 5.2.82
The question: What needs to be fixed?
The corrected code fragment incorporating @IanH's fix:
interface
MODULE subroutine allocator_rank_2_sub ( array, rows, cols )
use mPrecisionDefinitions, only : ip, rp
real ( rp ), allocatable, intent ( out ) :: array ( : , : )
integer ( ip ), intent ( in ) :: rows, cols
end subroutine allocator_rank_2_sub
end interface
The interface block for allocator_rank_2_sub in the specification part of the module is missing the MODULE prefix. This means that it specifies an external procedure, not the intended separate module procedure. The linker is then complaining that it cannot find such an external procedure.
Add the MODULE prefix to the subroutine statement in the interface body.