引言
最近有个科研课题需要在树莓派上做一系列验证,但是实验的程序是依赖OpenCV库的(最重要我们修改了库源码),而在树莓派上编译OpenCV源码很费时间,因此我只好使用交叉编译的方法来编译源程序。刚开始我们觉着网上材料大片,这部分的问题应该不大。可到操刀干活的时候,我才发现网上很多方法不仅繁琐,而且有的甚至还不是那么一回事,没看到一篇完全适合我的情况的。于是,我花了一天半左右的时间,整理这些材料并结合一点TRIZ原理,完成了这项任务。现在分享一下我的方案总结,不过我的方案不尽完善,欢迎大家指点修正,帮助后人节省时间。
准备工作
首先,我的操作系统是Ubuntu16.04,其实OpenCV的交叉编译对系统并没有任何特殊要求,只是我个人觉着Linux操作环境比较方便而已,本文提供的方法理论上window系统只需稍加修改应该也是适用的。不过值得注意的是,如果想按照OpenCV官方教程(http://docs.opencv.org/master/d0/d76/tutorial_arm_crosscompile_with_cmake.html)的话,我建议使用14.04LTS的Ubuntu旧版本系统。因为16.04采用的编译工具已经升级到5.0了,它编译出来的文件需要依赖新版本的libstdc++库,要求树莓派更新安装gcc-5.0或g++-5.0才可以使用,但在树莓派上安装那玩意并不划算,所以我建议在老版本的Ubuntu环境下按照官方教程操作,从apt获取4.9以下的GNU交叉编译工具,交叉编译OpenCV3.0的目的。记得在树莓派上运行相应程序前,要将编译好的库文件拿进板载系统里面,并设置好相应的环境变量,具体后文会有详细介绍。
然后,安装下载git,cmake图形界面工具,树莓派编译工具,以及OpenCV源码。
参考操作:
apple@hello-world:~$ sudo apt-get install git cmake-qt-gui
apple@hello-world:~$ git clone https://github.com/opencv/opencv.git
apple@hello-world:~$ git clone https://github.com/raspberrypi/tools.git
安装下载完成后,我们就能看到当前目录下多了两个目录——opencv和tool——以及一个cmake-gui的指令,到这里我们的准备工作就完成了。
交叉编译OpenCV
完成了准备工作,接下来就是实际操做编译OpenCV。
1.建立编译链接目录,用cmake-gui配置编译工具
参考操作:
apple@hello-world:~$ cd opencv
apple@hello-world:~$ mkdir build
apple@hello-world:~$ cd build
apple@hello-world:~$ cmake-gui
进入如图所示的cmake图形界面。
1)先点击Browse Source…选择到opencv的根目录,如~/opencv
2)再点击Browse Build…选择到opencv下我们创建的编译链接目录,如~/opencv/build
3)最后点击Configure,进入编译器选择界面如下图
4)选择Specify options for cross-compiling,并点击Next进入编译器设置界面如下图
5)如图填写编译工具信息,其中比较重要的是Compilers下的C, C++, Target Root项。
其中C项代表的是树莓派编译工具的gcc编译器,如本文的
/home/apple/tools/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc
而C++项表示树莓派编译工具的g++编译器,如本文的
/home/apple/tools/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/bin/arm-linux-gnueabihf-g++
Target Root代表标准库与头文件的搜索起始位置,可以理解为对应交叉编译工具的根目录。
/home/apple/tools/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/arm-linux-gnueabihf
6)点击Finish生成一系列编译配置。
2.建立装载目录,配置编译选项,生成Makefile。
1)在编译链接目录下,建立一个装载目录。
apple@hello-world:~$ mkdir install
2)在Search栏上输入BUILD_SHARED_LIBS,并去掉对应value的勾,我们采用静态编译。
3)在Search栏上输入WITH_CUDA,也去掉对应value的勾,不编译CUDA部分代码。
4)在Search栏上输入CMAKE_INSTALL_PREFIX,将对应value的值改成我们build下的install装载目录,如/home/apple/opencv/build/install
5)在Search栏上输入BUILD_DOCS,去掉对应value的勾,表示不生成帮助文档。
6)在Search栏上输入WITH_CUFFT,去掉对应value的勾,表示不用cuda的fft。
7)在Search栏上输入CL,分别将WITH_OPENCL, WITH_OPENCLAMDBLAS, WITH_OPENCLAMDFFT, OPENCL_FOUND的勾去掉,我们的实验不采用OpenCL的GPU加速。
8)点击Configure,进度条完成后,再点击Generate,即会在build下产生Makefile编译文件。
3.修改CMakeCache.txt文件,编译并装载库文件。
1)打开CMakeCache.txt文件,查找CMAKE_CXX_FLAGS:STRING,并为其赋值-lpthread -lrt
apple@hello-world:~$ vim CMakeCache.txt
将CMAKE_CXX_FLAGS:STRING=
改成CMAKE_CXX_FLAGS:STRING=-lpthread -lrt
保存并关闭CMakeCache.txt文件。
2)执行编译装载指令。
apple@hello-world:~$ make
apple@hello-world:~$ make install
4.完成OpenCV的交叉编译。这时,我们可以检查以下install/lib目录下是否有我们所需要的.a静态库文件。如果存在这些文件,就表示我们已经编译装载成功了。
测试编译结果
最后,我们将install目录传到树莓派上做测试。注:下面的说明都建立在install目录已经在树莓派板子上的前提条件下。
1.修改~/.bashrc,在文件尾部添加下面两行代码:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/pi/install/lib
export LIBRARY_PATH=$LIBRARY_PATH:/home/pi/install/lib
2.执行install/bin下的opencv_version,如果打印输出是该opencv的版本号就表明咱们交叉编译成功!
总结
虽然上面的操作相当简单,但是如果对Linux系统的一些机制和编译流程没有一定理解,我想大家还是会有不少问题的。所以,欢迎大家评论提问,指点修正,集思广益。