Есть ли способ использовать 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 через командную строку.

DeadMG
источник
3
Вы знаете причину этого дизайнерского решения?
Макс
libgccjitработает в этом направлении, хотя это будет тяжелая битва: programmers.stackexchange.com/a/323821/124651
Сиро Сантилли,
3

С gcc это невозможно, но вы можете найти tcc (встраиваемый компилятор C) достаточно хорошим для того, что вы имеете в виду. Дистрибутив поставляется с библиотекой libtcc, которая позволяет компилировать, связывать и запускать код C "на лету".

Обратите внимание, что это только для C, ваш вопрос также помечен C ++, но я не видел никакого эквивалента tcc для C ++.

Remo.D
источник
Обратите внимание, что tccкомпилируется быстро, но не оптимизируется вообще. Сгенерированный код часто в 3–10 раз медленнее, чем то, gcc -O2что генерируется.
Василий Старынкевич
2

Я сомневаюсь, что есть что-то лучше, чем разветвление gcc. Вы можете рассмотреть Clang, который больше подходит для такого использования.

Брюс Стивенс
источник
2

(Я предполагаю, что вы находитесь в какой-то системе POSIX, например, Linux или MacOSX)

Вы, очевидно, должны посмотреть на GCCJIT , как упомянул Сиро Сантилли . Затем вы создадите некоторое похожее на AST представление сгенерированного кода. Конечно, вы могли бы рассмотреть LLVM вместо этого или даже более простую библиотеку JIT, такую ​​как libjit или GNU lightning (но libjitи выдаютlightning код быстро, но испускаемый код медленный и неоптимизированный).

Тем не менее, вы все равно можете подумать о выделении некоторого кода на C во временный файл и создании его компиляции (например, в качестве разделяемой библиотеки, которую вы позже динамически загрузите как плагин, используя dlopen (3) & dlsym (3) ), см. Здесь и здесь для деталей.

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

На самом деле, мой опыт (в GCC MELT ) заключается в том, что на современных настольных компьютерах и ноутбуках испускание нескольких сотен строк кода на C и создание их компиляции достаточно быстро (одна или две десятых секунды), чтобы быть совместимым с взаимодействием с пользователем. Итак, сегодня вы могли бы рассмотреть вариант REPL, который бы это сделал. Смотрите также этот связанный ответ.

Посмотрите также на Common Lisp и SBCL, который является реализацией, которая компилируется в машинный код при каждом взаимодействии REPL.

Василий Старынкевич
источник