Tutorial zu Makefiles

Disclaimer: Dieser Thread wurde aus dem alten Forum importiert. Daher werden eventuell nicht alle Formatierungen richtig angezeigt. Der ursprüngliche Thread beginnt im zweiten Post dieses Threads.

Tutorial zu Makefiles
Ich wollte mal fragen ob jemand von euch weiss wo ich mich endlich mal richtig in Makefiles einlesen kann. Ich bin da nie 100 Prozent durchgestiegen, glaube aber dass es jetzt langsam mal Zeit wird. Also das geht insbesondere an die Tutoren und Verantwortlichen, wenn ihr gute Materialien habt immer her damit, koennte mir darueber wuerden sich auch noch viele andere freuen…


https://www.gnu.org/software/make/manual/make.html


Im Internet findet man eine Vielzahl an Tutorials zum Thema Makefile, wie zB. das hier. “Offizielle” Literatur (neben den Uebungsfolien und der schon verlinkten Anleitung) gibt es nicht.

Wir haben das Thema Makefiles heute auch nochmal in unserer SP-Uebungsleiterbesprechung thematisiert, weil wir bei der Korrektur auch sehen, dass Makefiles immer wieder Probleme machen. Allerdings ist uns nicht ganz klar an welcher Stelle es hakt (Sinn und Zweck, Funktionsweise, …) und wissen daher auch nicht, wie wir da gegensteuern koennen.
Es wuerde uns daher helfen, wenn du uns beschreibst, was deine Probleme mit Makefiles sind (gerne auch per Mail oder persoenlich).


Ich melde mich die Tage bei dir mit einer ausfuehrlicheren Mail. Wo es aber schon mal anfaengt ist dass auf den Uebungsfolien gar nicht erklaert ist was das -c bedeutet und wozu es verwendet wird. Bei den Compilerflags ist denke ich jedem klar das wir Makros verwenden muessen, wie das geht steht auf den Folien, kein Problem. Nur was fuer mich immer wieder schwierig war das die Reihenfolge von -c -o und den Flags nicht klar ist heisst es

gcc -c $(CFLAGS) test.c -o test.o oder
gcc -c -o test.o $(CFLAGS) test.c oder
gcc -c $(CFLAGS) test.c -o test.o oder

Und nochmal die Frage braucht man das -c eigentlich, wenn ja was tut es?


Die Reihenfolge der Optionen, die man dem Compiler mitgibt, ist egal (solange sie sich nicht gegenseitig widersprechen).

Ein Tipp: Bei solchen Fragen hilft zuverlässig ein Blick in die Man-Page.


Danke Airhardt! Und was bedeutet es jetzt wenn ich -c weglasse?


Ohne [m]-c[/m] versucht der Compiler eine fertig gelinkte ausführbare ELF-Binärdatei zu erzeugen anstelle einer .o-Zwischendatei.

Wenn man versucht ein Programm, das aus mehreren Modulen (= .c-Dateien) besteht, modulweise so zu übersetzen - also ohne Angabe von [m]-c[/m] - dann probiert der Compiler jedes Modul einzeln zu linken. Das wird fehlschlagen, weil der Linker in den jeweiligen Einzelschritten noch nicht alle Symbole beisammen hat.

Deswegen fährt man üblicherweise folgendes Schema: Zuerst wird jede .c-Quelldatei separat in eine gleichnamige .o-Zwischendatei kompiliert; anschließend werden in einem finalen Schritt diese .o-Dateien zur fertigen ausführbaren Datei zusammengebunden.

Einer der großen Vorteile von Makefiles ist es, dass bei jedem erneuten Aufruf von [m]make[/m] das Kompilieren von .c zu .o nur für diejenigen Quelldateien durchgeführt wird, die sich seit dem letzten Mal geändert haben. Bei großen Projekten bringt das massive Zeitersparnis mit sich!


Hierbei muss man aber noch den Zeitverlust anrechnen, den man durch den Einsatz einer solch archaischen Technologie wie Makefiles erfährt :slight_smile:
Makefiles verursachen bei größeren Projekten leider nur noch Kopfschmerzen, weil sie eben unstruktierte Daten, ja fast Code sind.


Danke fuer den Hinweis mit dem -c, jetzt wird mir einiges klar :slight_smile:


Und jetzt denke man auch noch an den Zeitverlust bei anderen abenteuerlich zerfrickelten Buildsystemen, die auf einer kruden Kombination aus Bash, Ruby, Python und Perl basieren und dann komisch explodieren.


Neulich gesehen: Using Make – writing less Makefile (Diskussion).