Load sibling libraries from the same directory
When libEGL and either libGLESv2 or libGLES_CM are in a different
folder from the executable's folder, libEGL wasn't successfully
finding libGLESv2/libGLES_CM (or vice versa). Since these libraries
are generally in the same folder, using the current library's folder
as a starting location to find another library solves this issue.
Change-Id: Ice9217411de4e269d511549411297b57fc1a4bbb
Reviewed-on: https://swiftshader-review.googlesource.com/18548
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/Common/SharedLibrary.hpp b/src/Common/SharedLibrary.hpp
index ab710eb..85e5e7d 100644
--- a/src/Common/SharedLibrary.hpp
+++ b/src/Common/SharedLibrary.hpp
@@ -21,14 +21,35 @@
#include <dlfcn.h>
#endif
+#include <string>
+
void *getLibraryHandle(const char *path);
void *loadLibrary(const char *path);
void freeLibrary(void *library);
void *getProcAddress(void *library, const char *name);
template<int n>
-void *loadLibrary(const char *(&names)[n], const char *mustContainSymbol = nullptr)
+void *loadLibrary(const std::string &libraryDirectory, const char *(&names)[n], const char *mustContainSymbol = nullptr)
{
+ if(!libraryDirectory.empty())
+ {
+ for(int i = 0; i < n; i++)
+ {
+ std::string nameWithPath = libraryDirectory + names[i];
+ void *library = getLibraryHandle(nameWithPath.c_str());
+
+ if(library)
+ {
+ if(!mustContainSymbol || getProcAddress(library, mustContainSymbol))
+ {
+ return library;
+ }
+
+ freeLibrary(library);
+ }
+ }
+ }
+
for(int i = 0; i < n; i++)
{
void *library = getLibraryHandle(names[i]);
@@ -84,6 +105,22 @@
{
return (void*)GetProcAddress((HMODULE)library, name);
}
+
+ inline std::string getLibraryDirectoryFromSymbol(void* symbol)
+ {
+ HMODULE module = NULL;
+ GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)symbol, &module);
+ char filename[1024];
+ if(module && (GetModuleFileName(module, filename, sizeof(filename)) != 0))
+ {
+ std::string directory(filename);
+ return directory.substr(0, directory.find_last_of("\\/") + 1).c_str();
+ }
+ else
+ {
+ return "";
+ }
+ }
#else
inline void *loadLibrary(const char *path)
{
@@ -127,6 +164,20 @@
return symbol;
}
+
+ inline std::string getLibraryDirectoryFromSymbol(void* symbol)
+ {
+ Dl_info dl_info;
+ if(dladdr(symbol, &dl_info) != 0)
+ {
+ std::string directory(dl_info.dli_fname);
+ return directory.substr(0, directory.find_last_of("\\/") + 1).c_str();
+ }
+ else
+ {
+ return "";
+ }
+ }
#endif
#endif // SharedLibrary_hpp
diff --git a/src/OpenGL/libEGL/libEGL.hpp b/src/OpenGL/libEGL/libEGL.hpp
index 46e319a..7ef0d31 100644
--- a/src/OpenGL/libEGL/libEGL.hpp
+++ b/src/OpenGL/libEGL/libEGL.hpp
@@ -73,10 +73,8 @@
class LibEGL
{
public:
- LibEGL()
+ LibEGL(const std::string libraryDirectory) : libraryDirectory(libraryDirectory)
{
- libEGL = nullptr;
- libEGLexports = nullptr;
}
~LibEGL()
@@ -124,7 +122,7 @@
#error "libEGL::loadExports unimplemented for this platform"
#endif
- libEGL = loadLibrary(libEGL_lib, "libEGL_swiftshader");
+ libEGL = loadLibrary(libraryDirectory, libEGL_lib, "libEGL_swiftshader");
if(libEGL)
{
@@ -136,8 +134,9 @@
return libEGLexports;
}
- void *libEGL;
- LibEGLexports *libEGLexports;
+ void *libEGL = nullptr;
+ LibEGLexports *libEGLexports = nullptr;
+ const std::string libraryDirectory;
};
#endif // libEGL_hpp
diff --git a/src/OpenGL/libEGL/main.cpp b/src/OpenGL/libEGL/main.cpp
index a1ff6f1..c850610 100644
--- a/src/OpenGL/libEGL/main.cpp
+++ b/src/OpenGL/libEGL/main.cpp
@@ -649,5 +649,5 @@
return &libEGL;
}
-LibGLES_CM libGLES_CM;
-LibGLESv2 libGLESv2;
+LibGLES_CM libGLES_CM(getLibraryDirectoryFromSymbol((void*)libEGL_swiftshader));
+LibGLESv2 libGLESv2(getLibraryDirectoryFromSymbol((void*)libEGL_swiftshader));
diff --git a/src/OpenGL/libGLES_CM/libGLES_CM.hpp b/src/OpenGL/libGLES_CM/libGLES_CM.hpp
index d6740ec..b9c29f5 100644
--- a/src/OpenGL/libGLES_CM/libGLES_CM.hpp
+++ b/src/OpenGL/libGLES_CM/libGLES_CM.hpp
@@ -229,10 +229,8 @@
class LibGLES_CM
{
public:
- LibGLES_CM()
+ LibGLES_CM(const std::string libraryDirectory) : libraryDirectory(libraryDirectory)
{
- libGLES_CM = nullptr;
- libGLES_CMexports = nullptr;
}
~LibGLES_CM()
@@ -285,7 +283,7 @@
#error "libGLES_CM::loadExports unimplemented for this platform"
#endif
- libGLES_CM = loadLibrary(libGLES_CM_lib, "libGLES_CM_swiftshader");
+ libGLES_CM = loadLibrary(libraryDirectory, libGLES_CM_lib, "libGLES_CM_swiftshader");
if(libGLES_CM)
{
@@ -297,8 +295,9 @@
return libGLES_CMexports;
}
- void *libGLES_CM;
- LibGLES_CMexports *libGLES_CMexports;
+ void *libGLES_CM = nullptr;
+ LibGLES_CMexports *libGLES_CMexports = nullptr;
+ const std::string libraryDirectory;
};
#endif // libGLES_CM_hpp
diff --git a/src/OpenGL/libGLES_CM/main.cpp b/src/OpenGL/libGLES_CM/main.cpp
index f2bd0b7..ea56c81 100644
--- a/src/OpenGL/libGLES_CM/main.cpp
+++ b/src/OpenGL/libGLES_CM/main.cpp
@@ -1610,4 +1610,4 @@
return &libGLES_CM;
}
-LibEGL libEGL;
+LibEGL libEGL(getLibraryDirectoryFromSymbol((void*)libGLES_CM_swiftshader));
diff --git a/src/OpenGL/libGLESv2/entry_points.cpp b/src/OpenGL/libGLESv2/entry_points.cpp
index b142b85..378f9fe 100644
--- a/src/OpenGL/libGLESv2/entry_points.cpp
+++ b/src/OpenGL/libGLESv2/entry_points.cpp
@@ -1426,5 +1426,5 @@
return &libGLESv2;
}
-LibEGL libEGL;
-LibGLES_CM libGLES_CM;
+LibEGL libEGL(getLibraryDirectoryFromSymbol((void*)libGLESv2_swiftshader));
+LibGLES_CM libGLES_CM(getLibraryDirectoryFromSymbol((void*)libGLESv2_swiftshader));
diff --git a/src/OpenGL/libGLESv2/libGLESv2.hpp b/src/OpenGL/libGLESv2/libGLESv2.hpp
index 8946f0b..1677d16 100644
--- a/src/OpenGL/libGLESv2/libGLESv2.hpp
+++ b/src/OpenGL/libGLESv2/libGLESv2.hpp
@@ -254,10 +254,8 @@
class LibGLESv2
{
public:
- LibGLESv2()
+ LibGLESv2(const std::string libraryDirectory) : libraryDirectory(libraryDirectory)
{
- libGLESv2 = nullptr;
- libGLESv2exports = nullptr;
}
~LibGLESv2()
@@ -310,7 +308,7 @@
#error "libGLESv2::loadExports unimplemented for this platform"
#endif
- libGLESv2 = loadLibrary(libGLESv2_lib, "libGLESv2_swiftshader");
+ libGLESv2 = loadLibrary(libraryDirectory, libGLESv2_lib, "libGLESv2_swiftshader");
if(libGLESv2)
{
@@ -322,8 +320,9 @@
return libGLESv2exports;
}
- void *libGLESv2;
- LibGLESv2exports *libGLESv2exports;
+ void *libGLESv2 = nullptr;
+ LibGLESv2exports *libGLESv2exports = nullptr;
+ const std::string libraryDirectory;
};
#endif // libGLESv2_hpp