Чи є спосіб використовувати gcc як бібліотеку?


10

Кожен знає рішення, яке працює приблизно так:

#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;
}

Я знаю, що можу запустити команду "gcc main.c -o main" у вилку та проаналізувати вихід ... але я шукав щось більш " надійне ", як на прикладі вище.

Відповіді:


10

GCC явно був розроблений, щоб протистояти використанню в якості бази / бібліотеки інструментів. Для цього вам потрібно використовувати Clang або зателефонувати в GCC через командний рядок.


3
Чи знаєте ви причину такого дизайнерського рішення?
Макс

libgccjitпрацює в цьому напрямку, хоча це буде
важкий


3

З gcc це неможливо, але ви можете знайти tcc (вбудовуваний компілятор C) достатньо хороший для того, що маєте на увазі. Дистрибутив постачається з бібліотекою libtcc, яка дозволяє компілювати, зв’язувати та запускати код C "на льоту".

Зауважте, що це лише для C, ваше питання також позначене тегом C ++, але я не бачив жодного еквівалента tcc для C ++.


Зауважте, що tccкомпілюється швидко, але зовсім не оптимізується. Згенерований код часто в 3 - 10 разів повільніше, ніж те, що створюється gcc -O2.
Базиль Старинкевич

2

Я сумніваюся, що є щось краще, ніж розвантажувати gcc. Ви можете розглянути кланг, який більше розроблений для такого типу використання.


2

(Я здогадуюсь, ви перебуваєте в якійсь системі POSIX, наприклад, Linux або MacOSX)

Ви, очевидно, повинні заглянути в GCCJIT , про що згадував Ciro Santilli . Потім ви побудуєте деяке AST- подібне подання згенерованого коду. Звичайно , ви могли б розглянути LLVM замість цього, або навіть якийсь - небудь простий JIT бібліотека як libjit або GNU блискавки (але libjitі lightningвипускають код швидко, але випромінюється код повільно і неоптимізованими).

Однак ви можете все-таки розглянути можливість видалення деякого коду С у тимчасовий файл і форсування компіляції з нього (наприклад, як спільна бібліотека, яку пізніше динамічно завантажуватимете як плагін за допомогою dlopen (3) & dlsym (3) ), дивіться тут і тут для деталей.

Зауважте важливий факт: генерування оптимізованого коду займає час процесора (за допомогою GCCJIT, або LLVM, або запуск gcc -O2), оскільки це складне завдання. Таким чином, накладні витрати форкінгу gccпроцесу (або використання іншого компілятора, як-от clang) незначні (wrt, використовуючи деяку бібліотеку, наприклад, GCCJIT або LLVM).

Насправді мій досвід (в GCC MELT ) полягає в тому, що на поточних настільних комп’ютерах і ноутбуках випромінювання декількох сотень рядків коду С і форсування компіляції з них досить швидко (одна-дві десяті секунди), щоб бути сумісним із взаємодією користувачів. Отже, сьогодні ви можете подумати про наявність REPL, який би це зробив. Дивіться також цю відповідь.

Подивіться також на Common Lisp та SBCL - це реалізація, яка компілюється в машинний код при кожній взаємодії REPL.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.