2013-04-18 4 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! Вы решили мою проблему. Благодаря вашему замечанию понял, что не добавил имя соответствующей подпрограммы к «общедоступному» тегу в верхней части модуля. – user2296052

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 если скомпилировано ранее).

+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

Смежные вопросы