(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