Любой знает решение, которое работает примерно так:
#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" в форке и проанализировать вывод ... но я искал что-то более " надежное ", как в примере выше.
libgccjit
работает в этом направлении, хотя это будет тяжелая битва: programmers.stackexchange.com/a/323821/124651libgccjit
Введенный в GCC 5 и все еще экспериментальный с GCC 6.
Документы: https://gcc.gnu.org/onlinedocs/jit/
Смежные вопросы:
источник
С gcc это невозможно, но вы можете найти tcc (встраиваемый компилятор C) достаточно хорошим для того, что вы имеете в виду. Дистрибутив поставляется с библиотекой libtcc, которая позволяет компилировать, связывать и запускать код C "на лету".
Обратите внимание, что это только для C, ваш вопрос также помечен C ++, но я не видел никакого эквивалента tcc для C ++.
источник
tcc
компилируется быстро, но не оптимизируется вообще. Сгенерированный код часто в 3–10 раз медленнее, чем то,gcc -O2
что генерируется.Я сомневаюсь, что есть что-то лучше, чем разветвление gcc. Вы можете рассмотреть Clang, который больше подходит для такого использования.
источник
(Я предполагаю, что вы находитесь в какой-то системе 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.
источник