Split loadFile() into two and we have a new interface loadLibrary()!

Prepare new result "library was alreday loaded" - will be implemented if we actually need it.


git-svn-id: http://root.cern.ch/svn/root/trunk@47319 27541ba8-7e3a-0410-8455-c3a389f83636
This commit is contained in:
Axel Naumann 2012-11-15 14:50:59 +00:00
parent b7beb7fabe
commit 8616cc7bea
2 changed files with 71 additions and 32 deletions

View File

@ -392,6 +392,24 @@ namespace cling {
CompilationResult loadFile(const std::string& filename,
bool allowSharedLib = true);
enum LoadLibResult {
LoadLibSuccess, // library loaded successfully
//not yet: kLoadLibExists, // library was alreday loaded
LoadLibError, // library was not found
LoadLibNumResults
};
///\brief Loads a shared library.
///
///\param [in] filename - The file to loaded.
///
///\returns LoadLibSuccess on success, LoadLibExists if the library was
/// already loaded, LoadLibError if the library cannot be found or any
/// other error was encountered.
///
///
LoadLibResult loadLibrary(const std::string& filename, bool permanent);
void enableDynamicLookup(bool value = true);
bool isDynamicLookupEnabled() { return m_DynamicLookupEnabled; }

View File

@ -40,9 +40,9 @@
using namespace clang;
namespace {
static bool tryLinker(const std::string& filename,
const cling::InvocationOptions& Opts,
llvm::Module* module) {
static cling::Interpreter::LoadLibResult
tryLinker(const std::string& filename, const cling::InvocationOptions& Opts,
llvm::Module* module, bool permanent) {
assert(module && "Module must exist for linking!");
llvm::Linker L("cling", module, llvm::Linker::QuietWarnings
| llvm::Linker::QuietErrors);
@ -60,7 +60,7 @@ static bool tryLinker(const std::string& filename,
if (!FilePath.getMagicNumber(Magic, 64)) {
// filename doesn't exist...
L.releaseModule();
return false;
return cling::Interpreter::LoadLibError;
}
if (llvm::sys::IdentifyFileType(Magic.c_str(), 64)
== llvm::sys::Bitcode_FileType) {
@ -68,30 +68,43 @@ static bool tryLinker(const std::string& filename,
L.setFlags(0);
if (L.LinkInFile(llvm::sys::Path(filename), Native)) {
L.releaseModule();
return false;
return cling::Interpreter::LoadLibError;
}
} else {
// Nothing the linker can handle
L.releaseModule();
return false;
return cling::Interpreter::LoadLibError;
}
} else if (Native) {
// native shared library, load it!
llvm::sys::Path SoFile = L.FindLib(filename);
assert(!SoFile.isEmpty() && "The shared lib exists but can't find it!");
std::string errMsg;
bool hasError = llvm::sys::DynamicLibrary
::LoadLibraryPermanently(SoFile.str().c_str(), &errMsg);
if (hasError) {
llvm::errs() << "Could not load shared library!\n"
<< "\n"
<< errMsg.c_str();
// TODO: !permanent case, LoadResAlreadyLoaded case.
cling::Interpreter::LoadLibResult res;
#if 0
switch (llvm::sys::DynamicLibrary::
LoadLibraryPermanently(SoFile.str().c_str(), &errMsg)) {
case llvm::sys::DynamicLibrary::LoadResSuccess:
res = cling::Interpreter::LoadLibSuccess;
case llvm::sys::DynamicLibrary::LoadResError:
llvm::errs() << "Could not load shared library!\n\n" << errMsg.c_str();
L.releaseModule();
return false;
res = cling::Interpreter::LoadLibError;
case llvm::sys::DynamicLibrary::LoadResAlreadyLoaded:
res = cling::Interpreter::LoadLibExists;
}
#endif
if (llvm::sys::DynamicLibrary::
LoadLibraryPermanently(SoFile.str().c_str(), &errMsg)) {
res = cling::Interpreter::LoadLibSuccess;
} else {
res = cling::Interpreter::LoadLibError;
}
L.releaseModule();
return res;
}
L.releaseModule();
return true;
return cling::Interpreter::LoadLibError;
}
static bool canWrapForCall(const std::string& input_line) {
@ -582,29 +595,37 @@ namespace cling {
return Interpreter::kFailure;
}
Interpreter::CompilationResult
Interpreter::loadFile(const std::string& filename,
bool allowSharedLib /*=true*/) {
if (allowSharedLib) {
llvm::Module* module = m_IncrParser->getCodeGenerator()->GetModule();
if (module) {
if (tryLinker(filename, getOptions(), module))
return kSuccess;
if (filename.compare(0, 3, "lib") == 0) {
// starts with "lib", try without (the llvm::Linker forces
// a "lib" in front, which makes it liblib...
if (tryLinker(filename.substr(3, std::string::npos),
getOptions(), module))
return kSuccess;
}
}
}
Interpreter::CompilationResult
Interpreter::loadFile(const std::string& filename,
bool allowSharedLib /*=true*/) {
if (allowSharedLib && loadLibrary(filename, false) == LoadLibSuccess)
return kSuccess;
std::string code;
code += "#include \"" + filename + "\"";
return declare(code);
}
Interpreter::LoadLibResult
Interpreter::loadLibrary(const std::string& filename, bool permanent) {
llvm::Module* module = m_IncrParser->getCodeGenerator()->GetModule();
if (module) {
LoadLibResult res = tryLinker(filename, getOptions(), module, permanent);
if (res != LoadLibError) {
return res;
}
if (filename.compare(0, 3, "lib") == 0) {
// starts with "lib", try without (the llvm::Linker forces
// a "lib" in front, which makes it liblib...
res = tryLinker(filename.substr(3, std::string::npos),
getOptions(), module, permanent);
if (res != LoadLibError)
return res;
}
}
return LoadLibError;
}
void Interpreter::installLazyFunctionCreator(void* (*fp)(const std::string&)) {
m_ExecutionContext->installLazyFunctionCreator(fp);
}