2015-03-07 3 views
3

Я попытался использовать LLVM для компиляции исходного кода на C++ для создания двоичных файлов. Вот пример:LLVM: как перекрестно компилировать программы на С ++

//hello.cpp 
#include <iostream> 
int main() { 
    std::cout << "Hello World!\n" << std::endl; 
    return 0; 
} 

Я использую следующие команды:

clang++ -emit-llvm -c hello.cpp -o hello.bc 
llc -march=arm hello.bc -o hello.s // I do need this step for running some backend optimizations 
arm-none-linux-gnueabi-g++ -static hello.s -o hello.exe 

Там не было никаких предупреждений или ошибок до сих пор. Затем я попытался запустить "hello.exe" с помощью QEmu-руки и gem5 тренажере, как столкнулся с ошибкой сегментации:

выход из для QEMU руки:

qemu-arm hello.exe 
qemu: uncaught target signal 11 (Segmentation fault) - core dumped 
Segmentation fault (core dumped) 

выходной формы gem5:

~/gem5/build/ARM/gem5.opt ~/gem5/configs/example/se.py -c ./hello.exe 
**** REAL SIMULATION **** 
info: Entering event queue @ 0. Starting simulation... 
panic: Page table fault when accessing virtual address 0xfffffff4 
@ tick 2035000 
[invoke:build/ARM/sim/faults.cc, line 70] 
Memory Usage: 646432 KBytes 
Program aborted at cycle 2035000 
Aborted (core dumped) 

Я использовал clang версию 3.7.0svn. Я что-то пропустил? Фактически процесс компиляции использовался для нескольких программ c, и все они работали правильно. Но не для C++-программ.

+0

У вашей среды сборки и исполнения есть совместимые библиотеки C++? –

+0

@CarlNorum Да, имеет смысл, что ошибка сегментации происходит, если библиотеки C++ несовместимы. Я использовал precompiled arm cross compiler, я уверен, что у него есть собственные библиотеки C++. Но как проверить совместимость? Или я могу использовать параметры командной строки, чтобы заставить llvm-бэкэнд использовать определенные библиотеки C++? Большое спасибо за помощь :) –

+1

Возможно, вам следует установить ссылку с помощью компоновщика, соответствующего вашему компилятору (т. Е. Ссылку с 'g ++' только при компиляции с 'g ++') –

ответ

1

Это не будет работать таким образом. На самом деле, LLVM IR не является нейтральным по назначению, поэтому компиляция x86 IR в ARM не будет работать: ABI - разные и т. Д.

Вам нужно использовать параметр -target от clang (или построить clang как кросс-компилятор, цель по умолчанию).

+0

Спасибо за ответ. Теперь я читаю документы llvm о том, как выполнять кросс-компиляцию с использованием параметров -target. Кстати, я не понимаю, почему этот метод не имеет проблем с программой c? –

1

Спасибо за помощь всем. Я просто понял, как это будет работать:

clang++ -target arm-none-linux-gnueabi --sysroot=/usr/local/arm-2009q3 -static hello.cpp -emit-llvm -c -I /usr/local/arm-2009q3/arm-none-linux-gnueabi/libc/usr/include/ 
llc hello.bc 
arm-none-linux-gnueabi-g++ -static hello.s -o hello.exe 

тонарма бинарными правильно работает на обоих для QEMU руки и gem5.

Я думал, что LLVM IR должен быть полностью независимым от целевой машины, но на самом деле это не так (странно ...)

Я до сих пор не понимаю, почему C программа не имеет эту проблему.

+0

Для C вам просто повезло. Я верю, что если вы попытаетесь передать/вернуть структуру по значению, например, или структурировать с разрывами между memebers, то вы увидите разницу. В конце концов, ARM 32-бит и, скорее всего, вы компилируете для x86-64 :) –

Смежные вопросы