diff --git a/compiler/include/concretelang/Support/CompilerEngine.h b/compiler/include/concretelang/Support/CompilerEngine.h index e8ea4d90f..b2da151fe 100644 --- a/compiler/include/concretelang/Support/CompilerEngine.h +++ b/compiler/include/concretelang/Support/CompilerEngine.h @@ -120,7 +120,9 @@ public: LINKER_SHARED_OPT, AR, AR_STATIC_OPT, DOT_STATIC_LIB_EXT, DOT_SHARED_LIB_EXT; void addExtraObjectFilePath(std::string objectFilePath); - llvm::Expected emit(std::string dotExt, std::string linker); + llvm::Expected + emit(std::string dotExt, std::string linker, + llvm::Optional> extraArgs = {}); ~Library(); private: diff --git a/compiler/include/concretelang/Support/LLVMEmitFile.h b/compiler/include/concretelang/Support/LLVMEmitFile.h index 3e9001bc7..9701b4e91 100644 --- a/compiler/include/concretelang/Support/LLVMEmitFile.h +++ b/compiler/include/concretelang/Support/LLVMEmitFile.h @@ -11,8 +11,10 @@ namespace concretelang { llvm::Error emitObject(llvm::Module &module, std::string objectPath); -llvm::Error emitLibrary(std::vector objectsPath, - std::string libraryPath, std::string linker); +llvm::Error +emitLibrary(std::vector objectsPath, std::string libraryPath, + std::string linker, + llvm::Optional> extraArgs = {}); } // namespace concretelang } // namespace mlir diff --git a/compiler/lib/ServerLib/DynamicModule.cpp b/compiler/lib/ServerLib/DynamicModule.cpp index ee008f30a..826edf573 100644 --- a/compiler/lib/ServerLib/DynamicModule.cpp +++ b/compiler/lib/ServerLib/DynamicModule.cpp @@ -37,7 +37,7 @@ DynamicModule::loadSharedLibrary(std::string path) { libraryHandle = dlopen( CompilerEngine::Library::getSharedLibraryPath(path).c_str(), RTLD_LAZY); if (!libraryHandle) { - return StringError("Cannot open shared library") << dlerror(); + return StringError("Cannot open shared library ") << dlerror(); } return outcome::success(); } diff --git a/compiler/lib/Support/CompilerEngine.cpp b/compiler/lib/Support/CompilerEngine.cpp index f35f0d096..cc8c839cb 100644 --- a/compiler/lib/Support/CompilerEngine.cpp +++ b/compiler/lib/Support/CompilerEngine.cpp @@ -607,15 +607,12 @@ std::string ensureLibDotExt(std::string path, std::string dotExt) { return path + dotExt; } -llvm::Expected CompilerEngine::Library::emit(std::string dotExt, - std::string linker) { +llvm::Expected CompilerEngine::Library::emit( + std::string dotExt, std::string linker, + llvm::Optional> extraArgs) { auto pathDotExt = ensureLibDotExt(libraryPath, dotExt); - auto objectsPathWithRuntimeLib = objectsPath; - if (!runtimeLibraryPath.empty()) { - objectsPathWithRuntimeLib.push_back(runtimeLibraryPath); - } - auto error = mlir::concretelang::emitLibrary(objectsPathWithRuntimeLib, - pathDotExt, linker); + auto error = mlir::concretelang::emitLibrary(objectsPath, pathDotExt, linker, + extraArgs); if (error) { return std::move(error); } @@ -623,7 +620,21 @@ llvm::Expected CompilerEngine::Library::emit(std::string dotExt, } llvm::Expected CompilerEngine::Library::emitShared() { - auto path = emit(DOT_SHARED_LIB_EXT, LINKER + LINKER_SHARED_OPT); + std::vector extraArgs; + if (!runtimeLibraryPath.empty()) { + extraArgs.push_back(runtimeLibraryPath); +#ifndef __APPLE__ // LINUX + // Getting the parent dir should work on Linux and Mac + std::size_t rpathLastPos = runtimeLibraryPath.find_last_of("/"); + if (rpathLastPos != std::string::npos) { + std::string rpath = runtimeLibraryPath.substr(0, rpathLastPos); + extraArgs.push_back("-rpath=" + rpath); + // Use RPATH instead of RUNPATH for transitive dependencies + extraArgs.push_back("--disable-new-dtags"); + } +#endif + } + auto path = emit(DOT_SHARED_LIB_EXT, LINKER + LINKER_SHARED_OPT, extraArgs); if (path) { sharedLibraryPath = path.get(); } diff --git a/compiler/lib/Support/LLVMEmitFile.cpp b/compiler/lib/Support/LLVMEmitFile.cpp index 5c8d53a61..b8a948e9e 100644 --- a/compiler/lib/Support/LLVMEmitFile.cpp +++ b/compiler/lib/Support/LLVMEmitFile.cpp @@ -69,12 +69,17 @@ llvm::Error emitObject(llvm::Module &module, string objectPath) { return llvm::Error::success(); } -string linkerCmd(vector objectsPath, string libraryPath, - string linker) { +string linkerCmd(vector objectsPath, string libraryPath, string linker, + llvm::Optional> extraArgs) { string cmd = linker + libraryPath; for (auto objectPath : objectsPath) { cmd += " " + objectPath; } + if (extraArgs.hasValue()) { + for (auto extraArg : extraArgs.getValue()) { + cmd += " " + extraArg; + } + } cmd += " 2>&1"; // to keep stderr with popen return cmd; } @@ -105,8 +110,9 @@ llvm::Error callCmd(string cmd) { } llvm::Error emitLibrary(vector objectsPath, string libraryPath, - string linker) { - auto cmd = linkerCmd(objectsPath, libraryPath, linker); + string linker, + llvm::Optional> extraArgs) { + auto cmd = linkerCmd(objectsPath, libraryPath, linker, extraArgs); return callCmd(cmd); }