一个本机库依赖于另一个库的搜索路径
我正在使用 JNA 和 Java,但我认为这个问题会影响任何本机到非本机的桥梁。
我有一个依赖于 lib1.dylib 的 Java 应用程序,而 lib1.dylib 依赖于 lib2.dylib。
我想将所有内容放入 Mac 上的 .app 文件中。我可以轻松地将 lib1.dylib 放入其中并设置 java.classpath (或 NativeLibrary.addSearchPath())来告诉 JVM 在哪里可以找到 lib1.dylib。问题是,我不知道如何传达 lib1.dylib 的依赖项也在我提供的位置。结果是 lib1 加载正常,但是找不到 lib2,因为它不在操作系统的库路径中。
有人知道我该如何克服这个问题吗?我想它在具有大量共享库的大型项目中一定会出现很多。
I'm using JNA and Java but I think this question affects any native-to-nonnative bridge.
I have a Java application which relies on lib1.dylib, and lib1.dylib relies on lib2.dylib.
I want to put everything inside of my .app file on Mac. I can easily put lib1.dylib inside and set java.classpath (or NativeLibrary.addSearchPath()) to tell the JVM where to find lib1.dylib. The trouble is, I don't know how to communicate that lib1.dylib's dependencies are also in the location I provided. The result is that lib1 is loaded fine, but then lib2 can't be found since it's not in the operating system's library path.
Anyone know how I can overcome this problem? I imagine it must come up plenty in big projects with large numbers of shared libraries.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我以前也遇到过这个问题,今天又遇到了。您也许可以通过添加 VM 参数“-Djava.library.path=/path/to/other/libs”来解决它,但我似乎记得 Java 仅使用它来搜索初始库,然后使用系统 PATH 来查找任何依赖项。
我之前尝试过的一些解决方案:
1)在加载库之前对依赖库使用 System.load(absolutePath) 。但这并不会使您的程序变得超便携,除非您始终知道该库将在哪里。
2)在 lib1 依赖于 lib2 的情况下,我实际上在本机代码中使用了 SetCurrentDirectory (Windows,不确定 Mac 的等效项),然后再链接到任何依赖库,这似乎有效。同样,需要知道其他库在哪里。
3) 在 Windows 上,可以将依赖库转储到 c:\windows\system32 中,并找到它们。
关于类似主题的一些有用的帖子(特定于 Windows,但我认为问题是相同的):
http://www.realityinteractive.com/rgrzywinski/archives/000219.html
http://www.velocityreviews.com/forums/t387618-jni-库路径.html
I've come across this problem before, and have just run into it again today. You may be able to get around it by adding the VM argument "-Djava.library.path=/path/to/other/libs", but I seem to remember Java only uses that to search for the intial library and then uses the system PATH to look for any dependencies.
A few solutions I've tried before:
1) Use System.load(absolutePath) on the dependent library before loading your library. Doesn't make your program ultra-portable though, unless you always know where that library is going to be.
2) In a case where lib1 depends on lib2, I actually used SetCurrentDirectory (Windows, not sure of the Mac equivalent) in the native code before it linked to any of the dependent libs, and that seemed to work. Again, requires knowing where the other libs are.
3) On Windows, could dump the dependent libraries in c:\windows\system32, and it finds them.
A few helpful posts on a similar topic (Windows-specific, but I think the problem is the same):
http://www.realityinteractive.com/rgrzywinski/archives/000219.html
http://www.velocityreviews.com/forums/t387618-jni-library-path.html
我根据 Stew 中的 (2) 中的想法找到了 MacOSX 的解决方案:
使用 Mac 的 JarBundler (或同名的 Ant 任务)将工作目录变量设置为 $JAVAROOT 并确保您的 dylib 位于内容/资源中/Java .app 的一部分。如果这样做,动态链接器将找到所有依赖项 dylib,因为它将是当前目录。出于同样的原因,Java 也会找到原始的 dylib(具有所有依赖项的)。
蚂蚁代码:
I've found a solution for MacOSX based on the idea in (2) from Stew:
Using Mac's JarBundler (or the Ant task of the same name) set the workingdirectory variable to $JAVAROOT and make sure your dylibs are in the Contents/Resources/Java part of the .app. If you do this the dynamic linker will find all the dependency dylibs because it will be the present directory. Java will also find the original dylib (the one that has all the dependencies) for the same reason.
Ant code: