我目前的编译器项目的工作使用LLVM。 我按照各种教程到我有一个解析器创建一个语法树,然后该树被转换成使用所提供的一个IRBuilder LLVM模块的点。
我的目标是创建一个可执行文件,我很困惑,下一步该怎么做。 所有我发现教程只是创建LLVM的模块和打印出来使用Module.dump大会()。 此外,我能找到的唯一文档是LLVM开发者,而不是结束项目的用户。
如果我要生成机器码,有什么下一步? LLVM的-MC项目看起来可以做我想做的,但我不能找出任何一种关于它的文档。
也许我期待LLVM做一些事情,事实并非如此。 我的期望是,我可以建立一个模块,那么就不会有我可以与模块和目标三重和对象文件会产生调用的API。 我发现在生产JIT文档和例子,我不感兴趣。 我在寻找如何产生编译的二进制文件。
我工作在OS X,如果有任何的影响。
使用llc -filetype=obj
从您的IR发射一个链接的目标文件。 你可以看一下的代码llc
看到LLVM API调用它使发出这样的代码。 至少对于Mac OS X和Linux上,以这样的方式发出的对象应该是不错的(即这不是一个“阿尔法质量”选项现在)。
LLVM不包含连接器(呢!),但是。 所以,实际上链接这个目标文件到一些可执行文件或共享库,则需要使用该系统连接。 需要注意的是,即使你有一个可执行文件,包括一个目标文件,后者无论如何都要联系。 在LLVM社区开发人员对LLVM一个真正的连接工作,叫lld
。 您可以访问其网页或搜索邮件列表归档跟随其进度。
正如你可以在阅读的LLC引导 ,确实是有意只生成组件,然后在“汇编语言输出然后可以通过本机汇编器和连接器传递到生成一个本地可执行程序” -比如GNU汇编( as
)和连接器( ld
)。
因此,这里的主要答案是使用本地工具组装和连接 。
然而,有一个为直接从IR文件生成所述原生对象,通过实验支持llc
:
-filetype - Choose a file type (not all types are supported by all targets):
=asm - Emit an assembly ('.s') file
=obj - Emit a native object ('.o') file [experimental]
或者你可以使用llvm-mc
从组装起来.s
文件:
-filetype - Choose an output file type:
=asm - Emit an assembly ('.s') file
=null - Don't emit anything (for timing purposes)
=obj - Emit a native object ('.o') file
我不知道接头,虽然。
另外,我建议您查看tools/bugpoint/ToolRunner.h
文件,它公开了一个包装组合llc
和生成机器码平台的本地C工具链。 从它的头评论:
此文件公开围绕平台C编译器的抽象,用于编译C和汇编代码。
看看这些功能llvm-c/TargetMachine.h
:
/** Emits an asm or object file for the given module to the filename. This
wraps several c++ only classes (among them a file stream). Returns any
error in ErrorMessage. Use LLVMDisposeMessage to dispose the message. */
LLVMBool LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T, LLVMModuleRef M,
char *Filename, LLVMCodeGenFileType codegen, char **ErrorMessage);
/** Compile the LLVM IR stored in \p M and store the result in \p OutMemBuf. */
LLVMBool LLVMTargetMachineEmitToMemoryBuffer(LLVMTargetMachineRef T, LLVMModuleRef M,
LLVMCodeGenFileType codegen, char** ErrorMessage, LLVMMemoryBufferRef *OutMemBuf);
要运行示例BrainF
程序,编译和运行:
echo ,. > test.bf
./BrainF test.bf -o test.bc
llc -filetype=obj test.bc
gcc test.o -o a.out
./a.out
然后键入一个字母,然后按Enter。 应该回应这封信回到你身边。 (这就是,.
确实。)
上述与LLVM版本3.5.0进行测试。