这里写自定义目录标题
一. 问题的产生
- 来源于开源项目PyDBoW3(https://github.com/notchla/PyDBoW3),该项目依赖于(OpenCv, DBow3) ,PyDBow实现内容是: 将C++编写的DBow,通过pybind11开源库转化为python形式DBow。
- 在centos 7 环境下,安装了Opencv4.x 后,使用CMake能够去编译构建PyDBoW3,生成动态库xxxx.so , 但在python环境运行时,import pydbow3导入时,却出现错误 undefined symbol :
import pydbow3 as bow, I get an error import pydbow3 Traceback (most recent call last): File “”, line 1, in ImportError: /home/xxx/miniconda3/envs/test_env_python39/lib/python3.9/site-packages/pydbow3.cpython-39-x86_64-linux-gnu.so: **undefined symbol: ZN2cv8internal18WriteStructContextC1ERNS_11FileStorageERKSsiS5
二. undefined symbol 问题的解决方式
1. 依赖库找不到
使用 **ldd -r xxx.so** 查看是否有动态库是查找不到
出现动态库not found ,解决方式:正确配置动态库的环境变量(/usr/local/lib /usr/local/lib64/)
2 编译和运行的依赖库版本不一致(运行>编译)
例:编译构建Pydbow项目时,使用的是系统环境下的opencv4.2去编译构建,但在conda虚拟环境下又装了一个opencv3.x, 那么在虚拟环境中import pydbow3导入是,会出现编译和运行的依赖库版本不一致。
notice: 编译时,使用的系统环境下的opencv
打印运行时的OpenCV 版本
import cv2
print(cv2.__version__)
notice: 运行时的版本可大于编译时的版本!!!
3. 项目及所有子项目(依赖项)的GCC/ C++版本保持一致!
PyDBoW 依赖于OpenCv 4,DBow (而我 undefined symbol: zn2 cv11 filestorage c1erkssis 2 原因就是: 使用GCC/C++11.2.0去编译构建PyDBow,OpenCv4, 但使用GCC/C++4.8.5去构建依赖项DBow —导致了依赖项GCC版本不一致)
- string xxx.so | grep GCC ——查看动态库xxx.so 的GCC版本
如下
pydbow.xxx.so 依赖于opencv ,DBow3, 三者的使用GCC/C++编译器的版本要保持一致 11.2.0
思考: 由于本人使用的是实验室的公用服务器Centos 7, 环境中安装了三个版本的GCC/C++编译器,所以在CMake构建时,指定特定版本的GCC
-DCMAKE_C_COMPILER=/usr/local/bin/gcc
-DCMAKE_CXX_COMPILER=/usr/local/bin/g++
三. 常用命令
- ldd -r xxx.so ——查看动态库所依赖的动态库
- sudo ldconfig —— 更新动态库缓存
- strings xxx.so | grep GCC —— 查看编译该动态库的GCC版本
- echo $CC/CXX —— 查看系统GCC的版本
- echo $ LD_LIBRATY_PATH ——打印动态库的路径
最后: 呜~, 被这个bug卡了好几天~,终于解决了!!!
( 遇到问题,思考问题的产生原因,解决问题)