I am trying to use OpenCV-2.4.13 shared objects (libopencv_core.so
,libopencv_imgproc.so
etc.) in mylib.so
.
These OpenCV shared objects are compiled and installed with standard build procedure (make, make install) and I confirmed that they are located in /usr/local/lib
, they can be used directly with an application without any problem.
I am using Qt 5.8 on Ubuntu 16.04 for building process.
In mylib.so
, I use common cv::Mat
functions. Looking at the similar questions, I have already skimmed this article, it suggests either using -rpath
or -rpath-link
options during linking mylib.so
with an application. I also did read this article from Qt and applied the suggested method when building mylib.so
: adding a a_global.h
and defining an export symbol as Q_DECL_EXPORT
.
I am providing .pro file for mylib.so
below.
QT -= gui
CONFIG += c++11
TARGET = mylib
TEMPLATE = lib
DEFINES += MYLIB_LIBRARY
SOURCES += a.cpp
HEADERS += a.h external_libraries.h a_global.h
unix {
target.path = /usr/lib
INSTALLS += target
}
INCLUDEPATH += "/usr/local/include"
LIBS += -L/usr/local/lib -lopencv_calib3d -lopencv_contrib -lopencv_core\
-lopencv_features2d -lopencv_flann -lopencv_highgui -lopencv_imgproc\
-lopencv_legacy -lopencv_ml -lopencv_objdetect -lopencv_ocl\
-lopencv_photo -lopencv_stitching -lopencv_superres -lopencv_video\
-lopencv_videostab
Also, here is the .pro file for a dummy test application.
QT += core
QT -= gui
CONFIG += c++11
TARGET = apptest
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += main.cpp
INCLUDEPATH += "/home/foo/mylib/" #this is where `a.h` is
LIBS += "/home/foo/mylib/build/mylib.so.1.0.0"
QMAKE_CXXFLAGS += "-Wall"
QMAKE_LFLAGS += "-Wl,-rpath-link,/usr/local/lib"
QMAKE_LFLAGS += "-Wl,--unresolved-symbols=ignore-in-shared-libs"
You can see that I am providing /usr/local/lib
as the -rpath-link
where OpenCV shared objects reside. I am also instructing the linker to ignore unresolved symbols from shared libraries, which is suggested in this question and documented here.
The "right way" according to many sources is not to link OpenCV (or any dependency) in application, because this causes overlinking. In apptest
, when I don't link OpenCV, I get the following linker error:
undefined reference to cv::Mat::deallocate()
undefined reference to cv::fastFree(void)
collect2: error: ld returned 1 exit status
Looking at the error, my intuition is, somehow -rpath-link
is not doing what it is supposed to do.
I was not able to resolve this, I decided to deliberately link OpenCV with apptest
just to see what happens. What happens is awkward: it compiles and links without errors (whether I provide --unresolved-symbols=ignore-in-shared-libs
option or not). But when I run the app, it crashes without any exceptions from OpenCV; cv::imread
operation does not work as expected, rows and cols of image is zero.
I checked both apptest
and mylib.so
with readelf -d
. Nothing strange occured to me,
mylib.so
depends onlibQt5Core
andlibopencv_*
and it has the right SONAME entry.apptest
depends onmylib.so
,libQt5Core
and alsolibopencv_*
when I did the deliberate linking.
I also tried to debug apptest
with gdb. Output was not very helpful...
(gdb) r
Starting program:
/home/foo/apptest/build/apptest
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Program received signal SIGSEGV, Segmentation fault.
0x00007fffffffc9b0 in ?? ()
I assume linking is not done properly, but why? How can I resolve this without having to link OpenCV libs directly in app?