2013-08-27 5 views
6

Ich bin neu in Fortran. Ich arbeite an einem Forschungsprojekt, bei dem ich ein Open-Source-Projekt verwende, bei dem mehrere Dateien in mehreren Ordnern verteilt sind. Ich habe die Abhängigkeit der einzelnen Programme gefunden, konnte aber nicht herausfinden, wie sie kompiliert werden.Wie kompiliert Multi-Ordner Fortran Projekt mit Schnittstellen, Modulen und Unterprogrammen

Ich habe Quellcode in drei Ordnern verteilt. a) Module b) Schnittstellen c) Subroutinen

Ich möchte ein Programm als ‚Main.f90‘ in Subroutinen Ordner mit dem Namen auszuführen, bietet dieses Programm die Abhängigkeit von Quellcodes von Modulen und Schnittstellen Ordner.

Ich verwende Eclipse für Ordnerstruktur und Makefile zu kompilieren.

Jede Hilfe mit diesem wird geschätzt.

UPDATE: Ich folgte die Antwort gepostet von @MBR und @Stefan, aus irgendeinem Grund nicht in der Lage VPATH haben Programme im Quellcode zu finden, so gab ich ausdrücklich Weg zu jenen Quellordner in meinem Makefile. Unten ist mein Make-Datei-Skript.

.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 

Ich habe alle Module kompiliert und im Modulverzeichnis des Stammordners abgelegt. Alle Kompilierung geht gut. Ich erhalte Fehler, wenn ich die ausführbare Datei erstelle. Ich bekomme folgenden Fehler.

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_ getdat Datei und iargc 'in verwendet wird' ist bereits zusammengestellt. Warum gibt es einen Fehler, wenn die ausführbare Datei eine nicht definierte Referenz erzeugt? Was vermisse ich?

Antwort

6

Sie können ein Makefile tun, die wie die

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 aussieht, ist die Pfade der Verzeichnisse, in denen Sie Ihre Makefile für Quelldateien aussehen wird, wenn Sie also Ihre Quelle im Stammverzeichnis von modules/, kompilieren interfaces/ und subroutines/, müssen Sie einfach VPATH so einrichten.

Wenn Sie viele Objekte haben, und Sie wollen nicht alles von Hand zu schreiben, können Sie abrufen sie den folgenden Trick

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] 

Der wildcard Befehl in einem Makefile ermöglicht es Ihnen, einen Joker zu verwenden *; dann müssen Sie nur sagen, dass in den Strings, die Sie in $(SRCOBJ) abrufen werden, Sie .f90 durch .o ersetzen möchten, um die Dateinamen Ihrer Module zu erhalten.

+1

+1 Ich wusste nicht über geben "VPATH" mehrere Verzeichnisse – Yossarian

+0

Vielen Dank MBR Ihr Makefile macht viel Sinn für mich. Ich habe versucht zu schreiben, konnte aber das Programm nicht durchgehen. Das Problem ist, dass ich alle Schnittstellen für mehrere Subroutinen erstellt habe und diese Schnittstellen im Programm Main.f90 mit dem Schlüsselwort "USE" aufgeführt sind. In ähnlicher Weise werden Module auch in Main.f90 mit dem Schlüsselwort "USE" verwendet. Da gibt es große Dateien, wie ich sie dynamisch aufnehmen und verknüpfen kann, anstatt jede Datei aufzulisten, wie Sie in Ihrer Antwort erwähnt haben wie MODOBJ = module1.o module2.o ... – user2721314

+0

Sehen Sie meine Bearbeitung, die hoffentlich beantwortet deine neue Frage. – MBR

3

Sie können Ihre Makefiles wie gewohnt erstellen. Das größte Problem sollte die .mod Dateien sein. Die einfachste Lösung für dieses Problem besteht darin, einen separaten Ordner zu erstellen, in dem diese Dateien gespeichert und gesucht werden.

Dies kann mit den Flags -J und -module für gfortran bzw. ifort erreicht werden.

Verwandte Themen