I have the following situation:
I created a dynamic library lib.so. This library uses another static library, lib.a. Both of them use the Boost library (I link them in the CMake file). (I use this dynamic library in a Java project)
This is the code for file.cpp in lib.so that calls getFilesFromDirectory () from lib.a
#include "DrawingDetector.h" #include "../../DrawingDetection.h" #include <vector> #include <boost/filesystem/operations.hpp> using namespace std; JNIEXPORT void JNICALL Java_DrawingDetector_detectImage( JNIEnv * env, jobject, jstring jMsg) { const char* msg = env->GetStringUTFChars(jMsg,0); vector<File> filesPic = getFilesFromDirectory(msg,0); env->ReleaseStringUTFChars(jMsg, msg); }
This is the getFilesFromDirectory () code from lib.a:
#include <string.h> #include <iostream> #include <boost/filesystem/operations.hpp> #include "DrawingDetection.h" using namespace std; using namespace boost; using namespace boost::filesystem; vector<File> getFilesFromDirectory(string dir, int status) { vector<File> files; path directoty = path(dir); directory_iterator end; if (!exists(directoty)) { cout<<"There is no such directory or file!"<<endl; } for (directory_iterator itr(directoty); itr != end; ++itr) { if ( is_regular_file((*itr).path())) { //some code } } return files; }
But when my project calls the lib.so library, it calls the following message:
java: symbol lookup error: /home/orlova/workspace/kmsearch/Images/branches/DrawingDetection/jni/bin/lib.so: undefined symbol:_ZN5boost11filesystem34path21wchar_t_codecvt_facetEv
As I found out, it crashes in lib.a when it tries to call the boost method of a method. But I declared all forwards headers and linked them in a CMake file. Can you explain why it does not recognize promotion methods?
EDIT
The version of my gcc compiler is 4.6. And if I use 4.5, everything is fine!
Also, if I use some boost methods directly in the .cpp file in lib.so, everything works fine, for example:
JNIEXPORT void JNICALL Java_DrawingDetector_detectImage( JNIEnv * env, jobject, jstring jMsg) { const char* msg = env->GetStringUTFChars(jMsg,0); path directoty = path("/home/orlova");
BUT
JNIEXPORT void JNICALL Java_DrawingDetector_detectImage( JNIEnv * env, jobject, jstring jMsg) { const char* msg = env->GetStringUTFChars(jMsg,0);
}
How can you explain this compiler behavior?
Please note that this error occurs at runtime.
solvable
The problem was the order of the libraries in * target_link_libraries * in the CMake file.
WRONG:
find_library( LIBRARY_MAIN NAMES lib.a PATHS ../bin ) set ( LIB_JNI jpeg ${OpenCV_LIBS} ${BOOST_LIB} ${LIBRARY_MAIN}//static library is the last in the list of libraries and after boost! ) target_link_libraries( ${PROJECT} ${LIB_JNI} )
RIGHT:
find_library( LIBRARY_MAIN NAMES lib.a PATHS ../bin ) set ( LIB_JNI ${LIBRARY_MAIN} jpeg ${OpenCV_LIBS} ${BOOST_LIB}//boost library is the last in the list and after static library! ) target_link_libraries( ${PROJECT} ${LIB_JNI} )