-
为什么会报这个错误? => 这涉及到执行到import cv2, python是如何来找到cv2所在的路径的?答案是通过PYTHONPATH环境变量。其实我们pip intall库的时候,只是工具在背后帮我们把库放到了PYTHONPATH环境变量里的路径里。参考文章Linux 安装Opencv中的源代码安装。文章指出在手动编译完opencv之后,需要
$ su mv /usr/local/lib/python2.7/site-packages/cv2.so /usr/lib/python2.7/site-packages
$ export PYTHONPATH=$PYTHONPATH:/usr/local/lib/python2.7/site-packages
首先把编译出来的cv2.so 拷贝到/usr/lib/python2.7/site-packages目录下,然后把这个路径加到PYTHONPATH环境变量中。
顺便说一下,举例来说,对于一个特定的python版本/home/utils/Python-3.5.2/bin/python3,在执行的时候import的库通常在:
a. /home/utils/Python-3.5.2/lib/python3.5下面的 *.py文件
b. /home/utils/Python-3.5.2/lib/python3.5/site-packages/ 下面的 *.so文件中。
-
既然是import cv2的时候出错,那么大概率是cv2这个库的问题,找到cv2库所在的位置 /home/utils/Python-3.5.2/lib/python3.5/site-packages/cv2.cpython-35m-x86_64-linux-gnu.so, 然后:
$ ldd /home/utils/Python-3.5.2/lib/python3.5/site-packages/cv2.cpython-35m-x86_64-linux-gnu.so | grep libatk
libatk-1.0.so.0 => /lib64/libatk-1.0.so.0 (0x00007fffc0bd1000)
果然是cv2依赖 /lib64/libatk-1.0.so.0 这个库。
-
我们现在遇到的问题是/lib64/libatk-1.0.so.0这个库里面的g_type_check_instance_is_fundamentally_a这个符号undefine, 那么我们可以通过nm命令查看是否是真的undefine:
$ nm /lib64/libatk-1.0.so.0
nm: /lib64/libatk-1.0.so.0: no symbols
为什么no symbols?这很奇怪,在stackOverflow上找到了答案:Why nm libc.so reports no symbols?
答案是需要加参数 --dynamic。
$ nm /lib64/libatk-1.0.so.0 --dynamic | grep g_type_check_instance_is_fundamentally_a
U g_type_check_instance_is_fundamentally_a
果然这个symbol是U(undefine)。
-
如何解决?公司有另一台机器可以运行cv2,发现最终使用的libatk的版本是libatk-1.0.so.0.3009.1
$ ll /usr/lib64/libatk-1.0.so.0
lrwxrwxrwx 1 root root 22 Feb 17 2017 /usr/lib64/libatk-1.0.so.0 -> libatk-1.0.so.0.3009.1
而出错的那台机器的libatk的版本是libatk-1.0.so.0.22209.1, 看起来是系统中libatk的版本太低导致的。所以说只要升级libatk的版本应该就可以了。
a. 如果系统中有高版本的libatk,只需要通过设置LD_LIBRARY_PATH让python在load cv2.so的时候找到高版本的libatk就可以了。
b. 但是我没有在系统中找到高版本的libatk,所以解决办法是。。。找Infra的同事来升级版本吧。
$ ll /lib64/libatk-1.0.so.0
lrwxrwxrwx 1 root root 23 Nov 21 2017 /lib64/libatk-1.0.so.0 -> libatk-1.0.so.0.22209.1
-
what is stripped?
$ file /lib64/libatk-1.0.so.0.22209.1
/lib64/libatk-1.0.so.0.22209.1: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=52d8c2ffbaecdca6fac51cda5395b35e588f546e, stripped
这里stripped的意思是: 为了减小可执行文件的大小,可以用strip工具来除去debug相关的符号信息。