Verständnis make
-
Hallo, ich habe ein Verständnisproblem bzgl. der Arbeitsweise von make. Und ich finde diesbezüglich keine Antworten im Internet. Alle Erklärungen scheinen dieses Detail geschickt zu umschreiben

Beispiel
all: main.o
gcc main.o
main.o: main.c main.h
gcc -c main.cSo, was genau prüft make denn da jetzt? Wenn ich "make" aufrufe dann wird beim Target all begonnen und all ist von main.o abhängig.
Make prüft nun NICHT, ob die Datei main.o existiert, oder? Sondern wenn da eine Abhängigkeit steht, dann schaut make nur erstmal, ob es ein TARGET mit dem Namen gibt. Gibt es so ein Target nicht, dann und nur dann, überprüft make, ob die Abhängigkeit eine DATEI ist.
In meinem Fall wird also NIEMALS überprüft, ob eine Datei namens main.o existiert und ob nun gcc main.o ausgeführt wird, hängt nur davon ab, ob der Code (gcc -c main.c) bei main.o ausgeführt wurde. Falls dem so war, so wird rekursiv an all zurückgegeben, dass es eine Änderung gab und deshalb wird nun auch gcc main.o ausgeführt.Das kann aber irgendwie nicht stimmen, weil wenn make bei main.o ist, dann muss er ja irgendwie überprüfen, ob main.o neuer ist als main.c und main.h und nun ist das Target plötzlich eine Datei. Allerdings müssen Targets nicht zwingend eine Datei sein ...
Also ich bin da total verwirrt und ich hoffe ihr wisst was ich meine. Wann wird eine Abhängigkeit und/oder ein Target als Datei betrachtet und wann nicht...
Vielen Dank im Voraus

-
Dieser Thread wurde von Moderator/in SeppJ aus dem Forum C (C89 und C99) in das Forum Compiler- und IDE-Forum verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
Du hast es genau falsch rum:
Target sei all. all ist von main.o abhängig, main.o ist von main.c und main.h abhängig. Ist main.c oder main.h neuer als eine Datei main.o (oder existiert diese gar nicht), so muss main.o nach dem Rezept "gcc -c main.c" neu erzeugt werden. Wenn main.o neuer ist als eine Datei all oder existiert diese gar nicht, so muss all nach dem Rezept "gcc main.o" neu erstellt werden. Letzteres etwas merkwürdige Verhalten resultiert daraus, dass du all nicht PHONY gemacht hast, wodurch es als Datei angesehen wird. Dass durch das Rezept gar keine Datei all erstellt wird, macht make aber gar nichts aus, es wird ja nirgendwo benutzt. Aber wenn du mal eine Datei namens all erstellst, wird das make gründlich verwirren.
-
Vielen Dank für deine Erklärung. Danach habe ich vergeblich gesucht

Und da es keine Targets names main.c und main.h gibt werden diese Abhängigkeiten direkt als Datei betrachtet und es findet der Zeitstempelvergleich mit main.o statt. Wären main.c und main.h aber Targets UND Dateien, dann würde zunächst wieder der Target-Code ausgeführt werden und dann wird erst geschaut, ob main.c und main.h neuer sind als main.o. Sehe ich das richtig?
-
Was mich auch noch verwirrt ist, dass die Abhängigkeiten ja gar nicht als Datei existieren brauchen. Es reicht, wenn es ein zugehöriges Target gibt.
In einem solchen fall wird der zugehörige Code auch immer ausgeführt, oder?
-
Ich glaube, du meinst das richtige. Targets (und Abhängigkeiten) sind erst einmal immer Dateien, es sei denn du sagst explizit, dass dem nicht so sein soll. Die Abhängigkeiten können auch gleichzeitig wieder Targets sein, bei denen dann wieder nach weiteren Abhängigkeiten geschaut wird.
Wenn du also hier noch Targets main.c und main.h hinzufügst, würde beim prüfen von main.o noch eine Ebene weiter gegangen werden und geprüft werden, ob die Abhängigkeiten von main.c und main.h sich verändert haben (oder neu erstellt werden müssen). Dann werden gegebenenfalls die Rezepte von main.h und main.c ausgeführt und dann geht es zurück zum Rezept von main.o und so weiter.
-
Jessyyy schrieb:
Was mich auch noch verwirrt ist, dass die Abhängigkeiten ja gar nicht als Datei existieren brauchen. Es reicht, wenn es ein zugehöriges Target gibt.
In einem solchen fall wird der zugehörige Code auch immer ausgeführt, oder?Effektiv ja. Deswegen funktioniert dein Makefile, obwohl all bei dir nicht PHONY ist. Da keine Datei all existiert, wird das Rezept von all ausgeführt. Da dadurch keine Datei namens all erstellt wird, wird beim nächsten Aufruf wieder das Rezept ausgeführt.
Probier mal folgendes Makefile (ich kann hier im Forum kein Tabzeichen machen, füg es vorm Rezept ein):
all: echo HalloDann kannst du auf der Konsole folgendes beobachten:
[b]ls[/b] Makefile [b]make[/b] Hallo [b]ls[/b] Makefile [b]make[/b] Hallo [b]touch all[/b] [b]ls[/b] all Makefile [b]make[/b] make: `all' is up to date.