mirror of https://github.com/KLayout/klayout.git
A little refactoring - central place for DLL/.so path detection
This commit is contained in:
parent
3d7bd0f32d
commit
3fb568671d
|
|
@ -95,46 +95,11 @@ static PluginDescriptor load_plugin (const std::string &pp)
|
||||||
return desc;
|
return desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Gets the path to the current module
|
|
||||||
*/
|
|
||||||
static std::string
|
|
||||||
get_module_path ()
|
|
||||||
{
|
|
||||||
#if defined(_WIN32)
|
|
||||||
|
|
||||||
HMODULE h_module = NULL;
|
|
||||||
if (GetModuleHandleEx (GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPCTSTR) &init, &h_module)) {
|
|
||||||
|
|
||||||
wchar_t buffer[MAX_PATH];
|
|
||||||
int len;
|
|
||||||
if ((len = GetModuleFileName(h_module, buffer, MAX_PATH)) > 0) {
|
|
||||||
return tl::absolute_file_path (tl::to_string (std::wstring (buffer, 0, len)));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// no way to get module file path
|
|
||||||
return std::string ();
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
Dl_info info = { };
|
|
||||||
if (dladdr ((void *) &init, &info)) {
|
|
||||||
return tl::absolute_file_path (tl::to_string_from_local (info.dli_fname));
|
|
||||||
} else {
|
|
||||||
tl::warn << tl::to_string (tr ("Unable to get path of db library (as basis for loading db_plugins)"));
|
|
||||||
return std::string ();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void init (const std::vector<std::string> &_paths)
|
void init (const std::vector<std::string> &_paths)
|
||||||
{
|
{
|
||||||
std::vector<std::string> paths = _paths;
|
std::vector<std::string> paths = _paths;
|
||||||
if (paths.empty ()) {
|
if (paths.empty ()) {
|
||||||
std::string module_path = get_module_path ();
|
std::string module_path = tl::get_module_path ((void *) &init);
|
||||||
if (! module_path.empty ()) {
|
if (! module_path.empty ()) {
|
||||||
paths.push_back (tl::absolute_path (module_path));
|
paths.push_back (tl::absolute_path (module_path));
|
||||||
}
|
}
|
||||||
|
|
@ -154,6 +119,8 @@ void init (const std::vector<std::string> &_paths)
|
||||||
const char *db_plugin_dir = "db_plugins";
|
const char *db_plugin_dir = "db_plugins";
|
||||||
std::string pp = tl::combine_path (*p, db_plugin_dir);
|
std::string pp = tl::combine_path (*p, db_plugin_dir);
|
||||||
|
|
||||||
|
tl::log << tl::sprintf (tl::to_string (tr ("Scanning '%s'' for plugins ..")), pp);
|
||||||
|
|
||||||
std::vector<std::string> ee = tl::dir_entries (pp, true, false);
|
std::vector<std::string> ee = tl::dir_entries (pp, true, false);
|
||||||
|
|
||||||
tl::GlobPattern pattern;
|
tl::GlobPattern pattern;
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@
|
||||||
#include "tlLog.h"
|
#include "tlLog.h"
|
||||||
#include "tlString.h"
|
#include "tlString.h"
|
||||||
#include "tlFileUtils.h"
|
#include "tlFileUtils.h"
|
||||||
|
#include "tlGlobPattern.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
|
|
@ -95,47 +96,11 @@ void load_plugin (const std::string &pp)
|
||||||
s_plugins.push_back (do_load_plugin (pp));
|
s_plugins.push_back (do_load_plugin (pp));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Gets the path to the current module
|
|
||||||
*/
|
|
||||||
static std::string
|
|
||||||
get_module_path ()
|
|
||||||
{
|
|
||||||
#if defined(_WIN32)
|
|
||||||
|
|
||||||
HMODULE h_module = NULL;
|
|
||||||
if (GetModuleHandleEx (GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPCTSTR) &init, &h_module)) {
|
|
||||||
|
|
||||||
wchar_t buffer[MAX_PATH];
|
|
||||||
int len;
|
|
||||||
if ((len = GetModuleFileName(h_module, buffer, MAX_PATH)) > 0) {
|
|
||||||
QFileInfo fi (QString::fromUtf16 ((const ushort *) buffer, len));
|
|
||||||
return tl::to_string (fi.absolutePath ());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// no way to get module file path
|
|
||||||
return std::string ();
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
Dl_info info = { };
|
|
||||||
if (dladdr ((void *) &init, &info)) {
|
|
||||||
return tl::absolute_file_path (tl::to_string_from_local (info.dli_fname));
|
|
||||||
} else {
|
|
||||||
tl::warn << tl::to_string (tr ("Unable to get path of lay library (as basis for loading lay_plugins)"));
|
|
||||||
return std::string ();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void init (const std::vector<std::string> &_paths)
|
void init (const std::vector<std::string> &_paths)
|
||||||
{
|
{
|
||||||
std::vector<std::string> paths = _paths;
|
std::vector<std::string> paths = _paths;
|
||||||
if (paths.empty ()) {
|
if (paths.empty ()) {
|
||||||
std::string module_path = get_module_path ();
|
std::string module_path = tl::get_module_path ((void *) &init);
|
||||||
if (! module_path.empty ()) {
|
if (! module_path.empty ()) {
|
||||||
paths.push_back (module_path);
|
paths.push_back (module_path);
|
||||||
}
|
}
|
||||||
|
|
@ -151,38 +116,41 @@ void init (const std::vector<std::string> &_paths)
|
||||||
|
|
||||||
for (std::vector<std::string>::const_iterator p = paths.begin (); p != paths.end (); ++p) {
|
for (std::vector<std::string>::const_iterator p = paths.begin (); p != paths.end (); ++p) {
|
||||||
|
|
||||||
// look next to the db library, but in "lay_plugins" directory
|
// look next to the lay library, but in "lay_plugins" directory
|
||||||
const char *db_plugin_dir = "lay_plugins";
|
const char *lay_plugin_dir = "lay_plugins";
|
||||||
std::string pp = tl::to_string (QDir (tl::to_qstring (*p)).filePath (QString::fromUtf8 (db_plugin_dir)));
|
std::string pp = tl::combine_path (*p, lay_plugin_dir);
|
||||||
|
|
||||||
QStringList name_filters;
|
tl::log << tl::sprintf (tl::to_string (tr ("Scanning '%s'' for plugins ..")), pp);
|
||||||
|
|
||||||
|
std::vector<std::string> ee = tl::dir_entries (pp, true, false);
|
||||||
|
|
||||||
|
tl::GlobPattern pattern;
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
name_filters << QString::fromUtf8 ("*.dll");
|
pattern.set_case_sensitive (false);
|
||||||
|
pattern = std::string ("*.dll");
|
||||||
#else
|
#else
|
||||||
name_filters << QString::fromUtf8 ("*.so");
|
pattern = std::string ("*.so");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QStringList inst_modules = QDir (tl::to_qstring (pp)).entryList (name_filters);
|
std::vector<std::string> inst_modules;
|
||||||
inst_modules.sort ();
|
for (std::vector<std::string>::const_iterator e = ee.begin (); e != ee.end (); ++e) {
|
||||||
|
if (pattern.match (*e)) {
|
||||||
|
inst_modules.push_back (*e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (QStringList::const_iterator im = inst_modules.begin (); im != inst_modules.end (); ++im) {
|
std::sort (inst_modules.begin (), inst_modules.end ());
|
||||||
|
|
||||||
QFileInfo layp_file (tl::to_qstring (pp), *im);
|
for (std::vector<std::string>::const_iterator im = inst_modules.begin (); im != inst_modules.end (); ++im) {
|
||||||
if (layp_file.exists () && layp_file.isReadable ()) {
|
|
||||||
|
|
||||||
std::string mn = tl::to_string (layp_file.fileName ());
|
|
||||||
if (modules.find (mn) == modules.end ()) {
|
|
||||||
|
|
||||||
std::string m = tl::to_string (layp_file.absoluteFilePath ());
|
|
||||||
try {
|
|
||||||
s_plugins.push_back (do_load_plugin (m));
|
|
||||||
modules.insert (mn);
|
|
||||||
} catch (tl::Exception (&ex)) {
|
|
||||||
tl::error << ex.msg ();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
std::string imp = tl::combine_path (pp, *im);
|
||||||
|
if (modules.find (*im) == modules.end ()) {
|
||||||
|
try {
|
||||||
|
s_plugins.push_back (do_load_plugin (imp));
|
||||||
|
modules.insert (*im);
|
||||||
|
} catch (tl::Exception (&ex)) {
|
||||||
|
tl::error << ex.msg ();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,10 @@
|
||||||
# include <libproc.h>
|
# include <libproc.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(_WIN32)
|
||||||
|
# include <dlfcn.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace tl
|
namespace tl
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -790,4 +794,36 @@ get_inst_path ()
|
||||||
return s_inst_path;
|
return s_inst_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
get_module_path (void *addr)
|
||||||
|
{
|
||||||
|
#if defined(_WIN32)
|
||||||
|
|
||||||
|
HMODULE h_module = NULL;
|
||||||
|
if (GetModuleHandleEx (GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPCTSTR) addr, &h_module)) {
|
||||||
|
|
||||||
|
wchar_t buffer[MAX_PATH];
|
||||||
|
int len;
|
||||||
|
if ((len = GetModuleFileName(h_module, buffer, MAX_PATH)) > 0) {
|
||||||
|
return tl::absolute_file_path (tl::to_string (std::wstring (buffer, 0, len)));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// no way to get module file path
|
||||||
|
return std::string ();
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
Dl_info info = { };
|
||||||
|
if (dladdr (addr, &info)) {
|
||||||
|
return tl::absolute_file_path (tl::to_string_from_local (info.dli_fname));
|
||||||
|
} else {
|
||||||
|
tl::warn << tl::to_string (tr ("Unable to get path of db library (as basis for loading db_plugins)"));
|
||||||
|
return std::string ();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -178,6 +178,12 @@ std::vector<std::string> TL_PUBLIC split_path (const std::string &p, bool keep_l
|
||||||
*/
|
*/
|
||||||
std::string TL_PUBLIC get_inst_path ();
|
std::string TL_PUBLIC get_inst_path ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the absolute path of the module (DLL/.so) which contains the given address
|
||||||
|
* "address" is supposed to be the address of a function inside the module.
|
||||||
|
*/
|
||||||
|
std::string TL_PUBLIC get_module_path (void *addr);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue