2013-08-27 9 views
6

Jestem nowy w Fortranie. Pracuję nad projektem badawczym, w którym używam projektu open source, który ma kilka plików rozproszonych w wielu folderach. znalazłem zależność każdego programu, ale nie mogłem wymyślić, jak je skompilować.jak skompilować wielo-folderowy projekt Fortran mający interfejsy, moduły i podprogramy

Mam kod źródłowy rozprowadzany w trzech folderach. a) moduły b) c) interfejsy podprogramów

Chciałbym uruchomić program o nazwie jako „Main.f90” w folderze podprogramów, program ten ma zależność kodów źródłowych z modułów i interfejsów folderach.

Używam eclipse do struktury folderów i makefile do kompilacji.

Każda pomoc w tym zakresie jest doceniana.

UPDATE: Śledziłem odpowiedź wysłana przez @MBR i @Stefan jakiegoś powodu VPATH nie mógł znaleźć programy w kodzie źródłowym więc wyraźnie dał do tych ścieżkę folderu źródłowego w moim Makefile. poniżej znajduje się mój skrypt do tworzenia plików.

.PHONY: Mopac_exe clean 

    # Change this line if you are using a different Fortran compiler 
    FORTRAN_COMPILER = gfortran 
    SRC = src 

    #make main program 
    Mopac_exe: subroutines mopac.o 
     $(FORTRAN_COMPILER) mopac.o *.o -O2 -g -o bin/Mopac_exe -I Modules/ 

    #compile all the subroutines 
    subroutines: interfaces 
     $(FORTRAN_COMPILER) -c $(SRC)/subroutines/*.F90 -J Modules/Subroutines/ -I Modules/ 

    #compiles all the interfaces 
    interfaces: modules 
     $(FORTRAN_COMPILER) -c $(SRC)/interfaces/*.f90 -J Modules/ 


    # build all the modules and generate .mod file in Modules directory 
    modules: build_vast_kind 
     $(FORTRAN_COMPILER) -c $(SRC)/modules/*.f90 -J Modules/ 
     $(FORTRAN_COMPILER) -c $(SRC)/modules/*.F90 -J Modules/ 

    # compile vastkind.f90 files and generates the .mod file in Modules directory.Every other Modules and interfaces are dependent on this. 
    build_vast_kind:clean 
     $(FORTRAN_COMPILER) -c $(SRC)/modules/vastkind.f90 -J Modules/ 

    clean: 
     rm -f bin/Mopac_exe *.mod 
     rm -f Modules/*.mod 
     rm -f *.o 

Skompilowałem wszystkie moduły i umieściłem w katalogu modułów katalogu głównego. Cała kompilacja idzie dobrze. Występuje błąd podczas budowania pliku wykonywalnego. Dostaję następujący błąd.

gfortran mopac.o *.o -O2 -g  -o bin/Mopac_exe -I Modules/ 
    mopac.o: In function `main': 
    mopac.F90:(.text+0x27c1): multiple definition of `main' 
    mopac.o:mopac.F90:(.text+0x27c1): first defined here 
    getdat.o: In function `getdat_': 
    getdat.F90:(.text+0x22): undefined reference to `iargc_' 
    getdat.F90:(.text+0xf2): undefined reference to `getarg_' 
    symr.o: In function `symr_': 
    symr.F90:(.text+0xd3f): undefined reference to `symp_' 
    writmo.o: In function `writmo_': 
    writmo.F90:(.text+0x20c2): undefined reference to `volume_' 
    collect2: error: ld returned 1 exit status 
    make: *** [Mopac_exe] Error 1 

`iargc_ 'jest używany w' pliku getdat i iargc jest już skompilowany. dlaczego wystąpił błąd podczas wykonywania pliku wykonywalnego z informacją o niezdefiniowanym odnośniku? czego mi brakuje?

Odpowiedz

6

Można zrobić Makefile, który wygląda tak

F90=gfortran 
FFLAGS = -O0 
VPATH = modules:interfaces:subroutines: 
MODOBJ = module1.o module2.o ... 

your_executable: $(MODOBJ) main.o 
     $(F90) main.o -o your_executable 
%.o:%.f90 
     $(F90) $(FFLAGS) -c $^ -o [email protected] 

VPATH jest ścieżki katalogów gdzie Makefile będzie wyglądać dla plików źródłowych, więc jeśli skompilowanie źródeł w katalogu głównym modules/, interfaces/ i subroutines/, po prostu musisz ustawić w ten sposób VPATH.

Jeśli masz wiele przedmiotów i nie chcesz, aby napisać wszystko ręcznie, można pobrać je za pomocą poniższego sztuczkę

F90 = gfortran 
FFLAGS = -O0 
VPATH = modules:interfaces:subroutines 
SRCOBJ = $(wildcard modules/*f90) 
MODOBJ = $(SRCOBJ:.f90=.o) 

your_executable: $(MODOBJ) main.o 
     $(F90) main.o -o your_executable 
%.o:%.f90 
     $(F90) $(FFLAGS) -c $^ -o [email protected] 

Komenda w Makefile wildcard pozwala użyć jokera *; następnie musisz powiedzieć, że w łańcuchach, które pobierzesz w $(SRCOBJ), chcesz zastąpić .f90 przez .o, aby uzyskać nazwy plików modułów.

+1

+1 Nie wiedziałem o nadpisaniu wielu katalogów 'VPATH' – Yossarian

+0

Dziękuję MBR Twoja makefile ma dla mnie sens. Próbowałem napisać, ale nie mogłem wykonać programu. Problem polega na tym, że mam wszystkie interfejsy utworzone dla kilku podprogramów, a te interfejsy są wymienione w programie Main.f90 za pomocą słowa kluczowego "USE". Podobnie moduły są również używane w Main.f90 za pomocą słowa kluczowego "USE". Ponieważ istnieją duże pliki, w jaki sposób mogę to dynamicznie i połączyć je raczej niż wymieniając każdy plik, jak już wspomniano w odpowiedzi na takie jak MODOBJ = module1.o module2.o ... – user2721314

+0

zobaczyć moje edycji z nadzieją, że odpowiedziami twoje nowe pytanie. – MBR

3

Możesz tworzyć swoje Makefile jak zwykle. Największym problemem powinny być pliki .mod. Najprostszym rozwiązaniem tego problemu jest utworzenie osobnego folderu, w którym te pliki są przechowywane i wyszukiwane.

Można to osiągnąć odpowiednio za pomocą flag -J i -module dla flag gfortran i ifort.

Powiązane problemy