Linux 上的共享库不包含对其依赖项之一的引用

Shared library on Linux does not contain reference to one of its dependencies

(这个问题涉及 Java JNI,但我不认为问题实际上出在 JNI 或 Java)

我正在执行这条命令:

cc -shared -fpic -L. -lcpdf -I$JAVA_HOME/include I$JAVA_HOME/include/linux jcpdfwrapper.c -o libjcpdf.so

也就是说我正在构建共享库 libjcpdf.so,它需要 libcpdf.so 的函数,所以应该依赖它。

在 Windows (MinGW) 和 MacOS 上,新的共享库 (jcpdf) 清楚地链接到给定的共享库 (cpdf):

WINDOWS:

$ ldd jcpdf.dll
    ntdll.dll => /cygdrive/c/WINDOWS/SYSTEM32/ntdll.dll (0x7ffe875f0000)
    KERNEL32.DLL => /cygdrive/c/WINDOWS/System32/KERNEL32.DLL (0x7ffe86400000)
    KERNELBASE.dll => /cygdrive/c/WINDOWS/System32/KERNELBASE.dll (0x7ffe851f0000)
    msvcrt.dll => /cygdrive/c/WINDOWS/System32/msvcrt.dll (0x7ffe87120000)
    libcpdf.dll => /home/JohnWhitington/jcpdf/libcpdf.dll (0x3743f0000)
    WS2_32.dll => /cygdrive/c/WINDOWS/System32/WS2_32.dll (0x7ffe870b0000)
    RPCRT4.dll => /cygdrive/c/WINDOWS/System32/RPCRT4.dll (0x7ffe87480000)
    VERSION.dll => /cygdrive/c/WINDOWS/SYSTEM32/VERSION.dll (0x7ffe7d270000)

OS X:

$ otool -L libjcpdf.dylib 
libjcpdf.dylib:
    libjcpdf.dylib (compatibility version 0.0.0, current version 0.0.0)
    libcpdf.so (compatibility version 0.0.0, current version 0.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1311.100.3)

但是,在 Linux 上,我们在 libjcpdf.so 中没有对 libcpdf.so 的引用:

$ ldd libjcpdf.so
linux-vds0,30,1 => (60x00007fc40b13000)
libc.so,6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fc1fb2af000)
/lib64/ld-linux-x86-64.so.2 (0x00007fe1fba8f000)

所以发生的事情是,虽然从主 Java 程序 System.LoadLibrary("jcpdf") 成功,但任何使用该库的尝试都会给出:

java: symbol lookup error: /home/john/jcpdf/libjcpdf.so: undefined symbol: cpdf_startup

整个程序在 MacOS 和 Windows 上运行良好。

如何告诉 cclibjcpdf.so 实际上依赖于 libcpdf.so

您的 cc 版本(或它使用的 link 编辑器)似乎默认为 -Wl,--as-neeeded。在这种情况下,命令行顺序很重要。如果 -lcpdf 先出现,则还没有对其符号的引用,因此不会创建依赖关系。 -l 参数应该放在最后:

cc -shared -fpic -I$JAVA_HOME/include I$JAVA_HOME/include/linux jcpdfwrapper.c -o libjcpdf.so -L. -lcpdf