gnu make, vpath, zusätzliches O-Dateiverzeichnis, Verwirrung

gnu make, vpath, zusätzliches O-Dateiverzeichnis, Verwirrung

Ich versuche, zwei verschiedene Bibliotheken aus Fortran-Quellcode zu erstellen, eine mit OMP-Unterstützung, die andere ohne. Daher unterscheiden sich %.o-Dateien aus derselben Quelle je nach Compiler-Flags. Beim Ändern/Neukompilieren einer Quelldatei benötigt AR immer noch alle O-Dateien, um die Bibliothek neu zu erstellen. Um das Neukompilieren aller Quelldateien zu vermeiden, möchte ich die O-Dateien aus unveränderten Quelldateien in zwei verschiedenen Verzeichnissen speichern, eines mit O-Dateien einschließlich OMP-Unterstützung, das andere ohne. Ich bin froh, dafür Makefiles in dem Verzeichnis zu haben, in dem sich die Bibliotheken schließlich befinden.

Aufgrund des Verhaltens der vpath-Variable kann ich die Bibliothek jedoch nicht mit einem einzigen Befehl neu erstellen. Hier ist die Make-Datei:

   SRC :=
   FORTRAN  = ifort
   OPTSSEQ = -mkl=sequential -DThreadUnSafe -warn nounused -warn declarations -O3 -DTIMEDETAIL
   DRVOPTS  = $(OPTS)
   NOOPT    =
   LOADER   = ifort
   LOADOPTS =
   kernel=$(shell uname -r)
   ARCH     = ar
   ARCHFLAGS= cr
   RANLIB   = ranlib
   LibName=Lib_LM_$(FORTRAN)_$(kernel)_1.0.a
  .SUFFIXES:
  .SUFFIXES: .f90 .o
   include Moduls.mk
   vpath %.f90 src/
   vpath %.o NoOMP/
   OBJS = $(patsubst %.f90,%.o,$(SRC))
   $(LibName): $(OBJS)
      $(ARCH) $(ARCHFLAGS) $@ $?
      $(RANLIB) $@
   %.o : %.f90
      $(FORTRAN) $(OPTSSEQ) -c $? -o $(addprefix NoOMP/,$@)
   clean:
     -rm *.mod
     -rm NoOMP/*.o
     -rm *.smod
     -rm $(LibName)

Dies führt dazu, dass alle %.o-Dateien nach „make clean“ erfolgreich erstellt werden, da alle %.f90-Dateien von src/ gelesen und alle %.o-Dateien nach NoOMP/ geschrieben werden. Das Erstellen des Archivs schlägt jedoch fehl, da das Präfix „NoOMP“ bei den %.o-Dateien gelöscht wird. Daher beschwert sich ar, dass es die %.o-Dateien nicht finden kann. Erst wenn ich „make“ erneut ausführe, wird das Archiv erstellt, da dann %.o-Dateien das Präfix NoOMP haben. Das Hinzufügen eines Präfixbefehls zur Archiverstellungszeile funktioniert einwandfrei, wenn das Archiv von Grund auf neu erstellt wird. Wenn sich jedoch nur eine einzige Datei geändert hat, haben die unveränderten Dateien ein Präfix „NoOMP/NoOMP/“, was erneut zu einem Abbruch führt.

Das ist zwar furchtbar ärgerlich, aber soweit ich das Handbuch verstanden habe, ist das das Standardverhalten von GNU make. Wenn ich falsch liege, wie kann ich das Makefile reparieren, wenn ich richtig liege, wie kann ich dieses Problem umgehen?

Antwort1

Gelöst

die Beispiele funktionieren beim Ändern der Zeile

    $(ARCH) $(ARCHFLAGS) $@ $?

Zu

    $(ARCH) $(ARCHFLAGS) $@ $(addprefix NoOMP/,$?)

Oben hatte ich diese Lösung ausgeschlossen, aber mein Versuch basierte auf $^anstelle von $?. Während die erste das gesamte Archiv aus alten und neuen %.o-Dateien neu aufbaut, aktualisiert die letzte nur das vorhandene Archiv mit neuen %.o-Dateien. Beim Neuaufbau des gesamten Archivs aus alten und neuen %.o-Dateien haben alte %.o-Dateien das falsche Präfix, neue das richtige. Das Ausschließen alter %.o-Dateien durch Aktualisieren des Archivs mit neu kompilierten %.o-Dateien umgeht dieses Problem.

Prost

verwandte Informationen