Commit 99be318a by Alexis Hetu Committed by Alexis Hétu

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/18548Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent c8eedebd
...@@ -21,14 +21,35 @@ ...@@ -21,14 +21,35 @@
#include <dlfcn.h> #include <dlfcn.h>
#endif #endif
#include <string>
void *getLibraryHandle(const char *path); void *getLibraryHandle(const char *path);
void *loadLibrary(const char *path); void *loadLibrary(const char *path);
void freeLibrary(void *library); void freeLibrary(void *library);
void *getProcAddress(void *library, const char *name); void *getProcAddress(void *library, const char *name);
template<int n> 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++) for(int i = 0; i < n; i++)
{ {
void *library = getLibraryHandle(names[i]); void *library = getLibraryHandle(names[i]);
...@@ -84,6 +105,22 @@ void *loadLibrary(const char *(&names)[n], const char *mustContainSymbol = nullp ...@@ -84,6 +105,22 @@ void *loadLibrary(const char *(&names)[n], const char *mustContainSymbol = nullp
{ {
return (void*)GetProcAddress((HMODULE)library, name); 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 #else
inline void *loadLibrary(const char *path) inline void *loadLibrary(const char *path)
{ {
...@@ -127,6 +164,20 @@ void *loadLibrary(const char *(&names)[n], const char *mustContainSymbol = nullp ...@@ -127,6 +164,20 @@ void *loadLibrary(const char *(&names)[n], const char *mustContainSymbol = nullp
return symbol; 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
#endif // SharedLibrary_hpp #endif // SharedLibrary_hpp
...@@ -73,10 +73,8 @@ public: ...@@ -73,10 +73,8 @@ public:
class LibEGL class LibEGL
{ {
public: public:
LibEGL() LibEGL(const std::string libraryDirectory) : libraryDirectory(libraryDirectory)
{ {
libEGL = nullptr;
libEGLexports = nullptr;
} }
~LibEGL() ~LibEGL()
...@@ -124,7 +122,7 @@ private: ...@@ -124,7 +122,7 @@ private:
#error "libEGL::loadExports unimplemented for this platform" #error "libEGL::loadExports unimplemented for this platform"
#endif #endif
libEGL = loadLibrary(libEGL_lib, "libEGL_swiftshader"); libEGL = loadLibrary(libraryDirectory, libEGL_lib, "libEGL_swiftshader");
if(libEGL) if(libEGL)
{ {
...@@ -136,8 +134,9 @@ private: ...@@ -136,8 +134,9 @@ private:
return libEGLexports; return libEGLexports;
} }
void *libEGL; void *libEGL = nullptr;
LibEGLexports *libEGLexports; LibEGLexports *libEGLexports = nullptr;
const std::string libraryDirectory;
}; };
#endif // libEGL_hpp #endif // libEGL_hpp
...@@ -649,5 +649,5 @@ extern "C" EGLAPI LibEGLexports *libEGL_swiftshader() ...@@ -649,5 +649,5 @@ extern "C" EGLAPI LibEGLexports *libEGL_swiftshader()
return &libEGL; return &libEGL;
} }
LibGLES_CM libGLES_CM; LibGLES_CM libGLES_CM(getLibraryDirectoryFromSymbol((void*)libEGL_swiftshader));
LibGLESv2 libGLESv2; LibGLESv2 libGLESv2(getLibraryDirectoryFromSymbol((void*)libEGL_swiftshader));
...@@ -229,10 +229,8 @@ public: ...@@ -229,10 +229,8 @@ public:
class LibGLES_CM class LibGLES_CM
{ {
public: public:
LibGLES_CM() LibGLES_CM(const std::string libraryDirectory) : libraryDirectory(libraryDirectory)
{ {
libGLES_CM = nullptr;
libGLES_CMexports = nullptr;
} }
~LibGLES_CM() ~LibGLES_CM()
...@@ -285,7 +283,7 @@ private: ...@@ -285,7 +283,7 @@ private:
#error "libGLES_CM::loadExports unimplemented for this platform" #error "libGLES_CM::loadExports unimplemented for this platform"
#endif #endif
libGLES_CM = loadLibrary(libGLES_CM_lib, "libGLES_CM_swiftshader"); libGLES_CM = loadLibrary(libraryDirectory, libGLES_CM_lib, "libGLES_CM_swiftshader");
if(libGLES_CM) if(libGLES_CM)
{ {
...@@ -297,8 +295,9 @@ private: ...@@ -297,8 +295,9 @@ private:
return libGLES_CMexports; return libGLES_CMexports;
} }
void *libGLES_CM; void *libGLES_CM = nullptr;
LibGLES_CMexports *libGLES_CMexports; LibGLES_CMexports *libGLES_CMexports = nullptr;
const std::string libraryDirectory;
}; };
#endif // libGLES_CM_hpp #endif // libGLES_CM_hpp
...@@ -1610,4 +1610,4 @@ extern "C" GL_API LibGLES_CMexports *libGLES_CM_swiftshader() ...@@ -1610,4 +1610,4 @@ extern "C" GL_API LibGLES_CMexports *libGLES_CM_swiftshader()
return &libGLES_CM; return &libGLES_CM;
} }
LibEGL libEGL; LibEGL libEGL(getLibraryDirectoryFromSymbol((void*)libGLES_CM_swiftshader));
...@@ -1426,5 +1426,5 @@ extern "C" GL_APICALL LibGLESv2exports *libGLESv2_swiftshader() ...@@ -1426,5 +1426,5 @@ extern "C" GL_APICALL LibGLESv2exports *libGLESv2_swiftshader()
return &libGLESv2; return &libGLESv2;
} }
LibEGL libEGL; LibEGL libEGL(getLibraryDirectoryFromSymbol((void*)libGLESv2_swiftshader));
LibGLES_CM libGLES_CM; LibGLES_CM libGLES_CM(getLibraryDirectoryFromSymbol((void*)libGLESv2_swiftshader));
...@@ -254,10 +254,8 @@ public: ...@@ -254,10 +254,8 @@ public:
class LibGLESv2 class LibGLESv2
{ {
public: public:
LibGLESv2() LibGLESv2(const std::string libraryDirectory) : libraryDirectory(libraryDirectory)
{ {
libGLESv2 = nullptr;
libGLESv2exports = nullptr;
} }
~LibGLESv2() ~LibGLESv2()
...@@ -310,7 +308,7 @@ private: ...@@ -310,7 +308,7 @@ private:
#error "libGLESv2::loadExports unimplemented for this platform" #error "libGLESv2::loadExports unimplemented for this platform"
#endif #endif
libGLESv2 = loadLibrary(libGLESv2_lib, "libGLESv2_swiftshader"); libGLESv2 = loadLibrary(libraryDirectory, libGLESv2_lib, "libGLESv2_swiftshader");
if(libGLESv2) if(libGLESv2)
{ {
...@@ -322,8 +320,9 @@ private: ...@@ -322,8 +320,9 @@ private:
return libGLESv2exports; return libGLESv2exports;
} }
void *libGLESv2; void *libGLESv2 = nullptr;
LibGLESv2exports *libGLESv2exports; LibGLESv2exports *libGLESv2exports = nullptr;
const std::string libraryDirectory;
}; };
#endif // libGLESv2_hpp #endif // libGLESv2_hpp
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment