Fortran: Anhang E
<< zur Fortran-Startseite | |
< Anhang D: Quellcodedokumentation | Anhang F: Photran > |
Einleitung
BearbeitenHier wird keine Einführung in die Verwendung und Syntax von make- und config-Tools geboten, sondern nur kurz auf einige Spezialitäten hingewiesen, die bei den ersten Einsatzversuchen derartiger Werkzeuge im Zusammenhang mit Fortran zu beachten sind.
Grundsätzlich kann bei der Erstellung von Makefiles und Konsorten eine ähnliche Vorgehensweise wie bei konventionellen C-Programmen gewählt werden. Es ist bei Fortran-Programmen jedoch zu bedenken, dass bei Verwendung von Modulen mod
-Dateien generiert werden (ab Fortran 90). Diese mod
-Dateien sind in weiterer Folge für das Kompilieren von moduleinbindenden Quellcodedateien und den Linkvorgang von entscheidender Bedeutung. Somit ist bei hierarchisch verzweigten Quellcodeverzeichnisbäumen Obacht zu geben, dass jeweils auch Zugriff zu diesen mod
-Dateien gegeben ist. Dies kann geschehen durch
- geeigneten Aufbau der Makefiles,
- durch Verwendung von Tools, die solche Abhängkeiten automatisch auflösen
- oder auch durch explizite Bekanntgabe der entsprechenden Pfade an Compiler und Linker.
Explizite Bekanntgabe von Modulpfaden
Bearbeitengfortran
BearbeitenStandardmäßig werden include- und mod-Dateien im aktuellen Verzeichnis gesucht. Die Suche kann aber mit folgendem Compilerschalter auf andere Pfade ausgedehnt werden:
-I...
: Suchpfad für- include-Dateien
- mod-Dateien
- erweitern.
Standardmäßig werden mod-Dateien in das aktuelle Verzeichnis geschrieben. Dieses Verhalten kann mit folgendem Schalter geändert werden:
-J...
: Legt Verzeichnis fest, in das die mod-Dateien geschrieben werden, gleichzeitig auch Suchpfad für mod-Dateien.
- (Alias für
-M...
um Konflikte mit bisherigen GCC-Optionen zu vermeiden)
g95
BearbeitenStandardmäßig werden include- und mod-Dateien im aktuellen Verzeichnis gesucht. Die Suche kann aber mit folgendem Compilerschalter auf andere Pfade ausgedehnt werden:
-I...
: Suchpfad für- include-Dateien
- mod-Dateien
- erweitern.
Auch der g95-Compiler kennt einen -M
-Schalter. Dieser hat aber eine komplett andere Bedeutung als beim gfortran-Compiler. Stattdessen gibt es beim g95-Compiler den Schalter:
-fmod=...
: Legt Verzeichnis fest, in das die mod-Dateien geschrieben werden, gleichzeitig auch Suchpfad für mod-Dateien.
ifort
Bearbeiten-I...
: Suchpfad für- include-Dateien
- mod-Dateien
- erweitern.
-module ..
: Legt Verzeichnis fest, in das die mod-Dateien geschrieben werden, gleichzeitig auch Suchpfad für mod-Dateien.
Sun f90/f95
Bearbeiten-M...
: Fügt den angegebenen Pfad zum Modulsuchpfad hinzu.–moddir=...
: mod-Dateien werden in das angegebene Verzeichnis geschrieben, gleichzeitig auch Suchpfad für mod-Dateien.
GNU Make
BearbeitenGNU Make erkennt derzeit leider nur FORTRAN 77-Dateien mit der Endung .f automatisch. Für "free source form"-Fortran-Programme sind daher einige vorbereitende Arbeiten nötig, um dann auch die Vorteile (und Nachteile) der impliziten Anwendung von "Pattern Rules" genießen zu dürfen. Werden alle Makeschritte für Fortran-Dateien explit vorgegeben, dann kann man sich dies natürlich sparen.
Ein einfaches Beispiel
BearbeitenEs sei ein einfaches Beispiel gegeben, das eine FORTRAN 77-, eine Fortran 2003- und eine C-Datei enthält. Diese Dateien liegen im selben Verzeichnis.
Quellcode-Dateien
Bearbeitenmain.f03:
Fortran 2003 (oder neuer)-Code |
! Das Hauptprogramm program main implicit none interface function addition( a, b ) bind( c ) use, intrinsic :: iso_c_binding real( kind = c_float ), value :: a real( kind = c_float ), value :: b real( kind = c_float ) :: addition end function addition subroutine sub() end subroutine sub end interface call sub() write (*,*) addition( 2.5, 3.3 ) ! Ausgabe: ! Summe = ! 5.8 end program main |
func.c:
Programmcode |
/* Addiere zwei Zahlen */ float addition(float a, float b) { return (a + b); } |
sub.f:
0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 12345678901234567890123456789012345678901234567890123456789012345678901234567890 |
C Eine einfache FORTRAN 77-Subroutine SUBROUTINE SUB WRITE( *, * ) 'Summe =' END |
12345678901234567890123456789012345678901234567890123456789012345678901234567890 0 . | 1 . 2 . 3 . 4 . 5 . 6 . 7 | . 8 |
Explizite Vorgabe der Makeschritte
BearbeitenMakefile:
FC = gfortran # oder g95, ifort, ... prog: main.o func.o sub.o $(FC) -o $@ $^ main.o: main.f03 $(FC) -c $^ func.o: func.c $(CC) -c $^ sub.o: sub.f $(FC) -c $^
Nutzung von "Pattern Rules"
BearbeitenMakefile:
FC = gfortran # oder g95, ifort, ... %.o: %.f03 $(FC) -c $< prog: main.o func.o sub.o $(FC) -o $@ $^
Die Generierung der Objektdateien aus den Quellcodedateien geschieht hier implizit. Für C- und FORTRAN 77-Dateien sucht sich GNU Make die entsprechenden Regeln aus seiner internen Regel-Datenbank. Für .f03-Dateien wurde der entsprechende Befehl hier von uns explizit durch eine "Pattern Rule" vorgegeben.
Die make-Ausgabe sieht so aus:
gfortran -c main.f03 cc -c -o func.o func.c gfortran -c -o sub.o sub.f gfortran -o prog main.o func.o sub.o
Solange die Quelldateien im selben Verzeichnis liegen, ist die Erstellung eines Makefiles ziemlich einfach. Wenn aber die Quelldateien gestaffelt in Unterverzeichnissen gespeichert sind und womöglich noch Abhängigkeiten von einem Unterverzeichis zum anderen gegeben sind, dann kann die ganze Sache ziemlich kompliziert werden. Im Anschluss wird eine einfache nichtrekursive Make-Variante gezeigt.
Nichtrekursive Make-Variante
BearbeitenVor der Programmerstellung:
-- (D) projektverzeichnis |-- (F) Makefile |-- (F) module.mk |-- (F) main.f90 | |-- (D) kreis | |-- (F) module.mk | |-- (F) kreis.f90 | |-- (F) kreissegment.f90 | |-- (D) quadrat | |-- (F) module.mk | |-- (F) quadrat.f90 (D) ... directory (F) ... file
Nach der Programmerstellung durch Aufruf von make
:
-- (D) projektverzeichnis |-- (F) Makefile |-- (F) module.mk |-- (F) main.f90 |-- (F) main.o |-- (F) prog |-- (F) kreis.mod |-- (F) kreissegment.mod |-- (F) quadrat.mod | |-- (D) kreis | |-- (F) module.mk | |-- (F) kreis.f90 | |-- (F) kreissegment.f90 | |-- (F) kreis.o | |-- (F) kreissegment.o | |-- (D) quadrat | |-- (F) module.mk | |-- (F) quadrat.f90 | |-- (F) quadrat.o
Quellcode-Dateien
Bearbeitenmain.f90:
Fortran 90/95-Code (free source form) |
program main use kreis use kreissegment use quadrat implicit none call k() call q() call ks() end program main |
kreis/kreis.f90:
Fortran 90/95-Code (free source form) |
module kreis implicit none private public :: k contains subroutine k() print *, "Ich bin ein Kreis!" end subroutine k end module kreis |
kreis/kreissegment.f90:
Fortran 90/95-Code (free source form) |
module kreissegment use kreis implicit none private public :: ks contains subroutine ks() call k() print *, "Hihi, war nur ein Scherz. Ich bin ein Kreissegment!" end subroutine ks end module kreissegment |
quadrat/quadrat.f90:
Fortran 90/95-Code (free source form) |
module quadrat implicit none private public :: q contains subroutine q() print *, "Ich bin ein Quadrat!" end subroutine q end module quadrat |
Makefile, Include-Dateien
BearbeitenMakefile:
FC := g95 SRC := OBJ = $(subst .f90,.o,$(SRC)) %.o: %.f90 $(FC) -c -o $@ $< include kreis/module.mk include quadrat/module.mk include module.mk prog: $(OBJ) $(FC) -o $@ $^
module.mk:
SRC += main.f90
kreis/module.mk:
SRC += kreis/kreis.f90 kreis/kreissegment.f90
quadrat/module.mk:
SRC += quadrat/quadrat.f90
Es gibt nur ein Makefile im Projekthauptverzeichnis. Sämtliche unterverzeichnisspezifischen Details (hier nur die Bekanntgabe der Quellcodedateien) werden in den jeweiligen Unterverzeichnissen in eigenen Include-Dateien (.mk) festgelegt und in das Makefile eingebunden. Da, anders als beim rekursiven Make, nicht in die einzelnen Unterverzeichnisse gewechselt wird, werden allfällige mod-Dateien auch nur in das Projekthauptverzeichnis (= das aktuelle Verzeichnis) geschrieben.
Weiterführende Make-Infos
BearbeitenCMake
BearbeitenCMake ist kein Make-Klon, sondern ein moderner Autotools-Ersatz.
Gleiches Beispiel wie bei [1], es muss in diesem Fall nur eine CMakeLists.txt
-Datei im Projekthauptverzeichnis erstellt werden. Makefile und dazugehörende Dateien werden automatisch beim cmake
-Aufruf erstellt.
CMakeLists.txt:
PROJECT(bsp Fortran) SET(src main.f90 kreis/kreis.f90 kreis/kreissegment.f90 quadrat/quadrat.f90 ) ADD_EXECUTABLE(prog ${src})
Generieren der Makefiles, etc.:
FC=g95 cmake .
-- Check for working Fortran compiler: /xyz/bin/g95 -- Check for working Fortran compiler: /xyz/bin/g95 -- works -- Checking whether /xyz/bin/g95 supports Fortran 90 -- Checking whether /xyz/bin/g95 supports Fortran 90 -- yes -- Configuring done -- Generating done -- Build files have been written to: /abc/projektverzeichnis
Mittels FC=...
wird der zu verwendende Fortran-Compiler festgelegt. Wenn irgendein auf dem System installierter Fortran-Compiler verwendet werden soll, kann diese Vorgabe auch entfallen. In der CMakeLists.txt
muss die Programmiersprache Fortran ausdrücklich aktiviert werden. Entweder wie hier im PROJECT
-Statement oder alternativ auch über die ENABLE_LANGUAGE
-Anweisung.
Programmerstellung:
make
Scanning dependencies of target prog [ 25%] Building Fortran object CMakeFiles/prog.dir/kreis/kreis.o [ 50%] Building Fortran object CMakeFiles/prog.dir/kreis/kreissegment.o [ 75%] Building Fortran object CMakeFiles/prog.dir/quadrat/quadrat.o [100%] Building Fortran object CMakeFiles/prog.dir/main.o Linking Fortran executable prog
CMake (2.4-patch 7) erkennt nur Dateien mit den Endungen f, F, ,f77, F77, f90, F90, for, f95 und F95, jedoch keine mit f03 oder F03.
CMake-Homepage:
SCons
Bearbeiten<< zur Fortran-Startseite | |
< Anhang D: Quellcodedokumentation | Anhang F: Photran > |