2012-04-11 6 views
5

Ich versuche zu verstehen, wie man eine gemeinsame Bibliothek in Fortran unter Linux dynamisch herstellt und verbindet.Gemeinsame Bibliothek in Fortran, minimales Beispiel funktioniert nicht

Ich habe zwei Dateien: Die erste, liblol.f90, das wie folgt aussieht:

subroutine func() 
    print*, 'lol!' 
end subroutine func 

ich es kompilieren mit gfortran -shared -fPIC -o liblol.so liblol.f90

Die zweite Datei, sieht main.f90, wie folgt aus:

program main 
    call func() 
end program main 

Wenn ich jetzt versuche, das mit dem Befehl gfortran -L. -llol main.f90 -o main zu kompilieren, erhalte ich den folgenden Fehler:

/tmp/ccIUIhcE.o: In function `MAIN__': 
main.f90:(.text+0xa): undefined reference to `func_' 
collect2: ld returned 1 exit status 

Ich verstehe nicht, warum heißt es "undefined reference", da der Ausgang des nm -D liblol.so das gibt mir:

    w _Jv_RegisterClasses 
0000000000201028 A __bss_start 
       w __cxa_finalize 
       w __gmon_start__ 
0000000000201028 A _edata 
0000000000201038 A _end 
0000000000000778 T _fini 
       U _gfortran_st_write 
       U _gfortran_st_write_done 
       U _gfortran_transfer_character_write 
0000000000000598 T _init 
00000000000006cc T func_ 

Gibt es einen anderen Parameter benötigt?

Antwort

8

Das einzige, was geändert werden muss, ist die Reihenfolge der Argumente, wie in

gfortran -L. main.f90 -llol -o main 

Ja, nur main.f90 und -llol umgekehrt werden. Ich hoffe, das rettet jemandem das Jahr seines Lebens, das ich gerade verloren habe. Wenn Sie versuchen, ein Programm zu kompilieren, das LAPACK oder BLAS verwendet (was bei mir nicht funktioniert hat und deshalb zuerst versucht habe, eine gemeinsame Bibliothek zu erstellen), gilt das Gleiche auch. Schreiben Sie den Namen der Quelldatei zuerst:

gfortran mylapack.f90 -llapack -lblas -o mylapack 

Der Grund hierfür in den Handbuchseiten gefunden werden kann, finden Sie in der oben auf http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html für die Option -l:

It makes a difference where in the command you write this option; the linker searches and processes libraries and object files in the order they are specified. Thus, foo.o -lz bar.o searches library z after file foo.o but before bar.o. If bar.o refers to functions in `z', those functions may not be loaded.