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.
libgccjit
arbeitet in diese Richtung, obwohl es ein harter Kampf sein wird: programmers.stackexchange.com/a/323821/124651libgccjit
Eingeführt in GCC 5 und ist ab GCC 6 noch experimentell.
Dokumente: https://gcc.gnu.org/onlinedocs/jit/
Verwandte Fragen:
quelle
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.
quelle
tcc
Kompilierung schnell erfolgt, aber überhaupt nicht optimiert wird. Der generierte Code ist oft drei- bis zehnmal langsamer als das, wasgcc -O2
produzieren würde.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.
quelle
(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
libjit
und gebenlightning
Code 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 einesgcc
Prozesses (oder die Verwendung eines anderen Compilers wieclang
) 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.
quelle