2016-07-14 5 views
1

Ich verwende ein Makefile einschließlich einer Regel, um eine Abhängigkeitsdatei zu erstellen. Der Compiler ist GCC.Erstellen Sie Abhängigkeitsdateien in Makefile

%.d: %.c 
    mkdir -p $(@D) 
    $(CC) $(CFLAGS) $(CPPFLAGS) -M $< | \ 
    sed 's,\($(notdir $*)\.o\) *:,$(dir [email protected])\1 [email protected]: ,' > [email protected] 
    mv [email protected] [email protected] 

Ich bin ganz neu in Makefile-Technik, und ich finde es ein wenig schwierig, diese Regel aus einer Mischung von mehreren Optionen bestehen zu verstehen.
Kann jemand eine einfache Erklärung geben, wie diese Regel funktioniert? Vielen Dank im Voraus.

Antwort

2

%.d: %.c

Alle Dateien, die auf .d können, solange es eine .c Datei mit dem gleichen Verzeichnis mit dieser Regel gemacht werden und in dem aktuellen Verzeichnis oder eine der vpaths relativ stammen.

mkdir -p $(@D)

Erstellen Sie die oberste und alle Zwischenverzeichnisse für $(@D), die ein automatisch make Variable, die in das Verzeichnis Teil des aktuellen Ziels erweitert.

$(CC) $(CFLAGS) $(CPPFLAGS) -M $< | \

Rufen Sie den C-Compiler auf die erste Voraussetzung (whatever.c) und sagen, dass es eine Liste von Make-Abhängigkeiten auf die Standardausgabe ausgegeben wird. Rohr dieser Ausgang

sed 's,\($(notdir $*)\.o\) *:,$(dir [email protected])\1 [email protected]: ,' > [email protected]

sed. Die Regeln in der Ausgabe haben den gleichen Pfad wie die Quelldateien, aber wer auch immer diese Regel geschrieben hat, möchte die Objektdateien in einem anderen Verzeichnis haben, also brauchen wir sed, um die Pfade zu ersetzen.

Sed erfasst alle Regeln mit Zielen, die mit .o enden, die mit $(notdir $*) übereinstimmen. $* ist eine weitere automatische Variable, die auf das Muster erweitert wird, das % in der aktuellen Regel entspricht, und notdir entfernt alle Verzeichnis-Teile, so dass Sie mit dem Dateinamen-Stamm ohne Erweiterung bleiben.

Sed prepends dann $(dir [email protected]) auf die Objektdatei Ziel, das dasselbe ist wie $(@D) wir oben gesehen haben, und fügt die Abhängigkeitsdatei selbst ([email protected]) als Ziel der gleichen Voraussetzungen. Diese Ausgabe wird in eine Datei mit dem Namen des aktuellen Ziels + .tmp umgeleitet.

mv [email protected] [email protected]

Verschiebt die vorherige Datei an das eigentliche Ziel der Regel.


Randbemerkung:

sources := src/somefile1.c src/somefile2.c 
objects := $(sources:src/%.c=obj/%.o) 
deps := $(objects:.o=.d) 

CFLAGS := -MMD -MP 

.PHONY: all 
all $(objects) 

$(objects): obj/%.o: src/%.c 
    $(COMPILE.c) $(OUTPUT_OPTION) $< 

-include $(deps) 
: Wenn Sie im selben Verzeichnis wie die Objektdateien dann diese Rezepte sind veraltet erzeugt nicht die Abhängigkeitsdateien kümmern wird, können Sie die gleiche Sache mit so etwas wie erreichen
+0

Ausgezeichnet. Danke! – Gaston