Alguém conhece uma solução que funciona mais ou menos assim:
#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;
}
Eu sei que posso executar o comando "gcc main.c -o main" em um fork e analisar a saída ... mas eu estava procurando por algo mais ' confiável ' como o exemplo acima.
libgccjit
está trabalhando nessa direção, embora possa ser uma batalha difícil: programmers.stackexchange.com/a/323821/124651libgccjit
Introduzido no GCC 5 e ainda é experimental a partir do GCC 6.
Documentos: https://gcc.gnu.org/onlinedocs/jit/
Perguntas relacionadas:
fonte
Não é possível com o gcc, mas você pode encontrar o tcc (um compilador C incorporado) bom o suficiente para o que você tem em mente. A distribuição vem com uma biblioteca libtcc que permite compilar, vincular e executar o código C "on the fly".
Observe que isso apenas para C, sua pergunta também é marcada como C ++, mas eu não vi nenhum equivalente de tcc para C ++.
fonte
tcc
compila rapidamente, mas não está otimizando. O código gerado é geralmente 3 a 10 vezes mais lento do que ogcc -O2
que produziria.Duvido que haja algo melhor do que bifurcar o gcc. Você pode considerar o clang, que é mais projetado para esse tipo de uso.
fonte
(Suponho que você esteja em algum sistema POSIX, como Linux ou MacOSX)
Obviamente, você deve examinar o GCCJIT , como mencionado por Ciro Santilli . Você criará uma representação semelhante ao AST do código gerado. É claro que você pode considerar o LLVM , ou mesmo alguma biblioteca JIT mais simples, como libjit ou GNU lightning (mas
libjit
elightning
estão emitindo código rapidamente, mas o código emitido é lento e unoptimized).No entanto, você ainda pode emitir um código C em um arquivo temporário e fazer uma compilação dele (por exemplo, como uma biblioteca compartilhada que posteriormente carregaria dinamicamente como um plug-in usando dlopen (3) e dlsym (3) ), veja aqui e aqui para detalhes.
Observe um fato importante: gerar código otimizado leva tempo de CPU (com GCCJIT, ou LLVM, ou executando
gcc -O2
) porque é uma tarefa difícil. Portanto, a sobrecarga de bifurcar umgcc
processo (ou usar algum outro compilador, comoclang
) é insignificante (escrita usando alguma biblioteca como GCCJIT ou LLVM).Na verdade, minha experiência (no GCC MELT ) é que, nos desktops e laptops atuais, emitir algumas centenas de linhas de código C e criar uma compilação delas é rápido o suficiente (um ou dois décimos de segundo) para ser compatível com a interação do usuário. Então, hoje, você poderia considerar ter um REPL que faria isso. Veja também esta resposta relacionada.
Veja também o Common Lisp e o SBCL, que é uma implementação que é compilada no código da máquina a cada interação REPL.
fonte