OSDN Git Service

Load sibling libraries from the same directory
authorAlexis Hetu <sugoi@google.com>
Mon, 16 Apr 2018 19:38:40 +0000 (15:38 -0400)
committerAlexis Hétu <sugoi@google.com>
Thu, 19 Apr 2018 12:23:59 +0000 (12:23 +0000)
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>
src/Common/SharedLibrary.hpp
src/OpenGL/libEGL/libEGL.hpp
src/OpenGL/libEGL/main.cpp
src/OpenGL/libGLES_CM/libGLES_CM.hpp
src/OpenGL/libGLES_CM/main.cpp
src/OpenGL/libGLESv2/entry_points.cpp
src/OpenGL/libGLESv2/libGLESv2.hpp

index ab710eb..85e5e7d 100644 (file)
        #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 @@ void *loadLibrary(const char *(&names)[n], const char *mustContainSymbol = nullp
        {
                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 @@ void *loadLibrary(const char *(&names)[n], const char *mustContainSymbol = nullp
 
                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
index 46e319a..7ef0d31 100644 (file)
@@ -73,10 +73,8 @@ public:
 class LibEGL
 {
 public:
-       LibEGL()
+       LibEGL(const std::string libraryDirectory) : libraryDirectory(libraryDirectory)
        {
-               libEGL = nullptr;
-               libEGLexports = nullptr;
        }
 
        ~LibEGL()
@@ -124,7 +122,7 @@ private:
                                #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 @@ private:
                return libEGLexports;
        }
 
-       void *libEGL;
-       LibEGLexports *libEGLexports;
+       void *libEGL = nullptr;
+       LibEGLexports *libEGLexports = nullptr;
+       const std::string libraryDirectory;
 };
 
 #endif   // libEGL_hpp
index a1ff6f1..c850610 100644 (file)
@@ -649,5 +649,5 @@ extern "C" EGLAPI LibEGLexports *libEGL_swiftshader()
        return &libEGL;
 }
 
-LibGLES_CM libGLES_CM;
-LibGLESv2 libGLESv2;
+LibGLES_CM libGLES_CM(getLibraryDirectoryFromSymbol((void*)libEGL_swiftshader));
+LibGLESv2 libGLESv2(getLibraryDirectoryFromSymbol((void*)libEGL_swiftshader));
index d6740ec..b9c29f5 100644 (file)
@@ -229,10 +229,8 @@ public:
 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 @@ private:
                                #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 @@ private:
                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
index f2bd0b7..ea56c81 100644 (file)
@@ -1610,4 +1610,4 @@ extern "C" GL_API LibGLES_CMexports *libGLES_CM_swiftshader()
        return &libGLES_CM;
 }
 
-LibEGL libEGL;
+LibEGL libEGL(getLibraryDirectoryFromSymbol((void*)libGLES_CM_swiftshader));
index b142b85..378f9fe 100644 (file)
@@ -1426,5 +1426,5 @@ extern "C" GL_APICALL LibGLESv2exports *libGLESv2_swiftshader()
        return &libGLESv2;
 }
 
-LibEGL libEGL;
-LibGLES_CM libGLES_CM;
+LibEGL libEGL(getLibraryDirectoryFromSymbol((void*)libGLESv2_swiftshader));
+LibGLES_CM libGLES_CM(getLibraryDirectoryFromSymbol((void*)libGLESv2_swiftshader));
index 8946f0b..1677d16 100644 (file)
@@ -254,10 +254,8 @@ public:
 class LibGLESv2
 {
 public:
-       LibGLESv2()
+       LibGLESv2(const std::string libraryDirectory) : libraryDirectory(libraryDirectory)
        {
-               libGLESv2 = nullptr;
-               libGLESv2exports = nullptr;
        }
 
        ~LibGLESv2()
@@ -310,7 +308,7 @@ private:
                                #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 @@ private:
                return libGLESv2exports;
        }
 
-       void *libGLESv2;
-       LibGLESv2exports *libGLESv2exports;
+       void *libGLESv2 = nullptr;
+       LibGLESv2exports *libGLESv2exports = nullptr;
+       const std::string libraryDirectory;
 };
 
 #endif   // libGLESv2_hpp