在本章中,我们学习如何跨平台编译
但是本章节的代码,和之前几章节是脱节的,尤其是如果在原来的代码基础上增加 Export to Object,是无法成功导出的 这里和 JIT 那部分内容冲突,代码上增加了宏来跳过
支持的平台 #
通过
llvm-as < /dev/null | llc -march=x86 -mattr=help
我们得知 LLVM
支持的平台
修改支持平台 #
我们之前的代码中都是
llvm::InitializeNativeTarget (); // 支持当前平台 nativeTarget
我们修改为
- llvm::InitializeNativeTarget ();
- llvm::InitializeNativeTargetAsmPrinter ();
- llvm::InitializeNativeTargetAsmParser ();
+
+
+
增加生成逻辑 #
// 获得当前目标的
auto TargetTriple = llvm::sys::getDefaultTargetTriple();
TheModule->setTargetTriple(TargetTriple);
std::string Error;
auto Target = llvm::TargetRegistry::lookupTarget(TargetTriple, Error);
// 如果找不到目标就直接报错退出
if (!Target) {
llvm::errs() << Error;
return 1;
}
auto CPU = "generic";
auto Features = "";
llvm::TargetOptions opt;
auto RM = llvm::Optional<llvm::Reloc::Model>();
auto TheTargetMachine = Target->createTargetMachine(TargetTriple, CPU, Features, opt, RM);
TheModule->setDataLayout(TheTargetMachine->createDataLayout());
auto Filename = "output.o";
std::error_code EC;
llvm::raw_fd_ostream dest(Filename, EC, llvm::sys::fs::OF_None);
if (EC) {
llvm::errs() << "Could not open file: " << EC.message();
return 1;
}
llvm::legacy::PassManager pass;
auto FileType = llvm::CGFT_ObjectFile;
if (TheTargetMachine->addPassesToEmitFile(pass, dest, nullptr, FileType)) {
llvm::errs() << "TheTargetMachine can't emit a file of this type";
return 1;
}
pass.run(*TheModule);
dest.flush();
llvm::outs() << "Wrote " << Filename << "\n";
Try it #
ready> def average(x y) (x + y) * 0.5;
^D
Wrote output.o
$ llvm-objdump -d cmake-build-debug/output.o
cmake-build-debug/output.o: file format mach-o 64-bit x86-64
Disassembly of section __TEXT,__text:
0000000000000000 <_average>:
0: f2 0f 11 44 24 f0 movsd %xmm0, -16(%rsp)
6: f2 0f 11 4c 24 f8 movsd %xmm1, -8(%rsp)
c: f2 0f 58 c1 addsd %xmm1, %xmm0
10: f2 0f 59 05 08 00 00 00 mulsd 8(%rip), %xmm0 ## 0x20 <_average+0x20>
18: c3 retq
$ ./main
average of 3.0 and 4.0: 3.5