[libbluray-devel] Improve dlopen on OSX

Jean-Baptiste Kempf git at videolan.org
Wed Aug 29 16:42:20 CEST 2012


libbluray | branch: master | Jean-Baptiste Kempf <jb at videolan.org> | Wed Aug 29 16:39:48 2012 +0200| [bbc5a574b1835e90f8ecc40a42cb91c14b40c034] | committer: Jean-Baptiste Kempf

Improve dlopen on OSX

It will search some common paths when dlopening libraries

> http://git.videolan.org/gitweb.cgi/libbluray.git/?a=commit;h=bbc5a574b1835e90f8ecc40a42cb91c14b40c034
---

 src/file/dl_posix.c |   78 ++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 53 insertions(+), 25 deletions(-)

diff --git a/src/file/dl_posix.c b/src/file/dl_posix.c
index 57ab232..76998dc 100644
--- a/src/file/dl_posix.c
+++ b/src/file/dl_posix.c
@@ -54,51 +54,79 @@ static const char *dlerror(char *buf, int buf_size)
 }
 #endif
 
-void   *dl_dlopen  ( const char* path, const char *version )
+static void   *_dl_dlopen  ( const char* path )
 {
-    char *name;
     void *result;
 
-#if defined(__APPLE__)
-    static const char ext[] = ".dylib";
-    version = NULL;
-#elif defined(_WIN32)
-    static const char ext[] = ".dll";
-    version = NULL;
-#else
-    static const char ext[] = ".so";
-#endif
-
-    if (version) {
-        name = str_printf("%s%s.%s", path, ext, version);
-    } else {
-        name = str_printf("%s%s", path, ext);
-    }
-
-    BD_DEBUG(DBG_FILE, "searching for library '%s' ...\n", name);
+    BD_DEBUG(DBG_FILE, "searching for library '%s' ...\n", path);
 
 #if defined(_WIN32)
     wchar_t wname[MAX_PATH];
-    MultiByteToWideChar(CP_UTF8, 0, name, -1, wname, MAX_PATH);
+    MultiByteToWideChar(CP_UTF8, 0, path, -1, wname, MAX_PATH);
     result = LoadLibraryW(wname);
 
     if (!result) {
         char buf[128];
-        BD_DEBUG(DBG_FILE, "can't open library '%s': %s\n", name, dlerror(buf, sizeof(buf)));
+        BD_DEBUG(DBG_FILE, "can't open library '%s': %s\n", path, dlerror(buf, sizeof(buf)));
     }
 #else
-    result = dlopen(name, RTLD_LAZY);
+    result = dlopen(path, RTLD_LAZY);
 
     if (!result) {
-        BD_DEBUG(DBG_FILE, "can't open library '%s': %s\n", name, dlerror());
+        BD_DEBUG(DBG_FILE, "can't open library '%s': %s\n", path, dlerror());
     }
 #endif
 
-    X_FREE(name);
-
     return result;
 }
 
+void   *dl_dlopen  ( const char* path, const char *version )
+{
+    char *name;
+    void *dll;
+    int i;
+
+#if defined(__APPLE__)
+    static const char ext[] = ".dylib";
+    /*
+      Search for the library in several locations:
+       ""               - default search path (including DYLD_LIBRARY_PATH)
+       @loader_path     - location of current library/binary (ex. libbluray.dylib)
+       @executable_path - location of running binary (ex. /Applications/Some.app/Contents/MacOS)
+       @rpath           - search rpaths of running binary (man install_name_path)
+    */
+    static const char *search_paths[] = {"", "@loader_path/lib/", "@loader_path/", "@executable_path/",
+                                         "@executable_path/lib/", "@executable_path/../lib/",
+                                         "@executable_path/../Resources/", "@rpath/", NULL};
+    version = NULL;
+#elif defined(_WIN32)
+    static const char ext[] = ".dll";
+    static const char *search_paths[] = {"", NULL};
+    version = NULL;
+#else
+    static const char ext[] = ".so";
+    static const char *search_paths[] = {"", NULL};
+#endif
+
+    for (i = 1 ; search_paths[i] ; ++i) {
+        if (version) {
+            name = str_printf("%s%s%s.%s", search_paths[i], path, ext, version);
+        } else {
+            name = str_printf("%s%s%s", search_paths[i], path, ext);
+        }
+
+        fprintf (stderr, "Attempting to open %s\n", name);
+
+        dll = _dl_dlopen (name);
+        X_FREE(name);
+        if (dll) {
+            return dll;
+        }
+    }
+
+    return NULL;
+}
+
 void   *dl_dlsym   ( void* handle, const char* symbol )
 {
 #if defined(_WIN32)



More information about the libbluray-devel mailing list