最近在编译一个小工程时遇到了一个OpenCV的问题,如标题所示找不到函数接口。其实,我们一般遇到“undefined reference to”的错误首先想到的肯定是相关的库没有正确连接。但是我遇到的问题要比这个奇怪的多。
下面记录下我的解决思路,做个笔记防止后面在遇到相同的问题。
检查库是否正确连接
ldd ****.so
可检查某个库的依赖情况,重点看那些找不到的库。如果我们发现某个库找不到,则有两种情况:一、在编译该库时,依赖库的路径没有指定正确,即编译时就有错误;二、环境变量LD_LIBRARY_PATH
中并不包括依赖库的路径,也会造成该问题。- 在makefile文件中使用依赖库的绝对路径,有时我们在makefile中使用
LIBRARY := -lopecv_core
的形式添加依赖库,而这是相对路径,其库所在路径我们一般通过变量LIBS_PATH
指定,即到LIBS_PATH
指定的路径内寻找库libopecnv_core.so
库.有时环境变量LD_LIBRARY_PATH
会和LIBS_PATH
冲突,即两个路径下可能都包含我们要找的库,这时很有可能就找到错误路径上了,因此为了避免这种情况,我们可以使用依赖库的绝对路径。如下所示LIBRARIES := -L. /usr/local/lib/libopencv_core.so.3.4
- 如果我们发现缺少某个库,但是又不能确定该库的位置,我们可以使用
locate
命令确定该库的路径。找到依赖库后,我们可以将其路径增加到环境变量LD_LIBRARY_PATH
中,也可以将其绝对路径添加到makefile中。
CXX11
如果我们在错误中发现有CXX11的字样,我们可以参考片博客
一下内容版权归上述博客作者所有,我只是复制粘贴过来。
- 原因:
注意上面的那个__cxx11
。旧版本编译器编译出来的代码中,不会有这个符号。
用于编译该代码的gcc编译器的版本是5.5.0
,而该代码所需要的opencv所使用的编译器的版本是4.8.0
。 - 解决办法:
第一种:在编译的时候加上-D_GLIBCXX_USE_CXX11_ABI=0
即可(参考《g++命令行参数》的-Dmacro=defn部分)。
第二种:在每个源文件中添加一个宏定义:# define _GLIBCXX_USE_CXX11_ABI 0
。
检查头文件,检查头文件,检查头文件
重要的事情说三遍,当我们改变了库的版本后,切记要检查头文件是否和版本相对应。
我在迁移时,将opencv的版本由2.10升级到3.4。opencv3.4的库和opencv2.10的库已经有所不同,注意libopencv_imgcodecs.so.3.4
的添加。可参考这篇博客
我的最终问题是,我虽然添加了相应的库,而且头文件也按照上篇博客改正了,但是还是报错。主要原因就是我的头文件是opencv2.10的,版本不对应,修改成opencv3.4的头文件即可。