Gibt es eine Möglichkeit, gcc als Bibliothek zu verwenden?

10

Jeder kennt eine Lösung, die ungefähr so ​​funktioniert:

#include <stdio.h>
#include <gcc.h> /* This .h is what I'm looking for. */

int main (void) {
    /* variables declaration (...) */

    /* The following line is supposed to be equivalent to:
     *     $ gcc main.c -o main */
    results = gcc_compile_and_link("main.c", "main");

    /* Now I want to use the warnings and errors to do something.
     * For instance, I'll print them to the console: */
    printf("warnings:\n");
    for (i=0; i<results.warns_len; i++)
        printf("%s\n", results.warings[i].msg);
    printf("errors\n");
    for (i=0; i<results.errs_len; i++)
        printf("%s\n", results.errors[i].msg);

    /* free memory and finalize (...) */
    return 0;
}

Ich weiß, dass ich den Befehl "gcc main.c -o main" in einem Fork ausführen und die Ausgabe analysieren kann ... aber ich suchte nach etwas ' Zuverlässigerem ' wie im obigen Beispiel.

Warum was
quelle

Antworten:

10

GCC wurde ausdrücklich entwickelt, um nicht als Werkzeugbasis / Bibliothek verwendet zu werden. Sie müssen dafür Clang verwenden oder GCC über die Befehlszeile aufrufen.

DeadMG
quelle
3
Kennen Sie den Grund für diese Entwurfsentscheidung?
Max
libgccjitarbeitet in diese Richtung, obwohl es ein harter Kampf sein wird: programmers.stackexchange.com/a/323821/124651
Ciro Santilli 2 病毒 审查 六四 事件 2
3

Mit gcc ist dies nicht möglich, aber Sie finden tcc (einen einbettbaren C-Compiler) möglicherweise gut genug für das, was Sie sich vorgestellt haben. Die Distribution enthält eine libtcc-Bibliothek, mit der C-Code "on the fly" kompiliert, verknüpft und ausgeführt werden kann.

Beachten Sie, dass dies nur für C gilt. Ihre Frage ist auch mit C ++ gekennzeichnet, aber ich habe kein Äquivalent von tcc für C ++ gesehen.

Remo.D
quelle
Beachten Sie, dass die tccKompilierung schnell erfolgt, aber überhaupt nicht optimiert wird. Der generierte Code ist oft drei- bis zehnmal langsamer als das, was gcc -O2produzieren würde.
Basile Starynkevitch
2

Ich bezweifle, dass es etwas Besseres gibt, als gcc zu gabeln. Sie könnten Clang in Betracht ziehen, das eher für diese Art der Verwendung entwickelt wurde.

Bruce Stephens
quelle
2

(Ich vermute, Sie befinden sich auf einem POSIX-System wie Linux oder MacOSX.)

Sie sollten sich natürlich mit GCCJIT befassen , wie von Ciro Santilli erwähnt . Anschließend erstellen Sie eine AST- ähnliche Darstellung des generierten Codes. Natürlich könnten Sie stattdessen LLVM oder sogar eine einfachere JIT- Bibliothek wie libjit oder GNU lightning in Betracht ziehen (aber libjitund geben lightningCode schnell aus, aber der ausgegebene Code ist langsam und nicht optimiert).

Möglicherweise möchten Sie jedoch weiterhin C-Code in einer temporären Datei ausgeben und eine Kompilierung davon erstellen (z. B. als gemeinsam genutzte Bibliothek, die Sie später dynamisch als Plugin mit dlopen (3) & dlsym (3) laden würden ), siehe hier und hier für Details.

Beachten Sie eine wichtige Tatsache: Das Generieren von optimiertem Code benötigt CPU-Zeit (mit GCCJIT oder LLVM oder durch Ausführen gcc -O2), da dies eine schwierige Aufgabe ist. Der Aufwand für das Forken eines gccProzesses (oder die Verwendung eines anderen Compilers wie clang) ist daher vernachlässigbar (bei Verwendung einer Bibliothek wie GCCJIT oder LLVM).

Nach meiner Erfahrung (in GCC MELT ) ist es auf aktuellen Desktops und Laptops schnell genug (ein oder zwei Zehntel Sekunden), ein paar hundert Zeilen C-Code auszugeben und eine Zusammenstellung davon zu erstellen, um mit der Benutzerinteraktion kompatibel zu sein. Heute könnten Sie eine REPL in Betracht ziehen, die dies tun würde. Siehe auch diese verwandte Antwort.

Schauen Sie sich auch Common Lisp und SBCL an , eine Implementierung, die bei jeder REPL-Interaktion in Maschinencode kompiliert wird.

Basile Starynkevitch
quelle