CS107 Kompilieren von C-Programmen mit GCC

Aufgeschrieben von Chris Gregg, mit Änderungen von Nick Troccoli

Klicken Sie hier für ein Video zur Vorgehensweise.

Der Compiler, den wir für CS107 verwenden werden, heißt „GNU Compiler Collection“ (gcc). Er ist einer der am weitesten verbreiteten Compiler, und er ist sowohl Freie Software als auch auf vielen verschiedenen Computerplattformen verfügbar.

gcc führt den Schritt der Kompilierung durch, um ein Programm zu erstellen, und ruft dann andere Programme auf, um das Programm zusammenzusetzen und die Bestandteile des Programms zu einem ausführbaren Programm zu verbinden, das Sie ausführen können. Wir werden in CS107 ein wenig über jeden dieser Schritte lernen, aber das Schöne ist, dass gcc das gesamte ausführbare (lauffähige) Programm mit einem einzigen Befehl erzeugen kann.

In CS107 werden wir überwiegend Makefiles verwenden, um unseren Code zu kompilieren, zusammenzusetzen und zu linken, aber das Makefile führt gcc aus, um die Arbeit zu erledigen. This is just a quick overview on how to compile and run your own programs should you decide to do so without a Makefile.

The simplest way to run gcc is to provide gcc a list of .c files:

$ gcc hello.c$

Note that you do not put header files (.h) into the gcc command: it reads in the header files as it compiles, based on the #include statements inside .c files.

If the program compiled without errors or warnings, you don’t get any output from gcc, and you will have a new file in your directory, called a.out. To run this file, you need to tell the shell to run the file in the current directory, by using ./ before the name:

$ ./a.outHello, World!$

Wir wollen in der Regel nicht, dass unsere Programme a.out heißen, also können Sie gcc eine Option geben, -o programName, um der Shell mitzuteilen, wie sie die ausführbare Datei nennen soll:

$ gcc hello.c -o hello$ ./helloHello, World!$

Hinweis: Achten Sie darauf, dass Sie nicht versehentlich einen Namen für die ausführbare Datei eingeben, der mit dem Namen der Eingabedatei übereinstimmt – etwa so:

$ gcc hello.c -o hello.c

Auf myth wurde Ihr Profil so eingerichtet, dass der Fehler abgefangen und nicht kompiliert wird, so dass Ihre Quelldatei erhalten bleibt. Das ist auf vielen anderen Linux-Systemen nicht der Fall, also seien Sie vorsichtig! Auf anderen Systemen würde GCC Ihre Quelldatei mit der neuen ausführbaren Datei überschreiben.

gcc nimmt viele verschiedene Kommandozeilenoptionen (Flags) an, die sein Verhalten ändern. Eine der gebräuchlichsten Optionen ist die Option „Optimierungsstufe“, -O (Großbuchstabe ‚o‘). gcc hat die Fähigkeit, Ihren Code für verschiedene Situationen zu optimieren.

  1. -O oder -O1: Optimieren. Eine optimierte Kompilierung benötigt etwas mehr Zeit und bei einer großen Funktion auch viel mehr Speicher. Mit -O versucht der Compiler, die Größe des Codes und die Ausführungszeit zu reduzieren, ohne irgendwelche Optimierungen durchzuführen, die viel Kompilierungszeit benötigen.
  2. -O2: Optimiere noch mehr. GCC führt fast alle unterstützten Optimierungen durch, die nicht mit einem Kompromiss zwischen Platz und Geschwindigkeit verbunden sind. Im Vergleich zu -O erhöht diese Option sowohl die Kompilierungszeit als auch die Leistung des generierten Codes.
  3. -O3: Optimiere noch mehr. -O3 schaltet alle Optimierungen ein, die durch -O2 angegeben wurden, und schaltet auch andere Optimierungen ein. Dies ist oft die beste Option, die man verwenden kann.
  4. -O0: Reduziert die Kompilierungszeit und sorgt dafür, dass die Fehlersuche die erwarteten Ergebnisse liefert. Dies ist die Standardeinstellung.
  5. -Os: Optimiere für die Größe. -Os aktiviert alle -O2 Optimierungen, die die Codegröße normalerweise nicht erhöhen. Es führt auch weitere Optimierungen durch, die die Codegröße verringern sollen.
  6. – Schnell: Ignoriert die strikte Einhaltung von Standards. -Ofast aktiviert alle -O3 Optimierungen. Es aktiviert auch Optimierungen, die nicht für alle standardkonformen Programme gültig sind.
  7. -Og: Optimiert die Debugging-Erfahrung. -Og ermöglicht Optimierungen, die die Fehlersuche nicht beeinträchtigen. Es sollte die Optimierungsstufe der Wahl für den Standard-Edit-Compile-Debug-Zyklus sein, die ein vernünftiges Maß an Optimierung bietet und gleichzeitig eine schnelle Kompilierung und eine gute Debugging-Erfahrung gewährleistet. Wir werden -Og in CS107 verwenden, wenn wir debuggen.

Siehe die man Seite für gcc für weitere Details zur Optimierung (oder siehe hier für weitere Informationen über Optimierungen).

Ein weiteres gängiges Flag ist die -std=gnu99-Option, die gcc anweist, die „gnu c-Version des c-Standards von 1999“ zu verwenden. Der Standard bietet eine Syntax, die es ermöglicht, eine Variable innerhalb einer for-Schleifen-Deklaration zu definieren (z.B. for (int i = ...). Wir werden diesen Standard in CS107 verwenden.

Wir werden auch das -g-Flag verwenden, das es uns ermöglicht, den Debugger gdb zu verwenden, um uns genaue Zeilennummern in unserem Code zu geben, wenn wir ihn ausführen.

Beispiel:

$ gcc -std=gnu99 -g -Og loop.c -o loop 

Wenn Sie an noch mehr Informationen über gcc interessiert sind, lesen Sie Abschnitt 1 dieses Stanford Unix Programming Tools Dokuments, sowie das komplette gcc Handbuch (GNU).