2013-04-18 231 views
5

我想編譯一個使用一堆模塊的fortran程序。我編譯時遇到錯誤,這讓我發瘋。該錯誤是源於通過添加一個子程序,併發生當我嘗試重新編譯程序: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 

我完全不知道爲什麼會出現這種行爲。如果有人能幫我解決這個噩夢,我會很感激。謝謝!

+2

你運行'make clean'然後再次嘗試make嗎? –

+0

是的,但沒有解決任何問題。我確保fileio.o(包含模塊)已更新。 – user2296052

回答

7

如果子程序read_step的定義在模塊中,那麼您或者忘記將該模塊的USE語句添加到主程序的頂部,或者模塊中的相關過程不是PUBLIC。

隨着該編譯器(和其他一些人),用於模塊程序鏈接程序名稱一般由模塊名,接着「熔點」(區分可能會發生變化),然後過程名稱,用不同量的前緣和後下劃線鹽醃去嚐嚐。您的鏈接器錯誤沒有任何「mangling」,這表示在編譯具有過程引用的範圍時,編譯器不認爲過程是模塊過程。

+0

非常感謝IanH!你解決了我的問題。感謝您的評論意識到,沒有將相關子例程的名稱添加到模塊頂部的「public」標籤。 – user2296052

0

爲了更具體一些,我將展示如何使用其他答案中提到的USE和PUBLIC語句。

我包我的F77功能是這樣的:

module mod 
    contains 
    FUNCTION FUNC(PARAM) 
    ... 
    END 
    end module mod 

雖然舊代碼(1986)是大寫和我的代碼是小寫。 這編譯得很好。您可以在modulecontains之間添加public func。但是這似乎是默認的,所以你不需要它。

鏈接時,您需要傳遞您的程序和庫如下:gfortran -o prog prog.for mod.for(或.o如果編譯之前)。

+0

這應該可能是一個問題,而不是答案。當您使用模塊編譯源代碼時,會生成一個目標文件(.o)。你是否將這個目標文件提供給後面的鏈接步驟? – IanH

+0

我知道,我發佈了一個問題:http://stackoverflow.com/questions/32278178/how-to-call-a-function-in-fortran-that-is-defined-in-a-separate-file/32278579 #32278579將刪除這一個,或更新它是一個真正的答案。 ;) – JPT