Existe uma maneira de usar o gcc como uma biblioteca?

10

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.

Porque o que
fonte

Respostas:

10

O GCC foi explicitamente projetado para resistir ao uso como base / biblioteca de ferramentas. Você precisa usar o Clang para isso ou ligar para o GCC através da linha de comando.

DeadMG
fonte
3
Você sabe o motivo dessa decisão de design?
Max
libgccjitestá trabalhando nessa direção, embora possa ser uma batalha difícil: programmers.stackexchange.com/a/323821/124651
Ciro Santilli冠状病毒审查六四事件法轮功
3

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 ++.

Remo.D
fonte
Observe que tcccompila rapidamente, mas não está otimizando. O código gerado é geralmente 3 a 10 vezes mais lento do que o gcc -O2que produziria.
Basile Starynkevitch
2

Duvido que haja algo melhor do que bifurcar o gcc. Você pode considerar o clang, que é mais projetado para esse tipo de uso.

Bruce Stephens
fonte
2

(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 libjitelightning 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 um gccprocesso (ou usar algum outro compilador, como clang) é 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.

Basile Starynkevitch
fonte