Home > Back-end >  Shared library on Linux does not contain reference to one of its dependencies
Shared library on Linux does not contain reference to one of its dependencies

Time:04-09

(This question concerns the Java JNI, but I don't believe the problem actually lies with the JNI or Java)

I am executing this command:

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

That is to say I am building the shared library libjcpdf.so which needs functions from libcpdf.so, so should depend upon it.

On Windows (MinGW) and MacOS, the new shared library (jcpdf) clearly links to the given one (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)

However, on Linux, we get no reference to libcpdf.so in libjcpdf.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)

So what happens is that, whilst, from the main Java program, System.LoadLibrary("jcpdf") succeeds, any attempt to use the library gives:

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

The whole program works fine on MacOS and Windows.

How can I tell cc to make libjcpdf.so actually depend on libcpdf.so?

CodePudding user response:

Your version of cc (or the link editor used by it) seem to default to -Wl,--as-neeeded. In this case, the command line order matters. If -lcpdf comes first, there are no references to its symbols yet, and so no dependency is created. -l arguments should come last:

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