Chcę, aby Clang skompilował mój C/C++
kod do LLVM
kodu bajtowego, a nie do pliku binarnego. Jak mogę to osiągnąć? A jeśli otrzymam LLVM
kod bajtowy, jak mogę go dalej skompilować do binarnego pliku wykonywalnego.
Zasadniczo chcę dodać część własnego kodu do LLVM
kodu bajtowego przed skompilowaniem do binarnego pliku wykonywalnego.
Odpowiedzi:
Biorąc pod uwagę plik C / C ++
foo.c
:Tworzy
foo.ll
plik LLVM IR.-emit-llvm
Opcja może być także przekazane do kompilatora frontonu bezpośrednio, a nie sterownika za pomocą-cc1
:Produkuje
foo.ll
z IR.-cc1
dodaje kilka fajnych opcji, takich jak-ast-print
. Sprawdź-cc1 --help
więcej szczegółów.Aby skompilować LLVM IR po złożeniu, użyj
llc
narzędzia:Produkuje
foo.s
z montażem (domyślnie do architektury maszyny, na której go uruchamiasz).llc
jest jednym z narzędzi LLVM - oto jego dokumentacja .źródło
Posługiwać się
źródło
.o
powinno odnosić się do binarnych plików obiektów,.s
do plików asemblerów i czegoś innego (zgodnie z konwencją.ll
) do plików LLVM IR. W przeciwnym razie łatwo się pogubić. Clang / LLVM nie ma teraz własnego konsolidatora dla obiektów binarnych (chociaż jeden jest w przygotowaniu). Linker LLVMllvm-ld
po prostu łączy kilka plików IR w jeden.bc
jest używana; również pamiętaj o tymllvm-ld
może działać jako nakładka na systemowy łańcuch narzędzi, tj. moja poprzednia odpowiedźllvm-ld -native
powinna działać zgodnie z oczekiwaniami ....foo.bc
to plik kodu bitowego LLVMclang -emit-llvm -o test.bc -c test.c && file test.bc: test.bc: LLVM IR bitcode
.Jeśli masz wiele plików źródłowych, prawdopodobnie chcesz użyć optymalizacji czasu łącza, aby wygenerować jeden plik kodu bitowego dla całego programu. Inne podane odpowiedzi spowodują, że otrzymasz plik kodu bitcode dla każdego pliku źródłowego.
Zamiast tego chcesz kompilować z optymalizacją czasu łącza
a na ostatnim etapie łączenia dodaj argument -Wl, -plugin-opt = also-emit-llvm
Daje to zarówno skompilowany program, jak i odpowiadający mu kod bitowy (program.bc). Następnie możesz zmodyfikować program.bc w dowolny sposób i ponownie skompilować zmodyfikowany program w dowolnym momencie, wykonując czynności
chociaż pamiętaj, że musisz ponownie dołączyć wszystkie niezbędne flagi konsolidatora (dla bibliotek zewnętrznych itp.).
Zauważ, że musisz użyć złotego linkera, aby to zadziałało. Jeśli chcesz zmusić clang do użycia określonego konsolidatora, utwórz dowiązanie symboliczne do tego konsolidatora o nazwie "ld" w specjalnym katalogu o nazwie "fakebin" gdzieś na twoim komputerze i dodaj opcję
do powyższych kroków łączenia.
źródło
Jeśli masz wiele plików i nie chcesz wpisywać każdego pliku, polecam wykonanie tych prostych kroków (używam,
clang-3.8
ale możesz użyć dowolnej innej wersji):wygeneruj wszystkie
.ll
plikipołącz je w jeden
(Opcjonalnie) Zoptymalizuj swój kod (może trochę analizy aliasów)
Generuj zespół (generuje
optimised.s
plik)Utwórz plik wykonywalny (nazwany
a.out
)źródło
-S
opcji (w kroku 2), określam, że chciałbym wyprodukować wyjście w LLVM IR. Zasadniczo umieść wszystkie pliki * .ll w jednym. Robię to, aby sprawdzić, czy optymalizacje naprawdę zmieniają kod, tj.single.ll
Ioptimised.ll
powinny teraz wyglądać inaczej (pod względem kodu), a także możesz wyświetlić raport, aby zobaczyć, czy w ogóle jest jakaś różnica.-basicaaa
jest złą flagą,-basicaa
należy jej użyć.Czy przeczytałeś
clang
dokumentację ? Prawdopodobnie szukasz-emit-llvm
.źródło