2013-04-18 15 views
5

Próbuję skompilować program fortranowy, który wykorzystuje kilka modułów. Podczas kompilacji otrzymuję błąd i doprowadza mnie to do szału. Błąd jest zapoczątkowane przez dodanie jednego podprogramu i odbywa się, gdy próbuję skompilować program:Błąd kompilacji Fortrana - niezdefiniowane odniesienie

Program główny zawiera te dwie linie:

-

call read_step(nStepOne,molOne) 
call read_step(nStep,mol) 

-

Wywołuje jeden z podprogramów w pliku "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 

-

Gdy próbuję go skompilować, pojawia się następujący błąd:

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 

Inne wywołań podprogramów w tym samym module nie daje żadnego błędu, a ja po prostu nie robić zobacz jakąkolwiek różnicę między wywołaniami do "starych podprogramów" a tymi, które właśnie stworzyłem.

Przykładem jednego z tych "starych podprogramów", który nie daje żadnej skargi, to:

W głównym programie:

call get_dim(n_atom,nSnap,mol) 

W 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 

Nie mam pojęcia, dlaczego to zachowanie. Byłbym wdzięczny, gdyby ktoś mógł mi pomóc rozwiązać ten koszmar. Dzięki!

+2

Czy uruchomiłeś 'make clean', a następnie wypróbowałem' make' ponownie? –

+0

Tak, ale niczego nie rozwiązuje. Upewniłem się, że plik fileio.o (zawierający moduł) jest aktualizowany. – user2296052

Odpowiedz

7

Jeśli definicja podprogramu readout jest w module, to albo zapomniałeś dodać instrukcję USE dla tego modułu do górnej części głównego programu, albo odpowiednie procedury w module nie są PUBLICZNE.

Z tego kompilator (i niektórych innych) nazwami łącznik do procedur modułu zazwyczaj zawierają nazwę modułu następuje przez „tt” (wielkość może się zmieniać), a następnie nazwy procedury z różnymi ilościami natarcia i spływu podkreślenia solone do smaku. Twój błąd linkera nie ma żadnego "zmasakrowania", co oznacza, że ​​kompilator podczas kompilacji zakresu z odniesieniem do procedury nie uważa, że ​​procedura jest procedurą modułu.

+0

Wielkie dzięki IanH! Rozwiązałeś mój problem. Dzięki twojemu komentarzowi zrozumiałeś, że nie dodałeś nazwy odpowiedniego podprogramu do "publicznego" tagu na górze modułu. – user2296052

0

Aby być bardziej konkretnym, pokażę, jak korzystać z instrukcji USE i PUBLIC wymienionych w drugiej odpowiedzi.

I zawinięte moje funkcji F77 takiego:

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

Choć stary kod (1986) jest wielkie litery i mój kod jest małe litery. To kompiluje się dobrze. Możesz dodać public func między module i contains. Ale wydaje się to być domyślne, więc nie potrzebujesz tego.

Podczas łączenia należy przekazać program i bibliotekę w następujący sposób: gfortran -o prog prog.for mod.for (lub .o, jeśli wcześniej skompilowano).

+0

To prawdopodobnie powinno być pytanie, a nie odpowiedź. Podczas kompilowania źródła przy pomocy modułu generowany jest plik obiektowy (.o). Czy udostępniasz ten plik obiektowy do późniejszego etapu łączenia? – IanH

+0

Wiem, napisałem pytanie: http://stackoverflow.com/questions/32278178/how-to-call-a-function-in-fortran-that-is-defined-in-a-parate-file/32278579 # 32278579 usunie ten plik lub zaktualizuje go, aby był prawdziwą odpowiedzią. ;) – JPT

Powiązane problemy