Alguien conoce una solución que funciona más o menos así:
#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;
}
Sé que puedo ejecutar el comando "gcc main.c -o main" en una bifurcación y analizar la salida ... pero estaba buscando algo más ' confiable ' como el ejemplo anterior.
libgccjit
está trabajando en esa dirección, aunque será una batalla cuesta arriba: programmers.stackexchange.com/a/323821/124651libgccjit
Introducido en GCC 5 y todavía es experimental a partir de GCC 6.
Documentos: https://gcc.gnu.org/onlinedocs/jit/
Preguntas relacionadas:
fuente
No es posible con gcc, pero es posible que encuentre tcc (un compilador C incorporable) lo suficientemente bueno para lo que tiene en mente. La distribución viene con una biblioteca libtcc que permite compilar, vincular y ejecutar código C "sobre la marcha".
Tenga en cuenta que esto solo para C, su pregunta también está etiquetada como C ++ pero no he visto ningún equivalente de tcc para C ++.
fuente
tcc
compila rápidamente, pero no se optimiza en absoluto. El código generado suele ser de 3 a 10 veces más lento de logcc -O2
que produciría.Dudo que haya algo mejor que bifurcar gcc. Puede considerar el sonido metálico, que está más diseñado para este tipo de uso.
fuente
(Supongo que estás en algún sistema POSIX, como Linux o MacOSX)
Obviamente deberías buscar en GCCJIT , como lo menciona Ciro Santilli . Luego construirá una representación similar a AST del código generado. Por supuesto, puede considerar LLVM en su lugar, o incluso alguna biblioteca JIT más simple como libjit o GNU lightning (pero
libjit
ylightning
está emitiendo código rápidamente, pero el código emitido es lento y no optimizado).Sin embargo, aún podría considerar emitir algún código C en un archivo temporal y bifurcar una compilación del mismo (por ejemplo, como una biblioteca compartida que luego cargaría dinámicamente como un complemento usando dlopen (3) y dlsym (3) ), vea aquí y aquí para detalles.
Observe un hecho importante: generar código optimizado requiere tiempo de CPU (con GCCJIT o LLVM, o al ejecutarse
gcc -O2
) porque es una tarea difícil. Entonces, la sobrecarga de bifurcar ungcc
proceso (o usar algún otro compilador, comoclang
) es insignificante (wrt usando alguna biblioteca como GCCJIT o LLVM).En realidad, mi experiencia (en GCC MELT ) es que en los equipos de escritorio y portátiles actuales, emitir unos cientos de líneas de código C y bifurcar una compilación de ellas es lo suficientemente rápido (una o dos décimas de segundo) para ser compatible con la interacción del usuario. Así que hoy, podrías considerar tener un REPL que haría eso. Ver también esta respuesta relacionada.
Mire también Common Lisp y SBCL, que es una implementación que se compila en código máquina en cada interacción REPL.
fuente