| Zeile 1: | Zeile 1: | ||
{{Stub}} | {{Stub}} | ||
| − | Ein '''Linker''' ist ein Programm, | + | Ein '''Linker''' ist ein Programm, das die vom Compiler generierten Objektdateien mit anderen Objektdateien und/oder Libraries verknüpft. |
== Funktionsweise == | == Funktionsweise == | ||
| − | Beispiel: | + | Ein Beispiel: Das gute, alte "Hello, world!"-Programm soll kompiliert, aber noch nicht gelinkt werden. |
| − | + | <c> | |
| + | #include <stdio.h> | ||
| + | |||
| + | int main() | ||
| + | { | ||
| + | printf("Hello, world!\n"); | ||
| + | } | ||
| + | </c> | ||
| + | |||
| + | Kompilieren kann man das Programm mit folgendem Befehl: | ||
<code> | <code> | ||
| Zeile 12: | Zeile 21: | ||
</code> | </code> | ||
| − | Nun wurde eine Objektdatei erstellt. Diese enthält | + | Das "-c" sorgt dafür, dass der gcc vorerst nur kompiliert und noch nicht linkt. |
| − | + | ||
| + | Nun wurde eine Objektdatei erstellt. Diese enthält zwar bereits den übersetzten Code aus hello.c, aber man könnte sie noch nicht ausführen: | ||
<code> | <code> | ||
| − | hello | + | $ gcc -c -o hello hello.c |
| − | + | $ ./hello | |
| − | + | bash: ./hello: Keine Berechtigung | |
| − | + | $ chmod u+x hello | |
| − | + | $ ./hello | |
| − | + | bash: ./hello: Kann die Datei nicht ausführen. | |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
</code> | </code> | ||
| − | + | Woran liegt das? Nun, wir benutzen in hello.c die Funktion printf() aus stdio.h. Allerdings genügt es nicht, stdio.h einfach zu inkludieren, wie man sieht. Zur Erklärung ein Auszug aus stdio.h: | |
| − | + | <c> | |
| − | + | extern int printf (__const char *__restrict __format, ...); | |
| + | </c> | ||
| + | Die Parameterliste soll uns hier nicht interessieren. Deutlich wichtiger (zumindest im Zusammenhang mit diesem Artikel) ist das Schlüsselwort "extern" vor der eigentlichen Funktionsdeklaration. Dieses Schlüsselwort besagt, dass die Funktion existiert (jedoch nicht in der aktuellen Quelldatei) und beruhigt somit den Compiler, der sonst eine Fehlermeldung oder zumindest eine Warnung ausgegeben hätte, wenn man printf() ohne diese Deklaration verwendet hätte. | ||
| − | + | Nun kommt der Linker ins Spiel. Dessen Aufgabe ist es, die Objektdatei (bzw. in diesem Fall Library), die die Funktion enthält, so mit dem Programm zu verknüpfen, dass die Funktion auch tatsächlich aufgerufen werden kann. Dazu genügt folgender Befehl: | |
| − | |||
| − | |||
| − | |||
<code> | <code> | ||
| − | + | $ gcc -c -o hello.o hello.c | |
| − | + | $ gcc hello.o -o hello | |
| − | + | $ ./hello | |
| − | + | Hello, world! | |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
</code> | </code> | ||
| + | Der gcc ruft selbstständig den Linker mit allen benötigten Libraries auf und erzeugt eine ausführbare Datei, die nun auch die Funktion printf() (sowie alle anderen Funktionen, die in stdio.h als extern deklariert wurden) enthält. | ||
[[Kategorie:Werkzeuge]] | [[Kategorie:Werkzeuge]] | ||
[[en:Linkers]] | [[en:Linkers]] | ||