4#include <gemc/glogging/glogger.h>
5#include <gemc/guts/gutilities.h>
24static dlhandle load_lib(
const std::string& path);
25static void close_lib(
dlhandle handle);
59 std::string dlFileName;
66 bool doesFileExists(
const std::string& name) {
68 return (stat(name.c_str(), &buffer) == 0);
72 std::shared_ptr<GLogger> log;
87 DynamicLib(std::shared_ptr<GLogger> logger, std::string path) : dlFileName(path), log(logger),
handle(nullptr) {
89 log->debug(
NORMAL,
"Trying ", dlFileName);
92 if (!doesFileExists(dlFileName)) {
93 log->debug(
NORMAL, dlFileName,
" not found...");
95 if (
const char* envPath = std::getenv(
"GEMC_PLUGIN_PATH")) {
96 std::istringstream ss(envPath);
98 while (std::getline(ss, dir,
':')) {
99 const std::string candidate = dir +
"/" + path;
100 if (doesFileExists(candidate)) {
101 dlFileName = candidate;
106 log->debug(
NORMAL,
"Trying ", dlFileName);
110 if (!doesFileExists(dlFileName)) {
111 log->debug(
NORMAL, dlFileName,
" not found...");
114 dlFileName = gemcRoot.string() +
"/lib/" + path;
116 log->debug(
NORMAL,
"Trying ", dlFileName);
120 if (!doesFileExists(dlFileName)) {
121 log->debug(
NORMAL, dlFileName,
" not found...");
124 dlFileName = gemcRoot.string() +
"/build/" + path;
126 log->debug(
NORMAL,
"Trying ", dlFileName);
129 if (doesFileExists(dlFileName)) {
130 dlFileName = std::filesystem::absolute(dlFileName).string();
131 handle = load_lib(dlFileName);
133 char const*
const dlopen_error = dlerror();
135 " found, but handle is null. dlopen_error >> ",
136 dlopen_error !=
nullptr ? dlopen_error :
"unknown dlopen error");
138 else { log->info(1,
"Loaded ", dlFileName); }
141 const char* envPath = std::getenv(
"GEMC_PLUGIN_PATH");
143 "could not find ", dlFileName,
"\n",
144 " GEMC_PLUGIN_PATH = ", (envPath ? envPath :
"(not set)"),
"\n",
145 " Hint: set GEMC_PLUGIN_PATH or use -plugin_path=<dir> to the directory ",
146 "containing *.gplugin files.");
165 log->debug(
DESTRUCTOR,
"Destroying ", dlFileName);
182dlhandle load_lib(
const std::string& lib)
186#if defined(__linux__) && defined(RTLD_NODELETE)
187 constexpr int dlopen_flags = RTLD_NOW | RTLD_NODELETE;
189 constexpr int dlopen_flags = RTLD_NOW;
193 if (lib.find(
'/') != std::string::npos) { h = dlopen(lib.c_str(), dlopen_flags); }
196 std::string cwdPath =
"./" + lib;
197 h = dlopen(cwdPath.c_str(), dlopen_flags);
201 if (!h) { h = dlopen(lib.c_str(), dlopen_flags); }
210static void close_lib(
dlhandle handle) { dlclose(handle); }
void * dlhandle
Opaque handle returned by dlopen and consumed by dlsym / dlclose.
constexpr int ERR_FACTORYNOTFOUND
constexpr int ERR_DLHANDLENOTFOUND
constexpr int ERR_DLNOTFOUND
std::filesystem::path gemc_root()
DynamicLib(std::shared_ptr< GLogger > logger, std::string path)
Construct and attempt to load a dynamic library.
dlhandle handle
POSIX handle of the dynamic library.
~DynamicLib()
Destructor closes the library handle (if loaded).
DynamicLib()=default
Default constructor (does not load anything).