我正在尝试编译一个使用一堆模块的fortran程序。编译时我得到一个错误,这让我发疯了。该错误是由添加一个子例程引起的,当我尝试重新编译程序时发生:
主程序包含以下两行:
-
call read_step(nStepOne,molOne)
call read_step(nStep,mol)
-
这是调用文件“fileio.f90”中的一个子程序:
-
subroutine read_step(n,tape)
implicit none
integer, intent(in) :: tape
integer, intent(out) :: n
character(len=6) :: dum
rewind(tape)
read (tape,*)
read (tape,*) dum, n
rewind(tape)
return
!
end subroutine read_step
-
当我尝试编译它时,会出现以下错误:
ifort -o SpIdMD.x *.o -static-intel -openmp
SpIdMD.o: In function `MAIN__':
SpIdMD.f90:(.text+0x3b2): undefined reference to `read_step_'
SpIdMD.f90:(.text+0x3c5): undefined reference to `read_step_'
make: *** [SpIdMD.x] Error 1
在同一个模块中对子程序的其他调用没有给出任何错误,我只是看不到对“旧子程序”的调用与我刚创建的那个之间的任何区别。
其中一个“旧子程序”的例子是:
在主程序中:
call get_dim(n_atom,nSnap,mol)
在fileio.f90中:
subroutine get_dim(n,n_snap,tape)
implicit none
integer,intent(in) :: tape
integer,intent(out) :: n, n_snap
integer :: m
rewind(tape)
read (tape,*,err=1,end=2) n
rewind(tape)
m = 0
do while (.true.)
read (tape,*,err=1,end=3)
m = m +1
end do
3 n_snap = m/(n + 2)
if (m.ne.(n_snap*(n + 2))) stop 'unexpected end of input file'
rewind(tape)
return
!
1 stop 'error in input file'
2 stop 'unexpected end of input file'
end subroutine get_dim
我完全不知道为什么会这样做。如果有人能帮我解决这个噩梦,我将不胜感激。谢谢!
答案 0 :(得分:8)
如果子例程read_step的定义在模块中,那么您忘记将该模块的USE语句添加到主程序的顶部,或者模块中的相关过程不是PUBLIC。
使用该编译器(以及其他一些编译器),模块程序的链接器名称通常由模块名称后跟' mp ' (案例可能会有所不同),然后是程序名称,不同数量的前导和尾随下划线腌制成味道。您的链接器错误没有任何" mangling",这表明在使用过程引用编译范围时,编译器并不认为该过程是模块过程。
答案 1 :(得分:0)
更具体地说,我将展示如何使用其他答案中提到的USE和PUBLIC语句。
我把我的F77功能包裹起来:
module mod
contains
FUNCTION FUNC(PARAM)
...
END
end module mod
虽然旧代码(1986)是大写而我的代码是小写。
编译好了。您可以在public func
和module
之间添加contains
。但这似乎是默认的,所以你不需要它。
链接时,您需要传递您的程序和库,如下所示:gfortran -o prog prog.for mod.for
(如果之前已编译,则为.o
。)