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

问题描述 投票:3回答:2

我想使用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。

有人在手边有很好的教程吗?

api clang llvm jit
2个回答
1
投票

我建议使用MCJIT,因为旧的JIT基础结构将在进一步的版本中删除。我无法为您提供完整的教程,也无法保证自博客发布以来API并未更改,但是here您将找到如何将LLVM的万花筒示例与MCJIT结合使用的指南。 LLVM / Clang很难找到示例和教程。但是,我建议您尝试一下,也许您可​​以用一个简短的示例来记录您的旅程。

Julia项目还使用MCJIT在Julia lang内对C ++代码进行jit编译。也许您可以浏览一下代码,并了解如何使用MCJIT。

祝你好运;)


0
投票

我跟随this blog post获得了不错的结果。 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将其转储到了临时文件中。

© www.soinside.com 2019 - 2024. All rights reserved.