diff --git a/openmp/libomptarget/src/rtl.cpp b/openmp/libomptarget/src/rtl.cpp --- a/openmp/libomptarget/src/rtl.cpp +++ b/openmp/libomptarget/src/rtl.cpp @@ -69,6 +69,22 @@ #endif } +namespace { +std::string findLibomptargetDirectory() { + Dl_info Dlinfo; + // look up a symbol which is known to be from libomptarget.so as a portable + // way of locating the path to libomptarget.so from within libomtarget + if (dladdr((void *)&__tgt_register_lib, &Dlinfo) != 0) { + std::string LibomptargetPath = std::string(Dlinfo.dli_fname); + size_t Slash = LibomptargetPath.find_last_of('/'); + if (Slash != std::string::npos) { + return LibomptargetPath.substr(0, Slash + 1); // keep the / + } + } + return ""; +} +} // namespace + void RTLsTy::LoadRTLs() { // Parse environment variable OMP_TARGET_OFFLOAD (if set) PM->TargetOffloadPolicy = @@ -78,12 +94,17 @@ } DP("Loading RTLs...\n"); + const std::string LibomptargetPath = findLibomptargetDirectory(); + const bool NoLibomptargetPath = LibomptargetPath == ""; // Attempt to open all the plugins and, if they exist, check if the interface // is correct and if they are supporting any devices. for (auto *Name : RTLNames) { DP("Loading library '%s'...\n", Name); - void *dynlib_handle = dlopen(Name, RTLD_NOW); + std::string AdjacentPluginName = LibomptargetPath + std::string(Name); + void *dynlib_handle = NoLibomptargetPath + ? nullptr + : dlopen(AdjacentPluginName.c_str(), RTLD_NOW); if (!dynlib_handle) { // Library does not exist or cannot be found.