johnwhitington
johnwhitington

Reputation: 2763

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

(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?

Upvotes: 1

Views: 228

Answers (1)

Florian Weimer
Florian Weimer

Reputation: 33719

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

Upvotes: 1

Related Questions