Ich möchte, dass clang meinen C/C++
Code zu LLVM
Bytecode kompiliert und nicht zu einer ausführbaren Binärdatei. Wie kann ich das erreichen? Und wenn ich den LLVM
Bytecode erhalte , wie kann ich ihn verwenden, um ihn weiter in eine ausführbare Binärdatei zu kompilieren?
Grundsätzlich möchte ich dem LLVM
Bytecode einen Teil meines eigenen Codes hinzufügen, bevor ich ihn in eine ausführbare Binärdatei kompiliere.
Antworten:
Angesichts einer C / C ++ - Datei
foo.c
:Erzeugt
foo.ll
eine LLVM-IR-Datei.Die
-emit-llvm
Option kann auch direkt an das Compiler-Frontend und nicht an den Treiber übergeben werden-cc1
:Produziert
foo.ll
mit dem IR.-cc1
fügt einige coole Optionen wie hinzu-ast-print
. Schauen Sie sich-cc1 --help
für weitere Details.Verwenden Sie das folgende
llc
Tool, um LLVM IR weiter nach der Assembly zu kompilieren :Produziert
foo.s
mit Assembly (standardmäßig die Maschinenarchitektur, auf der Sie sie ausführen).llc
ist eines der LLVM-Tools - hier ist seine Dokumentation .quelle
Verwenden
quelle
.o
sollte sich auf binäre Objektdateien,.s
auf Assembly-Dateien und etwas anderes (.ll
gemäß Konvention ) auf LLVM-IR-Dateien beziehen . Ansonsten ist es leicht, verwirrt zu werden. Clang / LLVM haben jetzt keinen eigenen Linker für binäre Objekte (obwohl einer in Arbeit ist). Der LLVM-Linker verbindetllvm-ld
nur mehrere IR-Dateien zu einer.bc
es verwendet wird. Denken Sie auch daran, dassllvm-ld
dies als Frontend für die System-Toolchain dienen kann, dh meine vorherige Antwort mitllvm-ld -native
sollte wie erwartet funktionieren ....foo.bc
ist eine LLVM-Bitcode-Dateiclang -emit-llvm -o test.bc -c test.c && file test.bc: test.bc: LLVM IR bitcode
.Wenn Sie mehrere Quelldateien haben, möchten Sie wahrscheinlich die Link-Time-Optimierung verwenden, um eine Bitcode-Datei für das gesamte Programm auszugeben. Die anderen Antworten führen dazu, dass Sie für jede Quelldatei eine Bitcode-Datei erhalten.
Stattdessen möchten Sie mit der Optimierung der Verbindungszeit kompilieren
Fügen Sie für den letzten Verknüpfungsschritt das Argument -Wl, -plugin-opt = also-emit-llvm hinzu
Dies gibt Ihnen sowohl ein kompiliertes Programm als auch den entsprechenden Bitcode (program.bc). Sie können dann program.bc nach Belieben ändern und das geänderte Programm jederzeit neu kompilieren
Beachten Sie jedoch, dass Sie in diesem Schritt erneut alle erforderlichen Linker-Flags (für externe Bibliotheken usw.) einfügen müssen.
Beachten Sie, dass Sie den Gold-Linker verwenden müssen, damit dies funktioniert. Wenn Sie clang zwingen möchten, einen bestimmten Linker zu verwenden, erstellen Sie einen Symlink zu diesem Linker mit dem Namen "ld" in einem speziellen Verzeichnis namens "fakebin" irgendwo auf Ihrem Computer und fügen Sie die Option hinzu
zu den oben genannten Verknüpfungsschritten.
quelle
Wenn Sie mehrere Dateien haben und nicht jede Datei eingeben müssen, würde ich empfehlen, dass Sie diese einfachen Schritte ausführen (ich verwende,
clang-3.8
aber Sie können jede andere Version verwenden):Generieren Sie alle
.ll
DateienVerknüpfe sie zu einer einzigen
(Optional) Optimieren Sie Ihren Code (möglicherweise eine Alias-Analyse)
Baugruppe generieren (generiert eine
optimised.s
Datei)Erstellen Sie eine ausführbare Datei (benannt
a.out
)quelle
-S
Option (in Schritt 2) und gebe an , dass ich die Ausgabe in LLVM IR erzeugen möchte. Legen Sie grundsätzlich alle * .ll-Dateien in einer einzigen ab. Ich mache dies, um zu überprüfen, ob die Optimierungen den Code wirklich ändern, dhsingle.ll
undoptimised.ll
jetzt anders aussehen sollten (in Bezug auf den Code ), und Sie könnten den Bericht auch anzeigen, um festzustellen, ob es überhaupt einen Unterschied gibt.-basicaaa
ist eine falsche Flagge,-basicaa
muss stattdessen verwendet werden.Hast du die
clang
Dokumentation gelesen ? Sie suchen wahrscheinlich-emit-llvm
.quelle