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);
28#define ERR_DLNOTFOUND 1001
29#define ERR_FACTORYNOTFOUND 1002
30#define ERR_DLHANDLENOTFOUND 1003
57 std::string dlFileName;
64 bool doesFileExists(
const std::string& name) {
66 return (stat(name.c_str(), &buffer) == 0);
70 std::shared_ptr<GLogger> log;
85 DynamicLib(std::shared_ptr<GLogger> logger, std::string path) : dlFileName(path), log(logger),
handle(nullptr) {
87 log->debug(
NORMAL,
"Trying ", dlFileName);
90 if (!doesFileExists(dlFileName)) {
91 log->debug(
NORMAL, dlFileName,
" not found...");
93 if (
const char* envPath = std::getenv(
"GEMC_PLUGIN_PATH")) {
94 std::istringstream ss(envPath);
96 while (std::getline(ss, dir,
':')) {
97 const std::string candidate = dir +
"/" + path;
98 if (doesFileExists(candidate)) {
99 dlFileName = candidate;
104 log->debug(
NORMAL,
"Trying ", dlFileName);
108 if (!doesFileExists(dlFileName)) {
109 log->debug(
NORMAL, dlFileName,
" not found...");
112 dlFileName = gemcRoot.string() +
"/lib/" + path;
114 log->debug(
NORMAL,
"Trying ", dlFileName);
118 if (!doesFileExists(dlFileName)) {
119 log->debug(
NORMAL, dlFileName,
" not found...");
122 dlFileName = gemcRoot.string() +
"/build/" + path;
124 log->debug(
NORMAL,
"Trying ", dlFileName);
127 if (doesFileExists(dlFileName)) {
128 dlFileName = std::filesystem::absolute(dlFileName).string();
129 handle = load_lib(dlFileName);
131 char const*
const dlopen_error = dlerror();
132 log->error(
ERR_DLHANDLENOTFOUND,
"File ", dlFileName,
" found, but handle is null. dlopen_error >> ",
133 dlopen_error !=
nullptr ? dlopen_error :
"unknown dlopen error");
135 else { log->info(1,
"Loaded ", dlFileName); }
138 const char* envPath = std::getenv(
"GEMC_PLUGIN_PATH");
140 "could not find ", dlFileName,
"\n",
141 " GEMC_PLUGIN_PATH = ", (envPath ? envPath :
"(not set)"),
"\n",
142 " Hint: set GEMC_PLUGIN_PATH or use -plugin_path=<dir> to the directory ",
143 "containing *.gplugin files.");
162 log->debug(
DESTRUCTOR,
"Destroying ", dlFileName);
179dlhandle load_lib(
const std::string& lib)
183#if defined(__linux__) && defined(RTLD_NODELETE)
184 constexpr int dlopen_flags = RTLD_NOW | RTLD_NODELETE;
186 constexpr int dlopen_flags = RTLD_NOW;
190 if (lib.find(
'/') != std::string::npos) { h = dlopen(lib.c_str(), dlopen_flags); }
193 std::string cwdPath =
"./" + lib;
194 h = dlopen(cwdPath.c_str(), dlopen_flags);
198 if (!h) { h = dlopen(lib.c_str(), dlopen_flags); }
207static void close_lib(
dlhandle handle) { dlclose(handle); }
#define ERR_DLHANDLENOTFOUND
void * dlhandle
Opaque handle returned by dlopen and consumed by dlsym / dlclose.
std::filesystem::path gemc_root()
Helper that loads a shared library and holds its POSIX handle.
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).