machen, include-Direktive und Generierung von Abhängigkeiten mit -MM
Möchte ich eine build Regel ausgelöst werden durch eine include-Anweisung, wenn das Ziel der include ist veraltet oder nicht vorhanden ist.
Derzeit das makefile sieht wie folgt aus:
program_NAME := wget++
program_H_SRCS := $(wildcard *.h)
program_CXX_SRCS := $(wildcard *.cpp)
program_CXX_OBJS := ${program_CXX_SRCS:.cpp=.o}
program_OBJS := $(program_CXX_OBJS)
DEPS = make.deps
.PHONY: all clean distclean
all: $(program_NAME) $(DEPS)
$(program_NAME): $(program_OBJS)
$(LINK.cc) $(program_OBJS) -o $(program_NAME)
clean:
@- $(RM) $(program_NAME)
@- $(RM) $(program_OBJS)
@- $(RM) make.deps
distclean: clean
make.deps: $(program_CXX_SRCS) $(program_H_SRCS)
$(CXX) $(CPPFLAGS) -MM $(program_CXX_SRCS) > make.deps
include $(DEPS)
Das problem ist, dass es scheint, wie die include-Anweisung ausgeführt wird, bevor die Regel zu bauen machen.deps, die effektiv bedeutet, dass die machen ist entweder immer keine Liste von Abhängigkeiten, wenn machen.deps nicht vorhanden ist oder immer das machen.Highsider aus dem vorherigen build und nicht die aktuellen.
Beispiel:
$ make clean
$ make
makefile:32: make.deps: No such file or directory
g++ -MM addrCache.cpp connCache.cpp httpClient.cpp wget++.cpp > make.deps
g++ -c -o addrCache.o addrCache.cpp
g++ -c -o connCache.o connCache.cpp
g++ -c -o httpClient.o httpClient.cpp
g++ -c -o wget++.o wget++.cpp
g++ addrCache.o connCache.o httpClient.o wget++.o -o wget++
Bearbeiten
Lese ich die docs für die include-Direktive, und es klingt, wie wenn der gehören Ziel nicht existiert, wird es weiterhin die Bearbeitung der übergeordneten makefile versuchen Sie und bauen Sie das Ziel, aber es ist nicht ganz klar zu mir, wie das funktioniert:
Wenn eine mitgelieferte makefile nicht
in jedem dieser Verzeichnisse ein
Warnmeldung generiert, aber es
ist nicht sofort ein fataler Fehler;
die Verarbeitung des makefile mit
das zählen geht weiter. Einmal hat es
fertig gelesen makefiles machen wird
versuchen, remake, sind veraltet
bestehen oder nicht bestehen. Siehe Abschnitt Wie
Makefiles Sind Erneuert. Erst nach
hat versucht, einen Weg zu finden, remake
makefile und fehlgeschlagen sind, wird
diagnostizieren das fehlende makefile als
schwerwiegender Fehler.
ANTWORT
Dies ist eine Modifikation die Antwort, die ich akzeptiert. Das einzige, was fehlt war, dass die Abhängigkeit-Dateien auch abhängig von den Quellen, und werden nicht erhalten, regeneriert, es sei denn, Sie sind auf der deps-Dateien, die enthalten:
%.d: $(program_CXX_SRCS)
@ $(CXX) $(CPPFLAGS) -MM $*.cpp | sed -e 's@^\(.*\)\.o:@\1.d \1.o:@' > $@
sed
fügt den Namen des .d
- Datei an den Anfang jeder Abhängigkeit Zeile etwa so:
foo.d foo.o: foo.cpp foo.h bar.h baz.h
Ich habe die Idee von diesem erstaunlichen Papier auf die Gefahren des rekursiven machen:
Recursive Make Considered Harmful
Ich auch fügen Sie folgenden makefile:
clean_list += ${program_SRCS:.c=.d}
# At the end of the makefile
# Include the list of dependancies generated for each object file
# unless make was called with target clean
ifneq "$(MAKECMDGOALS)" "clean"
-include ${program_SRCS:.c=.d}
endif
- Sie sollten wahrscheinlich betrachten Sie dies, falls Sie es noch nicht: Theorie.uwinnipeg.ca/localfiles/infofiles/machen/...
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sie sich auf eine implizite Regel zu kompilieren .cpp-Dateien. Sie müssen neu definieren, es zu verwenden -MM und MF-flags, werden die Abhängigkeitsdatei erstellen.
Dann haben Sie, um diese Abhängigkeiten Dateien in das Makefile, mit
-include
dass nicht Fehler bei den Abhängigkeiten von Dateien existieren noch nicht (beim ersten mal oder nach einem sauberen).Und denken Sie daran, fügen Sie den rm-Befehl für die Abhängigkeiten der Dateien in der Regel sauber.
.d
Dateien im clean-Regel, als dieinclude
- Anweisung wird nur dazu führen, dass Sie regeneriert werden.Einem wichtigen Punkt, es nahm mich eine Weile, um zu begreifen, dass die stellen.Highsider aus dem vorherigen build sind gut genug. Denken Sie daran: für eine gegebene Objekt-Datei, die einzige Möglichkeit, die Liste der Abhängigkeitsdateien ändern kann, wenn... man von der alten Abhängigkeit-Dateien verändert wurde. Und wenn das der Fall ist, dann sind die alten machen.deps wird dazu führen, dass Objekt-Datei neu erstellt werden, und wenn eine Wiederherstellung der Objekt-Datei auch Umbauten machen.deps, dann ist alles up to date. Sie haben nicht zu rebuild machen.deps, bevor Sie prüfen, welche Objekte neu erstellt werden müssen.
Den include-Direktiven Arbeit tun, wie Sie in C und C++ - Sie verarbeitet werden, bevor irgendetwas anderes passiert, um den Bau des "echten" makefile, das machen dann die Prozesse. Insbesondere sind Sie verarbeitet, bevor alle Regeln, die ausgelöst werden.