Reputation: 58
On Ubuntu 16.04, I'm building a JNI library against another shared library. The dependency is OpenCv, version 3.4.0, built locally and not installed in a standard library path.
I'm using cmake from maven to build the my JNI library. The output of the compile and link lines are as follows:
[ 66%] Building CXX object CMakeFiles/lib-image-native.jiminger.com.dir/sources/CvRasterNative.cpp.o /usr/bin/c++ -DUNIX -Dlib_image_native_jiminger_com_EXPORTS -I/usr/lib/jvm/java-8-openjdk-amd64/include -I/usr/lib/jvm/java-8-openjdk-amd64/include/linux -I/home/jim/src/opencv-packaging/package-native/target/cmake -I/home/jim/utils/opencv-3.4.0/installed/include -fPIC -std=gnu++11 -o CMakeFiles/lib-image-native.jiminger.com.dir/sources/CvRasterNative.cpp.o -c /home/jim/src/opencv-packaging/package-native/target/sources/sources/CvRasterNative.cpp [100%] Linking CXX shared module liblib-image-native.jiminger.com.so /home/jim/src/opencv-packaging/package-native/target/dependency/cmake/bin/cmake -E cmake_link_script CMakeFiles/lib-image-native.jiminger.com.dir/link.txt --verbose=1 /usr/bin/c++ -fPIC -shared -o liblib-image-native.jiminger.com.so CMakeFiles/lib-image-native.jiminger.com.dir/sources/CvRasterNative.cpp.o -Wl,-rpath,/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/libjawt.so /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server/libjvm.so
When I run a test that calls my native function I get:
.../java: symbol lookup error: [path to my library].so: undefined symbol: _ZN2cv6String8allocateEm
Inside my java code I'm explicitly loading this library (using System.load) as well as the dependent OpenCv library. That symbol is in the OpenCv library that I'm explicitly System.load'ing.
nm [path to opencv shared library].so | grep _ZN2cv6String8allocateEm
gives
0000000000442990 t _ZN2cv6String8allocateEm
When I call into my library I get that error. It says the symbol is undefined. But it's definition is in the other library (notice, it's in the 'text' segment) which I'm explicitly loading.
Can someone please tell me what I'm missing?
Thanks
EDIT: If it makes a difference, when I ldd my shared library I get
linux-vdso.so.1 => (0x00007ffe6e58f000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f7d279dc000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f7d277c5000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f7d273fb000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f7d270f2000)
/lib64/ld-linux-x86-64.so.2 (0x00005574eb402000)
Upvotes: 0
Views: 1895
Reputation: 58
I figured out what the problem was. I didn't realize the output of the nm
command shows local (vs externally visible) symbols. From the man page for nm
:
The symbol type. At least the following types are used; others are, as well, depending on the object file format. If lowercase, the symbol is usually local; if uppercase, the symbol is global (external).
The symbol in the dependent library is local indicated by the lower case 't'.
Upvotes: 0