2017-01-28 5 views
3

Ich versuche, ein Makefile zu schreiben, das feststellen kann, wann Header geändert wurden, und kompiliert dann die entsprechenden CPP-Dateien erneut. Um dies zu testen, habe ich drei Dateien erstellt: main.cpp, a.h und b.h. main.cpp einschließlich s a.h und a.h enthält b.h.Rekursive Abhängigkeiten zwischen make-Zielen in demselben Makefile

Mein Make-Datei sieht wie folgt aus:

prog: main.cpp a.h 
     g++ main.cpp -o prog 

a.h: b.h 

Wenn eine beliebige Kombination von a.h, b.h und main.cpp geändert wird, erwarte ich prog neu kompiliert werden. Trotzdem wird prog nur dann rekompiliert, wenn a.h oder main.cpp geändert wird, wobei die letzte Zeile scheinbar ignoriert wird.

Was ist ich falsch tun und wie kann ich erreichen, was ich will, ohne so zu jeder einzelnen CPP-Datei des vollständigen und kompletten Satz von Header hinzugefügt (da für größere Projekte könnte dies werden extrem umständlich):

prog: main.cpp a.h b.h 
     g++ ... 
+0

Was ist der Zweck, diese Zeile 'a.h: b.h' hinzuzufügen. Willst du sagen, dass 'a.h' von' b.h' abhängt? Wenn ja, a.h '#inlcude b.h'? – Rishi

+0

Mögliches Duplikat: https://stackoverflow.com/questions/2394609/makefile-header-dependencies https://stackoverflow.com/questions/15857837/compile-headers-dependencies-with-makefile https://stackoverflow.com/ questions/297514/how-can-ich-habe-ein-makefile-automatisch-rebuild-source-files-das-include-a-modi – celtschk

+0

@Rishi Sie haben Recht, dass ah enthält bh – john01dav

Antwort

6

Was bin ich

Ihre Regel falsch machen:

a.h: b.h 

sagt lediglich make dass a.h auf b.h abhängt, das heißt, die a.h zu benötigt werden (wieder) hergestellt, in welcher Weise auch immer make von der Make-Datei bestimmen können, wenn a.h älter als b.h ist oder nicht existiert.

nicht sagen, dass es nicht makewas zu tun a.h von b.h neu zu machen. Ihr Makefile enthält keine Rezept für die Neubildung a.h von b.h. Es enthält nur ein Rezept für remaking prog von main.cpp und a.h, nämlich:

prog: main.cpp a.h 
     g++ main.cpp -o prog 

Außerdem make, hat natürlich keine eingebaute Regel mit einem Rezept für machen a.h von b.h. Also in Abwesenheit von irgendein Rezept für die Herstellung a.h von b.h es nimmt an, dass diese Abhängigkeit benötigt nichts zu tun. Es gibt keinen anderen angemessenen Standard . Selbst wenn a.h älter als b.h ist, wird nichts zu a.h getan; und obwohl prog von a.h abhängt, muss nichts zu prog auf diesem Konto getan werden.

Dies ist ein Glück, denn in der Tat Sie nichta.h wollen jede Art und Weise unabhängig, wenn b.h Änderungen in neu gemacht werden, und Sie wollen nicht main.cpp macht wieder in irgendeiner Art und Weise auch immer, wenn a.h oder b.h zu sein Änderungen. Sie wollen prog zu neu gemacht werden, wenn sich einer von ihnen ändert. Was Sie wollen, ist durch eine der folgenden Makefiles ausgedrückt:

prog: main.cpp a.h b.h 
    g++ main.cpp -o prog 

prog: main.cpp a.h 
    g++ main.cpp -o prog 

prog: b.h 

prog: main.cpp b.h 
    g++ main.cpp -o prog 

prog: a.h 

prog: main.cpp 
    g++ main.cpp -o prog 

prog: a.h b.h 

prog: main.cpp 
    g++ main.cpp -o prog 

prog: a.h 
prog: b.h 

(und einige mehr). Sie sind alle gleichwertig. Sie alle sagen, dass prog hängt auf main.cpp, a.h und b.h und sie alle sagen, was zu tun ist, wenn prog Bedürfnisse neu gemacht, nämlich:

g++ main.cpp -o prog 

wie kann ich erreichen, was ich will, ohne die Zugabe von vollständige und komplette Reihe von Header zu jeder einzelnen CPP-Datei wie diese (da für größere Projekte könnte dies äußerst lästig werden)

In der Tat würde es, und aus diesem Grund haben GCC-Compiler für eine sehr lange Zeit eine Funktion zum Generieren von Mini-Makefiles, die die Abhängigkeit von die Objektdatei, die auf jede der Header-Dateien generiert werden, sind lesen, um die Objektdatei zu erstellen. GNU make kann dieses Feature ausnutzen, um diese Abhängigkeitsdateien zu erzeugen und sie in ein Makefile für den Aufbau von GCC-Zielen einzubeziehen. Diese Kooperation zwischen GCC und make heißt Auto-Abhängigkeit Generation (oder ähnlich). Die Frage, wie es in einem Makefile zu tun ist, ist ein Duplikat von this one und wenn Sie googlen, z. "gcc auto generiert Abhängigkeiten" können Sie auch Guru-Behandlungen finden.

In einem Kommentar schlagen Sie vor, dass Sie mit GNU make noch nicht ausreichend Experten sind those answers zuversichtlich zu sein mit den Auto-Abhängigkeit Erzeugungstechniken dargestellt in.Nun, Sie können beginnen die hängen davon mit einer rudimentären Implementierung so einfach wie diese zu erhalten (was auch die Make-Datei normalere in anderer Hinsicht macht):

Makefile

.PHONY: all clean 

all: prog 

prog: prog.o 

prog.o: main.cpp 
    g++ -MMD -c -o prog.o main.cpp 

prog: prog.o 
    g++ -o prog prog.o 

clean: 
    rm -f prog *.o *.d 

-include prog.d 

-MMD ist die GCC-Präprozessoroption, die die Abhängigkeitsdatei prog.d generiert. Hier ist the documentation of -MMD

prog.d ist eine Mini-Make-Datei:

$ cat prog.d 
prog.o: main.cpp a.h b.h 

alle Abhängigkeiten von prog.o ausdrückt. Das erste Mal, das läuft, die include -ed Make-Datei prog.d nicht existieren, was ein fataler make Fehler sein würde, aber die Tatsache, dass die - Präfix make sagt, dass Fehler zu ignorieren. So make Erlös und alles, einschließlich prog.d werden gemacht, und danach prog.d wird regeneriert werden, wenn eine Regel - einschließlich der Regel in prog.d selbst - prog.o neu kompiliert werden muss.

Verwandte Themen