Ich verwende eine Open-Source-Bibliothek, die anscheinend viele Vorverarbeitungsanweisungen enthält, um viele andere Sprachen als C zu unterstützen. Damit ich untersuchen kann, was die Bibliothek tut, möchte ich den C-Code sehen, den ich nach der Vorverarbeitung kompiliere eher wie das, was ich schreiben würde.
Kann gcc (oder ein anderes unter Linux allgemein verfügbares Tool) diese Bibliothek lesen, aber C-Code ausgeben, bei dem die Vorverarbeitung in irgendetwas konvertiert wurde und der auch von einem Menschen gelesen werden kann?
gcc -E
ist nützlicher, als die Zeile neu schreiben zu müssen, damit sie funktioniertcpp
.Antworten:
Ja. Übergeben Sie gcc die
-E
Option. Dadurch wird vorverarbeiteter Quellcode ausgegeben.quelle
-o something.o
, möchten Sie diesen möglicherweise auch ändern-o something.i
. Andernfalls befindet sich die vorverarbeitete Ausgabe in der.o
Datei.gcc -E file1.c file2.c ...
cpp
ist der Präprozessor.Führen Sie
cpp filename.c
diese Option aus, um den vorverarbeiteten Code auszugeben, oder leiten Sie ihn besser in eine Datei mit umcpp filename.c > filename.preprocessed
.quelle
diff
zeigt keinen Unterschied in den Dateien. Dies scheint auch eine nützliche Möglichkeit zu sein, den Code vorab zu verarbeiten und nach Fehlern in Ihren Makros zu suchen. Tolle Frage und eine tolle Antwort (IALCTHW).Ich verwende gcc als Präprozessor (für HTML-Dateien). Es macht genau das, was Sie wollen. Es erweitert die Direktiven "# -" und gibt dann eine lesbare Datei aus. (Keiner der anderen C / HTML-Präprozessoren, die ich versucht habe, verkettet Zeilen, verschluckt Sonderzeichen usw.) Vorausgesetzt, Sie haben gcc installiert, lautet die Befehlszeile:
gcc -E -xc -P -C -traditional-cpp code_before.cpp> code_after.cpp
(Muss nicht 'cpp' sein.) Eine ausgezeichnete Beschreibung dieser Verwendung finden Sie unter http://www.cs.tut.fi/~jkorpela/html/cpre.html .
Das "-traditional-cpp" behält Leerzeichen und Tabulatoren bei.
quelle
-save-temps
Dies ist eine weitere gute Option:
Haupt c
und jetzt
main.o
enthält das aktuelle Arbeitsverzeichnis neben der normalen Ausgabe auch die folgenden Dateien:main.i
ist die gewünschte vorbesessene Datei, die Folgendes enthält:main.s
ist ein Bonus :-) und enthält die generierte Baugruppe:Wenn Sie dies für eine große Anzahl von Dateien tun möchten, sollten Sie stattdessen Folgendes verwenden:
Dadurch werden die Zwischendateien im selben Verzeichnis wie die
-o
Objektausgabe anstelle des aktuellen Arbeitsverzeichnisses gespeichert , wodurch potenzielle Konflikte mit Basisnamen vermieden werden.Der Vorteil dieser Option gegenüber
-E
ist, dass es einfach ist, sie zu jedem Build-Skript hinzuzufügen, ohne den Build selbst stark zu beeinträchtigen.Eine weitere coole Sache an dieser Option ist, wenn Sie hinzufügen
-v
:Es zeigt tatsächlich die expliziten Dateien, die anstelle von hässlichen temporären Dateien verwendet werden
/tmp
, so dass es einfach ist, genau zu wissen, was gerade passiert, einschließlich der Schritte Vorverarbeitung / Kompilierung / Assemblierung:Getestet in Ubuntu 19.04 amd64, GCC 8.3.0.
quelle
Lauf:
oder
quelle
Angenommen, wir haben eine Datei als Message.cpp oder eine .c-Datei
Schritte 1: Vorverarbeitung (Argument -E)
g ++ -E. \ Message.cpp> P1
Die generierte P1-Datei enthält erweiterte Makros und den Inhalt der Header-Datei. Kommentare werden entfernt.
Schritt 2: Übersetzen Sie die vorverarbeitete Datei in die Assembly (Argument -S). Diese Aufgabe erledigt der Compiler
g ++ -S. \ Message.cpp
Ein Assembler (ASM) wird generiert (Message.s). Es hat den gesamten Assembler-Code.
Schritt 3: Übersetzen Sie den Assemblycode in den Objektcode. Hinweis: Message.s wurde in Schritt 2 generiert. g ++ -c. \ Message.s
Eine Objektdatei mit dem Namen Message.o wird generiert. Es ist die binäre Form.
Schritt 4: Verknüpfen der Objektdatei. Diese Aufgabe erledigt der Linker
g ++. \ Message.o -o MessageApp
Hier wird eine exe-Datei MessageApp.exe generiert.
quelle