我正在尝试在libopencv_core.so
中使用OpenCV-2.4.13共享对象(libopencv_imgproc.so
,mylib.so
等)。
这些OpenCV共享对象使用标准构建过程(make,make install)进行编译和安装,并且我确认它们位于/usr/local/lib
中,它们可以直接与应用程序一起使用而没有任何问题。
我在Ubuntu 16.04上使用Qt 5.8进行构建过程。
在mylib.so
中,我使用了常见的cv::Mat
函数。查看类似的问题,我已经浏览了this article,它建议在将-rpath
与应用程序链接时使用-rpath-link
或mylib.so
选项。我还在Qt中阅读了this article并在构建mylib.so
时应用了建议的方法:添加a_global.h
并将导出符号定义为Q_DECL_EXPORT
。
我正在为mylib.so
提供.pro文件。
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
此外,这是虚拟测试应用程序的.pro文件。
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"
您可以看到我提供/usr/local/lib
作为OpenCV共享对象所在的-rpath-link
。我还指示链接器忽略共享库中未解析的符号,建议in this question并记录here。
正确的方式"根据许多来源,不要在应用程序中链接OpenCV(或任何依赖项),因为这会导致过度链接。在apptest
中,当我没有链接OpenCV时,我收到以下链接器错误:
undefined reference to cv::Mat::deallocate()
undefined reference to cv::fastFree(void)
collect2: error: ld returned 1 exit status
看着这个错误,我的直觉是,不知怎的-rpath-link
没有做它应该做的事情。
我无法解决这个问题,我决定故意将OpenCV与apptest
联系起来,看看会发生什么。发生的事情很尴尬:它编译和链接没有错误(我是否提供--unresolved-symbols=ignore-in-shared-libs
选项)。但是当我运行应用程序时,它会在没有任何OpenCV异常的情况下崩溃; cv::imread
操作无法按预期工作,图像的行和列为零。
我使用apptest
检查了mylib.so
和readelf -d
。没有什么奇怪的事发生在我身上,
mylib.so
取决于libQt5Core
和libopencv_*
,并且它具有正确的SONAME条目。apptest
取决于mylib.so
,libQt5Core
和libopencv_*
。我还尝试使用gdb调试apptest
。输出不是很有帮助......
(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 ?? ()
我认为链接没有正确完成,但为什么呢?如何在不必直接在应用程序中链接OpenCV库的情况下解决此问题?