先介绍下环境:pc(虚拟机)+ubuntu11.10+qt4.8+arm6410(飞凌的),申明下解决onot found (try using -rpath or -rpath-link)的方法是换成了opencv2.0版本,待我慢慢道来!
自从移植完qt4.8后,就可以移植opencv,因为做视觉处理算法不移植不好搞啊!开始了蛋疼的opencv移植,参见我的救急帖子:http://topic.csdn.net/u/20120427/08/ae5d7b21-e58c-4b9a-8a79-a229e38195cc.html?seed=1445143701&r=78398534#r_78398534。为了后人少走弯路,我说下心得:
(1)不管移植不移植,在opencv没有和qt结合以前,大家要先写个小例子测试一下。新建test.c文件,代码如下:
#include
#include
#include
int main()
{
IplImage *img = cvLoadImage("/ayan/r3.jpeg",1);
cvNamedWindow( "Image", 1 );//创建窗口
cvShowImage( "Image", img );//显示图像
cvWaitKey(0); //等待按键
cvDestroyWindow( "Image" );//销毁窗口
cvReleaseImage(&img);
printf("OK!\n");
return 0;
}
如果出现大量undefined reference的错误,检查下编译器格式问题,正确的是:gcc test.c -o test -I/usr/include/opencv -L/usr/lib -lml -lcvaux -lhighgui -lcv -lcxcore ,这里先用pc机上测试下,注意这个include的目录和lib的目录是我linux 386系统安装的opencv,不是移植的arm版的。如果你写成:gcc -I/usr/include/opencv-L/usr/lib -lml -lcvaux -lhighgui -lcv -lcxcore-o test test.c,将会出现大量undefined reference的错误,错误提示如下,只摘录前几行:
/tmp/ccNgdhSo.o: In function `cvRound':
test.c:(.text+0x19): undefined reference to `lrint'
/tmp/ccNgdhSo.o: In function `cvDecRefData':
test.c:(.text+0xa5a): undefined reference to `cvFree_'
test.c:(.text+0xacb): undefined reference to `cvFree_'
/tmp/ccNgdhSo.o: In function `cvGetRow':
test.c:(.text+0xbc1): undefined reference to `cvGetRows'
/tmp/ccNgdhSo.o: In function `cvGetCol':
test.c:(.text+0xbec): undefined reference to `cvGetCols'
/tmp/ccNgdhSo.o: In function `cvReleaseMatND':
test.c:(.text+0xbff): undefined reference to `cvReleaseMat'
/tmp/ccNgdhSo.o: In function `cvSubS':
test.c:(.text+0xd1f): undefined reference to `cvAddS'
/tmp/ccNgdhSo.o: In function `cvCloneSeq':
test.c:(.text+0xd6d): undefined reference to `cvSeqSlice'
/tmp/ccNgdhSo.o: In function `cvSetNew':
test.c:(.text+0xdcc): undefined reference to `cvSetAdd'
/tmp/ccNgdhSo.o: In function `cvGetSetElem':
test.c:(.text+0xe5f): undefined reference to `cvGetSeqElem'
/tmp/ccNgdhSo.o: In function `cvEllipseBox':
test.c:(.text+0xf5f): undefined reference to `cvEllipse'
/tmp/ccNgdhSo.o: In function `cvFont':
test.c:(.text+0xfa9): undefined reference to `cvInitFont'
/tmp/ccNgdhSo.o: In function `cvReadIntByName':
test.c:(.text+0x1057): undefined reference to `cvGetFileNodeByName'
/tmp/ccNgdhSo.o: In function `cvReadRealByName':
test.c:(.text+0x10e8): undefined reference to `cvGetFileNodeByName'
/tmp/ccNgdhSo.o: In function `cvReadStringByName':
test.c:(.text+0x1142): undefined reference to `cvGetFileNodeByName'
/tmp/ccNgdhSo.o: In function `cvReadByName':
test.c:(.text+0x1172): undefined reference to `cvGetFileNodeByName'
test.c:(.text+0x1188): undefined reference to `cvRead'
/tmp/ccNgdhSo.o: In function `cvCreateSubdivDelaunay2D':
test.c:(.text+0x1287): undefined reference to `cvCreateSubdiv2D'
如果您出现了undefined reference 请首先排查这个错误!
(2)如果您还没移植opencv请看这里。参照网上若干文章,我最初移植的是opencv2.1,什么都搞好了,用上述在gcc编译器下证实的正确代码测试,总是出现/usr/local/arm/4.3.2/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.2/../../../../arm-none-linux-gnueabi/bin/ld: warning: ../../lib/libcxcore.so, needed by /usr/local/arm/opencv-2.1/lib/libcv.so, not found (try using -rpath or -rpath-link)
/usr/local/arm/4.3.2/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.2/../../../../arm-none-linux-gnueabi/bin/ld: warning: ../../lib/libcv.so, needed by /usr/local/arm/opencv-2.1/lib/libcvaux.so, not found (try using -rpath or -rpath-link)
/usr/local/arm/4.3.2/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.2/../../../../arm-none-linux-gnueabi/bin/ld: warning: ../../lib/libhighgui.so, needed by /usr/local/arm/opencv-2.1/lib/libcvaux.so, not found (try using -rpath or -rpath-link)
/usr/local/arm/4.3.2/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.2/../../../../arm-none-linux-gnueabi/bin/ld: warning: ../../lib/libml.so, needed by /usr/local/arm/opencv-2.1/lib/libcvaux.so, not found (try using -rpath or -rpath-link)
的蛋疼错误!在/etc/profile里也加export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/arm/opencv/lib这句话了,然后source /etc/profile. 不中后,gedit /etc/ld.so.conf也 include/usr/local/arm/opencv/include/opencv,然后 ldconfig依旧不中!最后找到了/usr/local/arm/qte-4.8.0/mkspec/default/qmake.conf,修改这个文件,添加:CPPFLAGS="-I /usr/local/arm/opencv/include/opencv"
LDFLAGS="-L /usr/local/arm/opencv/lib" 。。。。依旧不中!将这五个.so文件拷贝到交叉编译器的相关目录下依旧不中! 最后想到修改MakeFile,将原始的
LIBS = $(SUBLIBS) -L/usr/local/arm/qte-4.8.0/lib /usr/local/arm/opencv/lib/libcv.so /usr/local/arm/opencv/lib/libcvaux.so /usr/local/arm/opencv/lib/libcxcore.so /usr/local/arm/opencv/lib/libhighgui.so /usr/local/arm/opencv/lib/libml.so -lQtGui -L/usr/local/arm/qte-4.8.0/lib -lQtNetwork -lQtCore -lpthread,以为这句话有问题,将其改成:
LIBS = $(SUBLIBS) -L/usr/local/arm/qte-4.8.0/lib -lQtGui -L/usr/local/arm/qte-4.8.0/lib -lQtNetwork -lQtCore -L/usr/local/arm/opencv/lib -lml -lcvaux -lhighgui -lcv -lcxcore -lpthread
以为这下格式可对了,依旧not found (try using -rpath or -rpath-link)!我日!!!最后参照http://blog.sina.com.cn/s/blog_602f87700100nyda.html
http://blog.sina.com.cn/s/blog_602f87700100fbm3.html 和http://www.cnblogs.com/s_agapo/archive/2011/11/24/2262346.html
,将makefile里添加:LFLAGS = -Wl,-O1 -Wl,-rpath,/usr/local/arm/qte-4.8.0/lib:-Wl,-O1 -Wl,-rpath,/usr/local/arm/opencv/lib以为这下可好了,谁知还是错! 靠,惹火老子了!直接决定移植opencv2.0拉倒,参考http://blog.csdn.net/chennxi/article/details/6082039,我的配置为:./configure --host=arm-linux --without-gtk --without-carbon --without-quicktime --without-1394libs --without-ffmpeg --without-python --without-swig --enable-static --enable-shared --disable-apps CXX=arm-linux-g++ CPPFLAGS=-I/usr/local/arm/4.3.2/arm-none-linux-gnueabi/include LDFLAGS=-L/usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/lib --with-v4l2 --prefix=/usr/local/arm/opencv --libdir=/usr/local/arm/opencv/lib -includedir=/usr/local/arm/opencv/include
安装好后,首先在nfs测试的,编译上述的test.c文件,arm-linux-gcc test.c -o test-arm -I/usr/local/arm/opencv/include/opencv -L/usr/local/arm/opencv/lib -lml -lcvaux -lhighgui -lcv -lcxcore -lpthread -lrt编译通过,将可执行文件复制到板子里运行,会提示这不到libcv。so,记得要添加环境变量:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/arm/opencv/lib,运行./test-arm会提示 什么highgui的函数不支持,gtk之类的!这就对了!
提示: 在pc linux上交叉编译时,一定要指定-I/usr/local/arm/opencv/include/opencv -L/usr/local/arm/opencv/lib -lml -lcvaux -lhighgui -lcv -lcxcore,即便你设置了LD_LIBRARY_PATH,如果不加这个-I 和-L 依旧会出错。反之,如果不设LD_LIBRARY_PATH,只需指定-I和-L也是可以的!!!
(3)如果不用nfs,要将opencv下的lib和include拷贝到相同目录下。在拷贝时,会出现找不到.so,这是因为用cp命令拷贝时找不到 快捷方式所致的,解决办法有两种,1,直接给.so文件改名字,比如提示找不到libcv.so,你到板子里发现就是没有libcv.so,只有libcv.so.4.0,你再到pc机上查看发现有libcv.so libcv.so.4 和lib.so.4.0三个文件,前两个都是快捷方式,用ls -al 命令,会看到libcv.so 指向libcv.so.4.0,在板子里连的超级终端,cd到lib的目录, 用ln -s libcv.so.4.0(老名字) libcv.so(新名字,快捷方式)
即可!2,直接mv libcv.so.4.0 libcv.so 就是直接改名字的意思!
(4)至此,我们回顾为什么会not found (try using -rpath or -rpath-link),只能一种解释,cmake2.8.5下make出来的.so 文件 arm-linux-gcc-4.3.2不识别!参照http://blog.sina.com.cn/s/blog_602f87700100nyda.html这篇文章,即便需要用到动态链接库,只需在LFLAGS中添加了:-Wl,-rpath-link -Wl,/。。、。。。/.....(lib的目录)就可以了!
(5)qmake生成的makefile的正确格式,就是LIBS = $(SUBLIBS) -L/usr/local/arm/qte-4.8.0/lib /usr/local/arm/opencv/lib/libcv.so /usr/local/arm/opencv/lib/libcvaux.so /usr/local/arm/opencv/lib/libcxcore.so /usr/local/arm/opencv/lib/libhighgui.so /usr/local/arm/opencv/lib/libml.so -lQtGui -L/usr/local/arm/qte-4.8.0/lib -lQtNetwork -lQtCore -lpthread这样的! 这是没问题的! 只需在.pro文件里添加:
INCLUDEPATH += /usr/local/arm/opencv/include/opencv
LIBS += /usr/local/arm/opencv/lib/libcv.so \
/usr/local/arm/opencv/lib/libcvaux.so \
/usr/local/arm/opencv/lib/libcxcore.so \
/usr/local/arm/opencv/lib/libhighgui.so \
/usr/local/arm/opencv/lib/libml.so
就可以了!另外在设置export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/arm/opencv/lib,如果你opencv编译正确的话只需这两个额外的设置,qt就可以用opencv了! 其他的一律多余!
(6)网上至今没有qt下的用opencv的测试程序,我这里提供一个代码,利用cvLoadImage 读一个函数,将IplImage格式转成Qimage格式,并显示出来。图片的路径是/ayan/r3.jpeg。鄙人姓晏,呵呵,在根目录下建文件夹ayan,然后把r3.jpeg拷贝到文件夹下。 在arm板子上也做如下操作。运行前设置export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/arm/opencv/lib就可以了!下载地址我会上传。。。。。
一点疑惑:
1,我在移植qt的时候设置了环境变量export QTDIR=/usr/local/arm/qte-4.8.0
export LD_LIBRARY_PATH=$QTDIR/lib:/usr/local/arm/opencv-2.1/lib:$LD_LIBRARY_PATH
export QT_QWS_FONTDIR=/usr/local/arm/qte-4.8.0/lib/fonts
export QWS_DISPLAY='LinuxFb:mmWidth76:mmHeight44:1'
但在后来的qt测试程序中,我没有设置这些环境变量程序照样运行了!我用env命令查看的确没有这些变量的设置。但用到opencv时 ,就必须设置opencv的lib目录!这是为何???
(2)arm板子上 用opencv预览视频,虽然在pc机上跑通了,但在板子上出现了错误,蛋疼啊!段错误!我用的是飞凌的6410上面已经可以播放视频了,请问还需要移植xvid、ffmpeg这些东西吗??
(3)gtk这个玩意究竟能移植到arm6410上吗??