Tout le monde connaît une solution qui fonctionne comme ceci:
#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;
}
Je sais que je peux exécuter la commande "gcc main.c -o main" dans un fork et analyser la sortie ... mais je cherchais quelque chose de plus " fiable " comme l'exemple ci-dessus.
libgccjit
travaille dans cette direction, même si ce sera une bataille difficile: programmers.stackexchange.com/a/323821/124651libgccjit
Introduit dans GCC 5 et est toujours expérimental depuis GCC 6.
Documents: https://gcc.gnu.org/onlinedocs/jit/
Questions connexes:
la source
Ce n'est pas possible avec gcc mais vous pourriez trouver tcc (un compilateur C intégrable) assez bon pour ce que vous avez en tête. La distribution est livrée avec une bibliothèque libtcc qui permet de compiler, lier et exécuter du code C "à la volée".
Notez que ceci uniquement pour C, votre question est également balisée C ++ mais je n'ai vu aucun équivalent de tcc pour C ++.
la source
tcc
compile rapidement, mais n'optimise pas du tout. Le code généré est souvent 3 à 10 fois plus lent que cegcc -O2
qu'il produirait.Je doute qu'il y ait quelque chose de mieux que de bifurquer gcc. Vous pourriez envisager le clang, qui est plus conçu pour ce type d'utilisation.
la source
(Je suppose que vous êtes sur un système POSIX, comme Linux ou MacOSX)
Vous devriez évidemment vous pencher sur GCCJIT , comme l'a mentionné Ciro Santilli . Vous allez ensuite créer une représentation de type AST du code généré. Bien sûr, vous pourriez envisager LLVM à la place, ou même une bibliothèque JIT plus simple comme libjit ou GNU lightning (mais
libjit
etlightning
émettent du code rapidement, mais le code émis est lent et non optimisé).Cependant, vous pourriez toujours envisager d' émettre du code C dans un fichier temporaire et d'en créer une compilation (par exemple, en tant que bibliothèque partagée que vous chargeriez plus tard dynamiquement en tant que plugin à l'aide de dlopen (3) et dlsym (3) ), voir ici et ici pour plus de détails.
Notez un fait important: générer du code optimisé prend du temps CPU (avec GCCJIT, ou LLVM, ou en exécutant
gcc -O2
) car c'est une tâche difficile. Ainsi, le surcoût lié à la fourche d'ungcc
processus (ou à l'utilisation d'un autre compilateur, commeclang
) est négligeable (par rapport à une bibliothèque comme GCCJIT ou LLVM).En fait, mon expérience (dans GCC MELT ) est que sur les ordinateurs de bureau et portables actuels, émettre quelques centaines de lignes de code C et en forger une compilation est assez rapide (une ou deux dixièmes de seconde) pour être compatible avec l'interaction avec l'utilisateur. Donc, aujourd'hui, vous pourriez envisager d'avoir un REPL qui ferait cela. Voir également cette réponse connexe.
Regardez également Common Lisp et SBCL qui est une implémentation qui se compile en code machine à chaque interaction REPL.
la source