C++ 如何使用llvm生成机器代码

C++ 如何使用llvm生成机器代码,c++,llvm,machine-code,C++,Llvm,Machine Code,我目前正在使用llvm进行一个编译器项目。我遵循了各种教程,使用解析器创建语法树,然后使用提供的IRBuilder将该树转换为llvm模块 我的目标是创建一个可执行文件,我不知道下一步该怎么做。我找到的所有教程都只是创建llvm模块并使用module.dump()打印程序集。此外,我能找到的唯一文档是针对llvm开发人员的,而不是针对项目的最终用户的 如果我想生成机器代码,接下来的步骤是什么?LLVMMC项目看起来可以做我想做的事情,但是我找不到任何关于它的文档 也许我希望llvm做一些它没有做

我目前正在使用llvm进行一个编译器项目。我遵循了各种教程,使用解析器创建语法树,然后使用提供的IRBuilder将该树转换为llvm模块

我的目标是创建一个可执行文件,我不知道下一步该怎么做。我找到的所有教程都只是创建llvm模块并使用module.dump()打印程序集。此外,我能找到的唯一文档是针对llvm开发人员的,而不是针对项目的最终用户的

如果我想生成机器代码,接下来的步骤是什么?LLVMMC项目看起来可以做我想做的事情,但是我找不到任何关于它的文档

也许我希望llvm做一些它没有做的事情。我的期望是,我可以构建一个模块,然后会有一个API,我可以用该模块调用,并将生成一个目标三元组和一个对象文件。我找到了关于生成JIT的文档和示例,对此我不感兴趣。我正在寻找如何生成已编译的二进制文件

如果有任何影响的话,我正在开发OS X。

正如您所读到的,它实际上是为了生成汇编,然后“汇编语言输出可以通过本机汇编程序和链接器来生成本机可执行文件”——例如gnu汇编程序(
As
)和链接器(
ld

因此,这里的主要答案是使用本机工具进行组装和链接

但是,通过
llc
,可以直接从IR文件生成本机对象:

-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和汇编代码


使用
llc-filetype=obj
从IR发出可链接的对象文件。您可以查看
llc
的代码,以查看它发出此类代码的llvmapi调用。至少对于Mac OS X和Linux来说,以这种方式发出的对象应该是相当好的(也就是说,到目前为止,这不是一个“alpha质量”选项)


但是,LLVM不包含链接器(还没有!)。因此,要将该对象文件实际链接到某个可执行文件或共享库中,需要使用系统链接器。请注意,即使您有一个由单个对象文件组成的可执行文件,也必须链接后者。LLVM社区中的开发人员正在为LLVM开发一个真正的链接器,名为
lld
。您可以访问或搜索邮件列表存档以跟踪其进度。

要运行示例
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测试的。

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);