Lässt es sich mit cremefarbenem Papier, einer Tönung, mehr Kontrast oder größerer Schrift besser lesen? Wählen Sie Ihre Farben und Ihre Schrift, einmalig für alle Seiten.

Kostenlose Lektion

Vom Quelltext zum lauffähigen Programm (gcc)

Nach dieser Lektion: Ich kann die Phasen nennen, die ein Compiler mit einem Programm durchläuft.

Lektion, 50 Min.9 BefehleLab für Compilerbau und Rechnerarchitektur: gcc, flex, bison und RISC-V in einer VM

Der Fehler kam ganz am Ende

Das neue Kassenprogramm einer Bäckereikette lässt sich nicht bauen. Die Meldung lautet undefined reference to printf. Eine Kollegin liest daraufhin den C-Code Zeile für Zeile durch.

Der Code ist in Ordnung. Die Meldung stammt aus dem letzten Schritt des Builds, und der liest den Code gar nicht. Wer die Schritte kennt, sucht an der richtigen Stelle.

Am Ende dieser Lektion

Notiz

Ich kann die Phasen nennen, die ein Compiler mit einem Programm durchläuft.

Schlüsselwörter

BegriffWas er bedeutetBeispiel
Compilertreiberein Programm, das die anderen Werkzeuge der Reihe nach startetgcc
Präprozessordie Phase, die Dateien einfügt und Makros ersetzt
Assemblerdas Programm, das Assemblercode in Maschinencode übersetztas
ObjektdateiMaschinencode, der noch kein ganzes Programm isthello.o
Symbolein Name, den der Linker finden muss, etwa eine Funktion
Linkerdas Programm, das Objektdateien und Bibliotheken verbindetld

Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.

gcc startet andere Programme

Wenn Sie gcc hello.c tippen, übersetzt gcc selbst fast nichts. gcc ist ein Compilertreiber. Er startet andere Programme nacheinander und reicht die Datei des einen an das nächste weiter.

Mit der Option -### gibt gcc diese Befehle nur aus und führt keinen davon aus. Die zwei Befehle unten zeigen davon nur das Programm, mit dem jeder Befehl beginnt. Vergleichen Sie die beiden Listen.

In den Ordner compiler wechseln

Befehl
cd ~/compiler

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Was gcc für -c starten würde

Befehl
gcc -### -c hello.c 2>&1 | grep "^ " | cut -d " " -f 2

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Was gcc für ein ganzes Programm startet

Befehl
gcc -### -o hello hello.c 2>&1 | grep "^ " | cut -d " " -f 2

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Beispiel: drei Programme, vier Phasen

ProgrammPhasenErgebnis
cc1Vorverarbeiten, dann kompilierenAssemblercode, eine .s-Datei
asAssemblierenEine Objektdatei, .o
collect2Binden, indem es ld startetDas fertige Programm

Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.

Die Datei jeder Phase behalten

Normalerweise landen die Zwischendateien in einem temporären Ordner und werden danach gelöscht. Die Option -save-temps legt sie neben den Quelltext.

Ein Build hinterlässt dann vier Dateien: hello.i nach dem Vorverarbeiten, hello.s nach dem Kompilieren, hello.o nach dem Assemblieren und hello nach dem Binden. Der Befehl file liest den Anfang jeder Datei und nennt ihre Art.

Einmal bauen, alles behalten

Befehl
gcc -save-temps -o hello hello.c

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Welche Art Datei ist jede?

Befehl
file hello.i hello.s hello.o hello

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Das Ende des vorverarbeiteten Codes

Befehl
gcc -E hello.c | tail -n 4

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Beispiel: was file gesagt hat

DateiErzeugt vonWas file meldet
hello.idem PräprozessorC source, ASCII text
hello.sdem Compilerassembler source, ASCII text
hello.odem AssemblerELF 64-bit LSB relocatable
hellodem LinkerELF 64-bit LSB pie executable

Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.

Eine Objektdatei hat Lücken

hello.o enthält den Maschinencode für square und main. Aber main ruft printf auf, und printf steht nicht in dieser Datei. Es liegt in der C-Bibliothek.

nm listet die Symbole einer Objektdatei. T heißt: Der Code ist hier. U heißt undefiniert, also eine Lücke für den Linker.

Starten Sie danach den Linker ld selbst, ohne C-Bibliothek. Lesen Sie, was er meldet.

Die Symbole in hello.o

Befehl
nm hello.o

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Ohne Bibliothek binden

Befehl
ld hello.o -o kaputt

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Ein häufiger Fehler

Warnung

Viele halten jeden Build-Fehler für einen Fehler im eigenen Code. Ein undefined reference meldet der Linker, nachdem der Code sauber kompiliert wurde. Dem letzten Schritt fehlt der Code eines Symbols. Prüfen Sie also, was gebunden wird, nicht die Zeile in C.

Woher printf kommt

Befehl
ldd hello

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Weiterführend

Tippen Sie diese Befehle selbst. Erzeugen Sie mit sed 's/square(7)/doppelt(7)/' hello.c > doppelt.c eine Kopie, in der eine Funktion doppelt aufgerufen wird, die es nirgends gibt. Bauen Sie mit gcc -c doppelt.c und sagen Sie, welche Phase sich meldet.

Fügen Sie dann über main die Zeile int doppelt(int n); ein. Bauen Sie erneut mit gcc -c, lesen Sie nm doppelt.o und bauen Sie zuletzt mit gcc doppelt.c. Erklären Sie, warum die zwei Fehler aus verschiedenen Phasen kommen.

Über dieses Lab und seinen Quellcode: Lab für Compilerbau und Rechnerarchitektur: gcc, flex, bison und RISC-V in einer VM

Sie unterrichten eine Gruppe? Weisen Sie dieses Modul Ihren Studierenden zu, mit Handbuch für Lehrende, automatisch geprüften Aufgaben und einem Lab für jede Person.