Czy istnieje sposób użycia gcc jako biblioteki?

10

Każdy zna rozwiązanie, które działa mniej więcej tak:

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

Wiem, że mogę uruchomić polecenie „gcc main.c -o main” w rozwidleniu i przeanalizować dane wyjściowe ... ale szukałem czegoś bardziej „ niezawodnego ”, jak w powyższym przykładzie.

Dlaczego co
źródło

Odpowiedzi:

10

GCC został wyraźnie zaprojektowany tak, aby nie był używany jako baza narzędzi / biblioteka. W tym celu musisz użyć Clanga lub wywołać GCC za pomocą wiersza poleceń.

DeadMG
źródło
3
Czy znasz powód tej decyzji projektowej?
Maks.
libgccjitpracuje w tym kierunku, choć będzie to bitwa pod górę: programmers.stackexchange.com/a/323821/124651
Ciro Santilli 法轮功 病毒 审查 六四 事件 法轮功
3

Z gcc nie jest to możliwe, ale może się okazać, że tcc (kompilator C do osadzenia) jest wystarczająco dobry, aby mieć to, co masz na myśli. Dystrybucja zawiera bibliotekę libtcc, która pozwala kompilować, łączyć i uruchamiać kod C „w locie”.

Zauważ, że to tylko dla C, twoje pytanie jest również oznaczone C ++, ale nie widziałem żadnego odpowiednika tcc dla C ++.

Remo.D
źródło
Zauważ, że tcckompiluje się szybko, ale wcale się nie optymalizuje. Wygenerowany kod jest często 3 do 10 razy wolniejszy niż ten, który gcc -O2by wyprodukował.
Basile Starynkevitch,
2

Wątpię, żeby było coś lepszego niż rozwidlenie gcc. Możesz rozważyć clang, który jest bardziej zaprojektowany do tego rodzaju zastosowań.

Bruce Stephens
źródło
2

(Zgaduję, że korzystasz z jakiegoś systemu POSIX, takiego jak Linux lub MacOSX)

Oczywiście powinieneś przyjrzeć się GCCJIT , o czym wspomniał Ciro Santilli . Następnie zbudujesz reprezentację wygenerowanego kodu podobną do AST . Oczywiście możesz zamiast tego rozważyć LLVM lub nawet prostszą bibliotekę JIT, taką jak libjit lub błyskawica GNU (ale libjiti lightningszybko emitują kod, ale emitowany kod jest powolny i niezoptymalizowany).

Jednak nadal możesz rozważyć wysłanie kodu C do pliku tymczasowego i wymyślenie jego kompilacji (np. Jako biblioteki współdzielonej, którą później dynamicznie ładowałbyś jako wtyczkę za pomocą dlopen (3) i dlsym (3) ), zobacz tutaj i tutaj dla szczegółów.

Zwróć uwagę na ważny fakt: generowanie zoptymalizowanego kodu wymaga czasu procesora (z GCCJIT, LLVM lub przez uruchomienie gcc -O2), ponieważ jest to trudne zadanie. Zatem narzut związany z rozwiązywaniem gccprocesu (lub używaniem innego kompilatora itp. clang) Jest znikomy (wrt przy użyciu biblioteki takiej jak GCCJIT lub LLVM).

W rzeczywistości, moje doświadczenie (w GCC MELT ) jest takie, że na obecnych komputerach stacjonarnych i laptopach, emitowanie kilkuset linii kodu C i rozwiązywanie ich kompilacji jest wystarczająco szybkie (jedna lub dwie dziesiąte sekundy), aby być kompatybilnym z interakcją użytkownika. Więc dzisiaj możesz rozważyć posiadanie REPL, który by to zrobił. Zobacz także pokrewną odpowiedź.

Zajrzyj również do Common Lisp i SBCL, która jest implementacją, która kompiluje się w kod maszynowy przy każdej interakcji REPL.

Basile Starynkevitch
źródło