How to load dylib on Mac?
Hi All I'm totally new to C programming on Mac. On other systems I can call dlopen("libkrb5.so", RTLD_NOW) to return a non-NULL pointer to the library. However, on Mac, dlopen("libkrb5.dylib", RTLD_NOW) returns NULL even if I can see the / usr/lib/libkrb5.dylib is right there. What's wrong here? Also, is there a way to write a cross-platform call? Say, dlopen_smart("krb5")? Thanks Max
Hi All I've found something new. It seems the dlopen() function in Mac is quite normal, but there are some problem inside OpenJDK. I'm calling dlopen("libkrb5.dylib", RTLD_NOW) inside OpenJDK now and it returns NULL. However, if I manually set DYLD_LIBRARY_PATH or DYLD_FALLBACK_LIBRARY_PATH to /usr/lib, then it works. So I printf the DYLD_FALLBACK_LIBRARY_PATH value, it is changed to something like jre/lib/i386:jre/lib:jre/../lib/i386. According to Apple doc, the default value of it should ~/lib:/usr/lib:/usr/local/lib. If OpenJDK wants to change it to something else, shouldn't it append the new value onto the old one? So I suggest making these changes: --- a/src/solaris/bin/java_md.c +++ b/src/solaris/bin/java_md.c @@ -443,6 +443,9 @@ * variable. */ runpath = getenv(LD_LIBRARY_PATH); +#ifdef __APPLE__ + if (!runpath) runpath = "/usr/local/lib:/usr/lib"; +#endif #endif /* __solaris__ */ #if defined(__linux__) || defined(_ALLBSD_SOURCE) Yes, the default runpath should also include "~/lib", omitted here for brevity. Thanks Max Max (Weijun) Wang wrote:
Hi All
I'm totally new to C programming on Mac.
On other systems I can call dlopen("libkrb5.so", RTLD_NOW) to return a non-NULL pointer to the library. However, on Mac, dlopen("libkrb5.dylib", RTLD_NOW) returns NULL even if I can see the / usr/lib/libkrb5.dylib is right there. What's wrong here?
Also, is there a way to write a cross-platform call? Say, dlopen_smart("krb5")?
I've found the JNI_LIB_NAME() macro. Nice.
Thanks Max
In fact, why is DYLD_FALLBACK_LIBRARY_PATH updated in src/solaris/bin/ java_md.c? Why not DYLD_LIBRARY_PATH? DYLD_LIBRARY_PATH should be preferred than DYLD_FALLBACK_LIBRARY_PATH. If the libjpeg.dylib is in DYLD_LIBRARY_PATH, it will be loaded instead of /usr/lib/libjpeg.dylib. Thanks Max On Jul 24, 2009, at 4:52 PM, Weijun Wang wrote:
Hi All
I've found something new.
It seems the dlopen() function in Mac is quite normal, but there are some problem inside OpenJDK.
I'm calling dlopen("libkrb5.dylib", RTLD_NOW) inside OpenJDK now and it returns NULL. However, if I manually set DYLD_LIBRARY_PATH or DYLD_FALLBACK_LIBRARY_PATH to /usr/lib, then it works.
So I printf the DYLD_FALLBACK_LIBRARY_PATH value, it is changed to something like jre/lib/i386:jre/lib:jre/../lib/i386. According to Apple doc, the default value of it should ~/lib:/usr/lib:/usr/local/lib. If OpenJDK wants to change it to something else, shouldn't it append the new value onto the old one?
So I suggest making these changes:
--- a/src/solaris/bin/java_md.c +++ b/src/solaris/bin/java_md.c @@ -443,6 +443,9 @@ * variable. */ runpath = getenv(LD_LIBRARY_PATH); +#ifdef __APPLE__ + if (!runpath) runpath = "/usr/local/lib:/usr/lib"; +#endif #endif /* __solaris__ */
#if defined(__linux__) || defined(_ALLBSD_SOURCE)
Yes, the default runpath should also include "~/lib", omitted here for brevity.
Thanks Max
Max (Weijun) Wang wrote:
Hi All
I'm totally new to C programming on Mac.
On other systems I can call dlopen("libkrb5.so", RTLD_NOW) to return a non-NULL pointer to the library. However, on Mac, dlopen("libkrb5.dylib", RTLD_NOW) returns NULL even if I can see the / usr/lib/libkrb5.dylib is right there. What's wrong here?
Also, is there a way to write a cross-platform call? Say, dlopen_smart("krb5")?
I've found the JNI_LIB_NAME() macro. Nice.
Thanks Max
On Jul 24, 2009, at 8:11 AM, Max (Weijun) Wang wrote:
In fact, why is DYLD_FALLBACK_LIBRARY_PATH updated in src/solaris/bin/ java_md.c? Why not DYLD_LIBRARY_PATH?
DYLD_LIBRARY_PATH should be preferred than DYLD_FALLBACK_LIBRARY_PATH. If the libjpeg.dylib is in DYLD_LIBRARY_PATH, it will be loaded instead of /usr/lib/libjpeg.dylib.
If DYLD_LIBRARY_PATH is set, it can cause library name conflicts. By default, Mach-O records the path to libraries, rather than only their name. Setting DYLD_LIBRARY_PATH results in this path being overridden, and case insensitive name matching occurs first, instead. One example of this is the JDK's libjpeg.dylib, which conflicts with / System/Library/Frameworks/ApplicationServices.framework/Versions/A/ Frameworks/ImageIO.framework/Versions/A/Resources/libJPEG.dylib This should probably be revisited, as it may be possible to remove the use of DYLD_* variables via the use of executable/library-relative @rpath, @executable_path, and/or @loader_path install_name values. -landonf
Oh, I didn't notice the case insensitive name matching part. But with the current implementation, libs in /usr/lib cannot be dlopen()'ed. For example, the following paragraphs shows that the native JGSS provider cannot be loaded: $ cat A.java class A { public static void main(String[] args) throws Exception { System.out.println(System.getProperty("os.name")); new sun.security.jgss.wrapper.SunNativeProvider(); } } $ java -Dsun.security.nativegss.debug=true -Dsun.security.jgss.lib=libgssapi_krb5.dylib A Darwin SunNativeGSS: [GSSLibStub_init] libName=libgssapi_krb5.dylib SunNativeGSS: dlopen(libgssapi_krb5.dylib, 2): image not found $ DYLD_LIBRARY_PATH=/usr/lib java -Dsun.security.nativegss.debug=true -Dsun.security.jgss.lib=libgssapi_krb5.dylib A Darwin SunNativeGSS: [GSSLibStub_init] libName=libgssapi_krb5.dylib SunNativeGSS: Loaded GSS library: libgssapi_krb5.dylib SunNativeGSS: Native MF for 1.2.840.113554.1.2.2 SunNativeGSS: Native MF for 1.3.5.1.5.2 SunNativeGSS: Native MF for 1.2.840.48018.1.2.2 SunNativeGSS: Native MF for 1.3.6.1.5.5.2 Thanks Max Landon Fuller wrote:
On Jul 24, 2009, at 8:11 AM, Max (Weijun) Wang wrote:
In fact, why is DYLD_FALLBACK_LIBRARY_PATH updated in src/solaris/bin/ java_md.c? Why not DYLD_LIBRARY_PATH?
DYLD_LIBRARY_PATH should be preferred than DYLD_FALLBACK_LIBRARY_PATH. If the libjpeg.dylib is in DYLD_LIBRARY_PATH, it will be loaded instead of /usr/lib/libjpeg.dylib.
If DYLD_LIBRARY_PATH is set, it can cause library name conflicts. By default, Mach-O records the path to libraries, rather than only their name. Setting DYLD_LIBRARY_PATH results in this path being overridden, and case insensitive name matching occurs first, instead.
One example of this is the JDK's libjpeg.dylib, which conflicts with /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/ImageIO.framework/Versions/A/Resources/libJPEG.dylib
This should probably be revisited, as it may be possible to remove the use of DYLD_* variables via the use of executable/library-relative @rpath, @executable_path, and/or @loader_path install_name values.
-landonf
------------------------------------------------------------------------
On Jul 26, 2009, at 7:56 PM, Weijun Wang wrote:
Oh, I didn't notice the case insensitive name matching part.
But with the current implementation, libs in /usr/lib cannot be dlopen()'ed. For example, the following paragraphs shows that the native JGSS provider cannot be loaded:
Ah -- I agree with your original assessment; the default paths should also be added. -landonf
On Jul 24, 2009, at 8:11 AM, Max (Weijun) Wang wrote:
In fact, why is DYLD_FALLBACK_LIBRARY_PATH updated in src/solaris/bin/ java_md.c? Why not DYLD_LIBRARY_PATH?
DYLD_LIBRARY_PATH should be preferred than DYLD_FALLBACK_LIBRARY_PATH. If the libjpeg.dylib is in DYLD_LIBRARY_PATH, it will be loaded instead of /usr/lib/libjpeg.dylib.
[resending with a list-subscribed address] If DYLD_LIBRARY_PATH is set, it can cause library name conflicts. By default, Mach-O records the path to libraries, rather than only their name. Setting DYLD_LIBRARY_PATH results in this path being overridden, and case insensitive name matching occurs first, instead. One example of this is the JDK's libjpeg.dylib, which conflicts with / System/Library/Frameworks/ApplicationServices.framework/Versions/A/ Frameworks/ImageIO.framework/Versions/A/Resources/libJPEG.dylib This should probably be revisited, as it may be possible to remove the use of DYLD_* variables via the use of executable/library-relative @rpath, @executable_path, and/or @loader_path install_name values. -landonf
participants (4)
-
Landon Fuller
-
Landon Fuller
-
Max (Weijun) Wang
-
Weijun Wang