LLVM:如何交叉编译 C++ 程序

LLVM: How to Cross Compile C++ Programs

我尝试使用 LLVM 将 C++ 源代码编译为 arm 二进制文件。这是一个例子:

//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

到目前为止没有警告或错误。然后我尝试使用 qemu-arm 和 gem5 模拟器 运行 "hello.exe",两者都因分段错误而崩溃:

qemu-arm 的输出:

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++ 程序。

这种方式行不通。事实上,LLVM IR 不是目标中立的,因此将 x86 IR 编译到 ARM 是行不通的:ABI 不同等。

您需要使用 clang 的 -target 选项(或将 clang 构建为指定默认目标的交叉编译器)。

感谢大家的帮助。我刚刚弄清楚它是如何工作的:

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

arm 二进制文件在 qemu-arm 和 gem5 上都能正常运行。

我认为 LLVM IR 应该完全独立于目标机器,但实际上它不是(奇怪...)

我还是不明白为什么c程序没有这个问题。