使用 clang API 编译并运行 C 代码



我想使用 clang/llvm API 编译一个在字符串中定义的 c 函数并立即执行它。像这样:

void main() {
  std::string codestr = "int foo(int bar) { return bar * 2; }"
  clang::??? *code = clang::???.compile(codestr);
  int result = code->call("foo", 5);
}

正在寻找教程,但到目前为止我发现的内容与我的目标不太相符或不起作用,因为它指的是 LLVM 的过时版本。目前,我正在使用LLVM 3.5。

有人手头有好的教程吗?

我关注了这篇博文,取得了很好的效果。clang API 已更改,因此您可能需要进行调整。使用 LLVM 3.6.1,我使用以下代码获得了良好的结果:

llvm::Module* compile(const char* filename) {                                                   
        clang::CompilerInstance compiler;                                                     
        clang::CompilerInvocation* invocation = new clang::CompilerInvocation();              
        llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagID(new clang::DiagnosticIDs());    
        auto diagOptions = new clang::DiagnosticOptions();                                    
        clang::DiagnosticsEngine Diags(DiagID, diagOptions,                                   
                new clang::TextDiagnosticPrinter(llvm::errs(), diagOptions));                 
        std::vector<const char *> arguments = {filename};            
        clang::CompilerInvocation::CreateFromArgs(*invocation,                                
                &*arguments.begin(), &*arguments.end(),                                       
                Diags);                                                                       
        compiler.setInvocation(invocation);                                                   
        compiler.setDiagnostics(new clang::DiagnosticsEngine(DiagID, diagOptions,                                   
                new clang::TextDiagnosticPrinter(llvm::errs(), diagOptions)));                                                      
        std::unique_ptr<clang::CodeGenAction> action(new clang::EmitLLVMOnlyAction());        
        compiler.ExecuteAction(*action);                                                      
        std::unique_ptr<llvm::Module> result = action->takeModule();                          
        llvm::errs() << *result;                                                              
        return result.release();                                                              
}                                                                                             

我对指针非常粗心,所以很可能存在内存泄漏或双重释放(尽管它没有崩溃)。

我不知道如何从内存缓冲区中获取源代码,所以我使用 mkstemp 将其转储到临时文件中。

我没有开始执行结果,但我认为您可以遵循@michael-haidi的响应,或者查看LLVM万花筒教程(这是JIT章节)。

我建议使用 MCJIT,因为旧的 JIT 基础结构将在进一步的版本中删除。我不能向您指出完整的教程,也不能保证自博客文章以来API没有更改,但在这里您将找到如何将MCJIT与LLVM的万花筒示例一起使用的指南,仅此而已。LLVM/Clang 很难找到示例和教程。但是,我建议尝试一下,也许你可以用一个简短的例子来记录你的旅程。

Julia 项目还使用 MCJIT 对 Julia lang 内部的C++代码进行 jit 编译。也许你可以偷看代码,找出如何使用MCJIT的。

祝你好运;)

相关内容

最新更新