Makefile

Zuerst ein paar Bemerkungen zu make und makefiles:

Makefile in Aktion

Wir testen zunächst, ob das zuvor vorgestellte makefile tut was es soll:

$shell> make clean                                                             
rm -f *.o sum_f77 sum_c
$shell> make                                                                   
gfortran -Wall -fimplicit-none -c dsum.f
gfortran -Wall -fimplicit-none -c sumtest.f
gfortran -Wall -fimplicit-none -o sum_f77 dsum.o sumtest.o
gcc-4.8 -Wall -c new_dsum.c
gfortran -Wall -fimplicit-none -o sum_c new_dsum.o sumtest.o
$shell> make  sum_f77                                                          
make: `sum_f77' is up to date.
$shell> make clean                                                             
rm -f *.o sum_f77 sum_c
$shell> make  sum_f77                                                          
gfortran -Wall -fimplicit-none -c dsum.f
gfortran -Wall -fimplicit-none -c sumtest.f
gfortran -Wall -fimplicit-none -o sum_f77 dsum.o sumtest.o
$shell> make                                                                   
gcc-4.8 -Wall -c new_dsum.c
gfortran -Wall -fimplicit-none -o sum_c new_dsum.o sumtest.o
$shell> ./sum_f77                                                              
 X =   1.0000000000000000        4.0000000000000000        9.0000000000000000        16.000000000000000        25.000000000000000        36.000000000000000        49.000000000000000        64.000000000000000        81.000000000000000        100.00000000000000     
 ALPHA = DSUM(10, X, 1) =   385.00000000000000     
 ALPHA = DSUM(5, X, 2) =   165.00000000000000     
 ALPHA = DSUM(5, X(2), 2) =   220.00000000000000     
$shell> ./sum_c                                                                
 X =   1.0000000000000000        4.0000000000000000        9.0000000000000000        16.000000000000000        25.000000000000000        36.000000000000000        49.000000000000000        64.000000000000000        81.000000000000000        100.00000000000000     
 ALPHA = DSUM(10, X, 1) =   385.00000000000000     
 ALPHA = DSUM(5, X, 2) =   165.00000000000000     
 ALPHA = DSUM(5, X(2), 2) =   220.00000000000000     

Fragen/Aufgaben:

Verbessertes Makefile

Das obige Makefile entstand dadurch, dass man das was sonst im Terminal eingetippt wurde einfach ins makefile geschrieben wurde. Wenn man nun aber neue Source Files hinzufügt, dann wird das makefile schnell unübersichtlicher. Zum Glück kann man die Regeln aber auch allgemeiner formulieren:

FC       = gfortran
FFLAGS  += -Wall -fimplicit-none

CC       = gcc-4.8
CFLAGS  += -Wall

all: sum_f77 sum_c

sum_f77: dsum.o sumtest.o
    $(FC) -o sum_f77 dsum.o sumtest.o

sum_c: new_dsum.o sumtest.o
    $(CC) -o sum_c new_dsum.o sumtest.o

%.o : %.c
    $(CC) $(CFLAGS) -c -o $@ $<

%.o : %.f
    $(FC) $(FFLAGS) -c -o $@ $<

clean:
    rm -f *.o sum_f77 sum_c

Interessant sind hier Zeilen in denen Variablen definiert (=) werden bzw. Werte an die Variable hinten angehängt werden (+=)

FC       = gfortran
FFLAGS  += -Wall -fimplicit-none

Und allgemeine Regeln wie zum Beispiel ein Object File foo.o aus einem Fortran Source File foo.f allgemein erzeugt werden soll:

%.o : %.f
    $(FC) $(FFLAGS) -c -o $@ $<

Dabei wird (siehe gnu make):

Ansonsten macht das Makefile das gleiche:

$shell> make -f NewMakefile clean                                              
rm -f *.o sum_f77 sum_c
$shell> make -f NewMakefile                                                    
gfortran -Wall -fimplicit-none -c -o dsum.o dsum.f
gfortran -Wall -fimplicit-none -c -o sumtest.o sumtest.f
gfortran -o sum_f77 dsum.o sumtest.o
gcc-4.8 -Wall -c -o new_dsum.o new_dsum.c
gcc-4.8 -o sum_c new_dsum.o sumtest.o
Undefined symbols for architecture x86_64:
  "__gfortran_set_args", referenced from:
      _main in sumtest.o
  "__gfortran_set_options", referenced from:
      _main in sumtest.o
  "__gfortran_st_write", referenced from:
      _MAIN__ in sumtest.o
  "__gfortran_st_write_done", referenced from:
      _MAIN__ in sumtest.o
  "__gfortran_transfer_array_write", referenced from:
      _MAIN__ in sumtest.o
  "__gfortran_transfer_character_write", referenced from:
      _MAIN__ in sumtest.o
  "__gfortran_transfer_real_write", referenced from:
      _MAIN__ in sumtest.o
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status
make: *** [sum_c] Error 1
$shell> make -f NewMakefile sum_f77                                            
make: `sum_f77' is up to date.
$shell> make -f NewMakefile clean                                              
rm -f *.o sum_f77 sum_c
$shell> make -f NewMakefile sum_f77                                            
gfortran -Wall -fimplicit-none -c -o dsum.o dsum.f
gfortran -Wall -fimplicit-none -c -o sumtest.o sumtest.f
gfortran -o sum_f77 dsum.o sumtest.o
$shell> make -f NewMakefile                                                    
gcc-4.8 -Wall -c -o new_dsum.o new_dsum.c
gcc-4.8 -o sum_c new_dsum.o sumtest.o
Undefined symbols for architecture x86_64:
  "__gfortran_set_args", referenced from:
      _main in sumtest.o
  "__gfortran_set_options", referenced from:
      _main in sumtest.o
  "__gfortran_st_write", referenced from:
      _MAIN__ in sumtest.o
  "__gfortran_st_write_done", referenced from:
      _MAIN__ in sumtest.o
  "__gfortran_transfer_array_write", referenced from:
      _MAIN__ in sumtest.o
  "__gfortran_transfer_character_write", referenced from:
      _MAIN__ in sumtest.o
  "__gfortran_transfer_real_write", referenced from:
      _MAIN__ in sumtest.o
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status
make: *** [sum_c] Error 1

Fragen/Aufgaben: