Wie man Clang in llvm IR kompilieren lässt

Lesezeit: 4 Minuten

Benutzeravatar von pythonic
pythonisch

Ich möchte, dass Clang meinen C/C++-Code in LLVM-Bitcode kompiliert und nicht in eine ausführbare Binärdatei. Wie kann ich das erreichen?

Und wenn ich den LLVM-Bitcode habe, wie kann ich ihn weiter in eine ausführbare Binärdatei kompilieren?

Ich möchte dem LLVM-Bitcode einen Teil meines eigenen Codes hinzufügen, bevor ich ihn in eine ausführbare Binärdatei kompiliere.

Benutzeravatar von Eli Bendersky
Eli Bendersky

Angesichts einer C/C++-Datei foo.c:

> clang -S -emit-llvm foo.c

Produziert foo.ll das ist eine LLVM IR-Datei.

Das -emit-llvm Die Option kann auch direkt an das Compiler-Frontend übergeben werden und nicht über den Treiber -cc1:

> clang -cc1 foo.c -emit-llvm

Produziert foo.ll mit deren. -cc1 fügt einige coole Optionen hinzu, wie z -ast-print. Kasse -cc1 --help für mehr Details.


Um LLVM IR nach der Assemblierung zu kompilieren, verwenden Sie die llc Werkzeug:

> llc foo.ll

Produziert foo.s mit Assembly (standardmäßig die Maschinenarchitektur, auf der Sie es ausführen). llc ist eines der LLVM-Tools – Hier ist seine Dokumentation.

  • Was macht -S hier?

    – Meawoppl

    27. Februar 2014 um 16:17 Uhr

  • @meawoppl: -S wie in gcc besagt, dass Textassembly anstelle von assemblierter Binärdatei ausgegeben wird

    – Eli Bendersky

    28. Februar 2014 um 16:53 Uhr

  • Aha. Ich hatte Schwierigkeiten, etwas in den Dokumenten darüber zu finden. Es ist davon auszugehen, dass viele Flags in Clang die gcc-Flag-Struktur spiegeln?

    – Meawoppl

    28. Februar 2014 um 17:35 Uhr

  • @EliBendersky Wissen Sie, wie Sie mehrere .c- und .h-Dateien in eine für Menschen lesbare IR kompilieren, damit ich die IR mit „lli theIrFile“ ausführen kann? Vielen Dank

    – Zwischenspeicher

    20. Juli 2014 um 18:43 Uhr


  • @cache: Kompilieren Sie jede in eine eigene IR-Datei und verwenden Sie dann den LLVM-Linker zum Kombinieren

    – Eli Bendersky

    22. Juli 2014 um 3:12 Uhr

Benutzeravatar von Christoph
Christoph

Verwenden

clang -emit-llvm -o foo.bc -c foo.c
clang -o foo foo.bc

  • Ich würde empfehlen, die Bedeutung von Erweiterungen beizubehalten. IOW, .o sollte sich auf binäre Objektdateien beziehen, .s in Assemblerdateien und etwas anderes (per Konvention .ll) in LLVM IR-Dateien. Sonst kommt man leicht durcheinander. Clang/LLVM haben jetzt keinen eigenen Linker für binäre Objekte (obwohl einer in Arbeit ist). Der LLVM-Linker llvm-ld verbindet einfach mehrere IR-Dateien zu einer

    – Eli Bendersky

    5. Februar 2012 um 13:06 Uhr

  • @EliBendersky: Sie haben Recht, wenn es um Dateierweiterungen geht – und das Clang-Frontend macht tatsächlich das Richtige, wenn .bc wird genutzt; auch daran denken llvm-ld kann als Frontend für die System-Toolchain fungieren, dh meine vorherige Antwort mit llvm-ld -native sollte wie erwartet funktionieren….

    – Christoph

    5. Februar 2012 um 13:13 Uhr


  • @rickfoosusa: funktioniert bei mir – foo.bc ist eine LLVM-Bitcode-Datei

    – Christoph

    25. September 2014 um 21:23 Uhr


  • Funktioniert bei mir: clang -emit-llvm -o test.bc -c test.c && file test.bc: test.bc: LLVM IR bitcode.

    – ntc2

    12. April 2016 um 17:11 Uhr

Wenn Sie mehrere Quelldateien haben, möchten Sie wahrscheinlich die Linkzeitoptimierung verwenden, um eine Bitcodedatei für das gesamte Programm auszugeben. Die anderen gegebenen Antworten führen dazu, dass Sie für jede Quelldatei eine Bitcode-Datei erhalten.

Stattdessen möchten Sie mit Link-Time-Optimization kompilieren

clang -flto -c program1.c -o program1.o
clang -flto -c program2.c -o program2.o

und fügen Sie für den letzten Verknüpfungsschritt das Argument -Wl,-plugin-opt=also-emit-llvm hinzu

clang -flto -Wl,-plugin-opt=also-emit-llvm program1.o program2.o -o program

Das gibt dir beide ein kompiliertes Programm und den dazugehörigen Bitcode (program.bc). Anschließend können Sie program.bc beliebig modifizieren und das modifizierte Programm jederzeit neu kompilieren

clang program.bc -o program

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 symbolischen Link zu diesem Linker namens „ld“ in einem speziellen Verzeichnis namens „fakebin“ irgendwo auf Ihrem Computer und fügen Sie die Option hinzu

-B/home/jeremy/fakebin

zu allen obigen Verknüpfungsschritten.

  • Offenbar also-emit-llvm wurde entfernt

    – Heide Mitchell

    30. Januar um 21:52 Uhr

Wenn Sie mehrere Dateien haben und nicht jede Datei eingeben müssen, würde ich Ihnen empfehlen, diese einfachen Schritte zu befolgen (ich verwende clang-3.8 aber Sie können jede andere Version verwenden):

  1. alle erzeugen .ll Dateien

    clang-3.8 -S -emit-llvm *.c
    
  2. verbinden sie zu einem einzigen

    llvm-link-3.8 -S -v -o single.ll *.ll
    
  3. (Optional) Optimieren Sie Ihren Code (vielleicht eine Alias-Analyse)

    opt-3.8 -S -O3 -aa -basicaaa -tbaa -licm single.ll -o optimised.ll
    
  4. Assembly generieren (erzeugt eine optimised.s Datei)

    llc-3.8 optimised.ll
    
  5. Erstellen Sie eine ausführbare Datei (benannt a.out)

    clang-3.8 optimised.s
    

Hast du gelesen clang Dokumentation ? Sie suchen wahrscheinlich -emit-llvm.

1425330cookie-checkWie man Clang in llvm IR kompilieren lässt

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy