Programlama amacıyla C kaynağının bitlerini derlemek ve bağlamak için clang/llvm kullanıyorum. Ben llvm Linker çözülmemiş externals bir modülde bir hata olarak var olduğu gerçeğini bildirmek için görünmüyor buluyorum.Çözülmeyen dışsalları programlı olarak bulmak için llvm :: Linker'ı kullanma
Ben ettik Aşağıdaki kodu (uzunluk affet, ama bu gerçekten gerekli minimum):
biz hata veriyor sonuna yakın runFunction arayana kadar hiçbir hata her yerde meydanaint CompileAndLink()
{
llvm::InitializeNativeTarget();
std::string code = "int UnresolvedFunction();\n"
"int main() { return UnresolvedFunction(); }";
clang::DiagnosticOptions diagnosticOptions;
clang::TextDiagnosticPrinter tdp(llvm::outs(), diagnosticOptions);
llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> diagIDs(new clang::DiagnosticIDs);
clang::Diagnostic diag(diagIDs, &tdp, false);
clang::FileSystemOptions fsOptions;
clang::FileManager fm(fsOptions);
clang::SourceManager sm(diag, fm);
clang::HeaderSearch hs(fm);
clang::TargetOptions targetOptions;
targetOptions.Triple = llvm::sys::getHostTriple();
clang::TargetInfo* ti = clang::TargetInfo::CreateTargetInfo(diag, targetOptions);
clang::HeaderSearchOptions headerSearchOptions;
clang::LangOptions langOptions;
clang::ApplyHeaderSearchOptions(hs, headerSearchOptions, langOptions, ti->getTriple());
clang::PreprocessorOptions ppo;
clang::Preprocessor pp(diag, langOptions, *ti, sm, hs);
clang::FrontendOptions frontendOptions;
clang::InitializePreprocessor(pp, ppo, headerSearchOptions, frontendOptions);
pp.getBuiltinInfo().InitializeBuiltins(pp.getIdentifierTable(), langOptions);
llvm::MemoryBuffer* sourceBuffer = llvm::MemoryBuffer::getMemBufferCopy(code);
sm.createMainFileIDForMemBuffer(sourceBuffer);
clang::Builtin::Context bic(*ti);
clang::ASTContext astc(langOptions, sm, *ti,
pp.getIdentifierTable(),
pp.getSelectorTable(),
bic,
0);
llvm::LLVMContext lc;
clang::CodeGenOptions codeGenOptions;
llvm::OwningPtr<clang::CodeGenerator> cg;
cg.reset(clang::CreateLLVMCodeGen(diag, "clang_test", codeGenOptions, lc));
if(cg == NULL) {
printf("could not create CodeGenerator\n");
return -1;
}
clang::ParseAST(pp, cg.get(), astc);
if(tdp.getNumErrors()) {
printf("error parsing AST\n");
return -2;
}
llvm::Module* new_module = cg->ReleaseModule();
if(!new_module) {
printf("error generating code\n");
return -2;
}
llvm::Linker linker("clang_test", "clang_test", lc, llvm::Linker::Verbose );
std::string error;
if(linker.LinkInModule(new_module, &error) || !error.empty()) {
printf("link error\n");
return -3;
}
llvm::Module* composite_module = linker.getModule();
if(composite_module == NULL) {
printf("link error\n");
return -3;
}
llvm::ExecutionEngine *pEngine = llvm::ExecutionEngine::create(composite_module,
false,
&error);
if(!error.empty() || pEngine == NULL) {
printf("error creating ExecutionEngine\n");
return -4;
}
llvm::Function* f = composite_module->getFunction("main");
if(f == NULL) {
printf("couldn't find main function\n");
return -5;
}
// This will abort with the message:
// LLVM ERROR: Program used external function 'UnresolvedFunction' which could not be resolved!
std::vector<llvm::GenericValue> params;
llvm::GenericValue result = pEngine->runFunction(f, params);
printf("function main returned %llu\n", result.IntVal.getZExtValue());
return 0;
}
"LLVM HATA : Program çözümlenemeyen 'UnresolvedFunction' harici işlevini kullandı! " iptal edilmeden önce.
Bazı hatalarla başarısız olmak için LinkInModule veya getModule beklenen bekleniyor, ancak bu durum böyle değil. Benim sorum şu: Bir modülün çözülmemiş dışsal varlıklar olduğunu belirlemek için bir yol var mı? Kodun çalıştırılmaya çalışılmaya çalışılmaya çalışılmaması ve çökmemesi için mi? Oldukça uzun bir süredir bir süredir kaynağım var, ve aradığım şeyi bulamıyorum.
Mac OS X'te (x86_64) llvm/clang 2.9 kullanıyorum, eğer önemliyse.
Düzenleme: İstediğimi yapmak görünen LLVM kaynaklardan (LLVM-2.9/lib/Bağlayıcı/LinkArchives.cpp) içinde GetAllUndefinedSymbols
denilen özel fonksiyon, buldum. Sanırım kaçırdığım bir şey için gerçek bir API var mıydı?
GetAllUndefinedSybols'daki koddaki bir varyasyon olan @servn tarafından önerildiği gibi daha fazla veya daha az çalışıyorum. – zpasternack