当System.load-ing依赖库按相反顺序加载时出现不满足链接错误



我有一个动态库libjvm_host.so,它依赖于libsgx_uae_service_sim.solibsgx_urts_sim.so:

$ ldd libjvm_host.so 
linux-vdso.so.1 =>  (0x00007ffcc376f000)
libsgx_uae_service_sim.so => not found
libsgx_urts_sim.so => not found
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f37d91fc000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f37d8e7a000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f37d8c64000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f37d889a000)
/lib64/ld-linux-x86-64.so.2 (0x00007f37d9651000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f37d8591000)

这两个依赖项都在libjvm_host.so旁边,它之所以说not found是因为我还没有设置LD_LIBRARY_PATH

我尝试使用System.load使用它们的绝对路径加载这些库,而不依赖LD_LIBRARY_PATH,按相反的顺序:

System.load(File(temporaryDirectory, "libsgx_uae_service_sim.so").absolutePath)
System.load(File(temporaryDirectory, "libsgx_urts_sim.so").absolutePath)
System.load(File(temporaryDirectory, "libjvm_host.so").absolutePath)

temporaryDirectory是我打开.so的地方。然而,我得到了一个UnsatisfiedLinkError:

java.lang.UnsatisfiedLinkError: /tmp/com.r3.sgx.host-libraries/libjvm_host.so: libsgx_uae_service_sim.so: cannot open shared object file: No such file or directory
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1941)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1824)
at java.lang.Runtime.load0(Runtime.java:809)
at java.lang.System.load(System.java:1086)
at com.r3.sgx.core.host.internal.NativeLoader.loadHostLibraries(NativeLoader.kt:31)

它加载前两个.so,并在依赖于前两个的libjvm_host.so上失败。

我在很多地方读到,这是在不依赖LD_LIBRARY_PATH的情况下加载相互依赖的库的方法,但我无法使其工作。我错过了什么?

用另一种方法解决了这个问题。不确定为什么反向加载不起作用,但以下内容起作用:

当链接顶级.so时,添加$ORIGIN的RPATH,如so:

ld (...) -rpath "$ORIGIN"

使用CMake:

target_link_libraries(jvm_host
(...)
-Wl,-rpath,"$ORIGIN")

这个特殊的RPATH会导致加载程序将顶级.so的父目录添加到库路径列表中,这意味着在与libjvm_host.so相同的文件夹中拥有依赖项就足够了。

有了这个System.load(File(temporaryDirectory, "libjvm_host.so").absolutePath,它对自己的作品就像一种魅力。

最新更新