Fortran: Anhang E
| << zur Fortran-Startseite | |
| < Anhang D: Quellcodedokumentation | Anhang F: Style Guides > |

Einleitung
[Bearbeiten]Hier 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
[Bearbeiten]gfortran
[Bearbeiten]Standardmäß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)
ifx
[Bearbeiten]-I...: Suchpfad für- include-Dateien
- mod-Dateien
- erweitern.
GNU Make
[Bearbeiten]GNU 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
[Bearbeiten]Es 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
[Bearbeiten]main.f90:
| 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
[Bearbeiten]Makefile:
FC = gfortran # oder ifx, ... prog: main.o func.o sub.o $(FC) -o $@ $^ main.o: main.f90 $(FC) -c $^ func.o: func.c $(CC) -c $^ sub.o: sub.f $(FC) -c $^
Nutzung von "Pattern Rules"
[Bearbeiten]Makefile:
FC = gfortran # oder ifx, ... %.o: %.f90 $(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 .f90-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
[Bearbeiten]Vor 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
[Bearbeiten]main.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
[Bearbeiten]Makefile:
FC := gfortran # oder ifx, ... 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
[Bearbeiten]- GNU Make Manual
- Robert Mecklenburg: Managing Projects with GNU Make, O'Reilly Openbook, 2004
- Peter Miller: Recursive Make Considered Harmful, 2006
CMake
[Bearbeiten]CMake ist kein Make-Klon, sondern ein moderner Autotools-Ersatz.
Gleiches Beispiel wie bei #Nichtrekursive_Make-Variante, 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=gfortran 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-Homepage:
SCons
[Bearbeiten]Die Konfigurations-Dateien von SCons sind Python-Dateien.
Ein einfaches Beispiel
[Bearbeiten]Gegeben seien die weiter oben gelisteten Dateien kreis/kreis.f90 kreis/kreissegment.f90 quadrat/quadrat.f90 main.f90.
Um dieses Beispiel zu bauen, erstellt man im Quellcode-Verzeichnis zuerst eine SConstruct-Datei, z.B.:
src_files = Split('kreis/kreis.f90 kreis/kreissegment.f90 quadrat/quadrat.f90 main.f90')
Program('prog', src_files)
Dann startet man scons in einer Konsole (zuvor natürlich, wenn noch nicht geschehen, in das entsprechende Quellcode-Verzeichnis wechseln) und erhält z.B. folgende Ausgabe:
scons: Reading SConscript files ... scons: done reading SConscript files. scons: Building targets ... gfortran -o kreis/kreis.o -c kreis/kreis.f90 gfortran -o kreis/kreissegment.o -c kreis/kreissegment.f90 gfortran -o quadrat/quadrat.o -c quadrat/quadrat.f90 gfortran -o main.o -c main.f90 gfortran -o prog kreis/kreis.o kreis/kreissegment.o quadrat/quadrat.o main.o scons: done building targets.
Gestartet wird das erstellte Programm in diesem Beispiel mittels ./prog. Ausgabe:
Ich bin ein Kreis! Ich bin ein Quadrat! Ich bin ein Kreis! Hihi, war nur ein Scherz. Ich bin ein Kreissegment!
Bereinigt werden kann das Verzeichnis (oder können die Verzeichnisse) mit scons -c. Als Ausgabe erscheint dann in der Konsole:
scons: Reading SConscript files ... scons: done reading SConscript files. scons: Cleaning targets ... Removed kreis/kreis.o Removed kreis.mod Removed kreis/kreissegment.o Removed kreissegment.mod Removed main.o Removed quadrat/quadrat.o Removed quadrat.mod Removed prog scons: done cleaning targets.
Das wars. Für weiterführende Informationen siehe die nachfolgenden Weblinks.
Weblinks
[Bearbeiten]| << zur Fortran-Startseite | |
| < Anhang D: Quellcodedokumentation | Anhang F: Style Guides > |