- 目的:将OpenCV移植到ARM板上
- PC操作系统:VMWare虚拟机上安装的Ubuntu 20.04(x86_64)
- OpenCV版本:3.4.12
- 交叉工具链:arm-linux-gnueabihf,gcc version 9.3.0
- 目标平台:arm板
- 编译时间:2021.08.20
所谓的将OpenCV移植到某个平台,就是用该平台对应的编译器将OpenCV源代码编译成so库。OpenCV里面有很多库,这些库封装了我们想要的一些功能,但它只提供了源码工程,需要我们编译以后,去执行它的入口代码函数。
【参考:https://www.jianshu.com/p/0fcdce428d8f】
0、序言
【gcc、make、makefile、cmake、CMakeList.txt说明】
1)gcc
它是GNU Compiler Collection(GNU编译器套件),可以简单认为是编译器,可以编译很多编程语言:C、C++、Fortran、Java等。
我们的程序只有一个源文件时,直接可以用gcc命令编译它。但包含很多个源文件时,用gcc命令逐个去编译就会工作量巨大且很混乱,于是就出现了make工具。
2)make
make工具可以看成是一个智能的批处理工具,它本身并没有编译和链接的功能,而是类似批处理的方式通过调用makefile文件中用户指定的命令来进行编译和链接的。
3)makefile
make工具可以比作乐团的指挥家,makefile就像一首歌的乐谱,指挥家根据乐谱来指挥整个乐团该怎样演奏,make工具就是根据makefile中的命令进行编译和链接的,makefile命令中就包含了调用gcc(也可以是别的编译器)去编译某个源文件的命令。
在一些简单的工程中可以人工的处理makefile,当工程非常大的时候,手写就很麻烦;且换个平台makefile又要重新修改,于是就出现了cmake工具。
4)cmake
cmake工具可以更加简单的生成makefile文件给上面的make用。当然cmake还有更牛的功能就是可以跨平台的生成对应平台能用的makefile。
但cmake又是根据什么生成makefile的呢?是根据一个叫CMakeList.txt文件(学名:组态档)去生成makefile。
5)CMakeList.txt
CMakeList.txt就是用户自己手写的了。
PS:在cmake后会输出一些编译信息,并生成一些中间文件,最重要的就是makefile文件。其他的一些中间文件在发布代码时是可删除,不需要的,因此可以通过新建一个中间目录(文件夹)专门存放这些中间文件,编译成功后直接删除这个中间目录就可以了。一般是新建一个中间目录 build。(注意此时在终端中运行程序时,也需要使终端cd在build中间目录中)
//新建一个中间目录 build
mkdir build
//终端进入该目录
cd build
//使用cmake对工程进行编译
cmake .. //最后是两个“..”,表示对上一层目录进行编译
//最后使用make指令进行编译
make
一、下载OpenCV源码
地址:https://www.opencv.org/releases.html。
//在/opt下创建目录arm
cd /opt
sudo mkdir arm
//将OpenCV源码放到/opt/arm下
sudo cp /……/opencv-3.4.12.zip /opt/arm
//解压源码
unzip opencv-3.4.12.zip
*
//进入解压生成的opencv-3.4.12目录,在该目录下创建2个文件夹:build(存放配置的中间文件)和output(存放编译好的OpenCV输出文件)
cd opencv-3.4.12
mkdir build output
*
二、下载交叉编译的ARM库
编译在PC上,编译运行的目标平台是ARM平台,需要下载ARM库所依赖的文件资料,以使得PU Ubuntu上编译出来的OpenCV能在ARM平台上顺利跑起来。
//查看Ubuntu的系统是32位(i686)还是64位(x86-64)
sudo uname --m
注意:需确认系统是32位还是64位,选择对应版本的交叉编译工具,64位系统没安装32位运行库就不能运行32位软件。
①安装arm-linux-gcc
sudo apt-get install gcc-arm-linux-gnueabihf
②安装arm-linux-g++
sudo apt-get install g++-arm-linux-gnueabihf
③检测是否安装成功
//终端进入/usr/bin,输入以下命令
arm-linux-gnueabihf-gcc -v
//出现以下gcc版本信息,表示安装成功
Using built-in specs.
COLLECT_GCC=arm-linux-gnueabihf-gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc-cross/arm-linux-gnueabihf/5/lto-wrapper
Target: arm-linux-gnueabihf
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.9' --with-bugurl=file:///usr/share/doc/gcc-5/README.Bugs --enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-5 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-libitm --disable-libquadmath --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-5-armhf-cross/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-5-armhf-cross --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-5-armhf-cross --with-arch-directory=arm --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libgcj --enable-objc-gc --enable-multiarch --enable-multilib --disable-sjlj-exceptions --with-arch=armv7-a --with-fpu=vfpv3-d16 --with-float=hard --with-mode=thumb --disable-werror --enable-multilib --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=arm-linux-gnueabihf --program-prefix=arm-linux-gnueabihf- --includedir=/usr/arm-linux-gnueabihf/include
Thread model: posix
gcc version 5.4.0 20160609 (Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.9)
三、配置工具链
①新建build目录
用于存放编译好的配置文件等信息
sudo mkdir build
②安装cmake-gui
OpenCV 2.2以后版本需要使用cmake生成编译OpenCV的makefile文件,需要先安装cmake / cmake-gui。
//查看是否已安装cmake
cmake --version //若无提示则表示未安装
sudo apt-get install cmake-gui //cmake-gui 可以调用图形化界面进行配置
cmake-gui --version //查看安装成功与否
//若要卸载cmake
sudo apt-get autoremove cmake
③工具链配置界面进行配置
1、终端输入以下命令
sudo cmake-gui //进入工具链配置界面
说明:
Where is the source code对应opencv的文件夹,Where to build the binaries对应opencv存放编译好的配置文件等信息的文件夹(刚才创建的build文件夹)
2、点击Configure,弹出编译方式选择对话框:
3、点击Next:
说明:Operating System 输入Linux ;Processor 输入 arm ;C 输入arm-linux-gnueabihf-gcc路径:/usr/bin/arm-linux-gnueabihf-gcc;C++路径:/usr/bin/arm-linux-gnueabihf-g++;Target Root输入:/usr/arm-linux-gnueabihf/lib
4、点击Finish。
5、Search位置输入Z,把zip库(BUILD_ZLIB选项)选中(Ubuntu 20.04 不选择可能会报错)。
6、Search位置输入install(CMAKE_INSTALL_PREFIX选项),修改下opencv编译后存放的目录路径:这里随便选择一个空的目录即可。
7、点击Configure。
8、点击Generate。关闭对话框。
四、编译项目
//进入build目录
cd /……/build
//执行编译
sudo make -j7 //成功出现 [100%] Built target opencv_test_……
//继续
sudo make install //成功出现 -- Set runtime path of "/home/lutos/bin/opencv_version" to "/home/lutos/lib"
说明:存放编译后的opencv执行文件的目录出现文件表示编译完成。
五、跑一个程序验证
1、创建并编译helloworld.cpp
简单试验一下
//创建一个目标文件夹,并进入该文件夹下
mkdir -p proj/helloworld
cd ~/proj/helloword
//创建helloworld.cpp
touch helloworld.cpp
//使用vim或gedit编辑代码
vim helloworld.cpp
//在vim编辑界面中输入如下代码
#include <iostream>
using namespace std;
int main()
{
cout<<"hello world"<<endl;
return 0;
}
//保存退出,回到命令行界面,编译并链接helloworld.cpp
g++ helloworld.cpp -o helloworld
//如果是.c文件,就用gcc -o helloworld helloworld.c
//执行此命令后检查
ls
//可以看到目录中生成了一个名为helloworld的无后缀文件,执行
./helloworld
//输出结果
2、检测是否生成ARM文件
//继续在上述工程文件夹下运行
arm-linux-g++ helloworld.cpp -o pp //不报错能成功编译即说明已完美安装
//用file命令查看编译后是否为arm的可执行文件
file pp
可以看到编译后的可执行文件是在 32-bit 的 ARM架构上运行的。
*
sudo rm xx.yy //删除xx.yy文件
sudo cp -r xxx /usr/local/arm //将当前文件夹下的xxx全部移动到arm下
sudo cp /……/xxx.tar.gz /usr/local/arm //将xxx.tar.gz拷贝到/usr/local/arm下
sudo tar -zxvf arm-linux-gcc-4.4.3.tar.gz //解压.gz文件
sudo tar -jxvf xxx.tar.bz2 //解压.tar.bz2文件
//解压tar.xz文件
sudo xz -d xxx.tar.zx //先解压成.tar文件
sudo tar xvf xxx.tar //再解压
*
其他可能出现问题:
1、添加交叉编译器到系统环境变量
//打开/etc/profile或者/root/.bashrc或者/etc/bash.barhrc
gedit /etc/bash.barhrc
//在最后一行添加上
export PATH=$PATH:/usr/local/arm/······/bin //······gcc-4.6.4。添加执行程序的环境变量
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/arm/······/bin //库文件的路径
//保存,然后source
source /etc/bash.barhrc
//测试环境变量是否添加成功
echo $PATH
//输出信息里有刚才添加的路径信息,继续在任意目录下输入
//检验是否安装成功
cd /
arm-none-linux-gnueabi-gcc -v
arm-linux-gcc -v //也可以用该命令
出现以下信息说明安装成功:
2、修改CMakeCache.txt文件
找到CMAKE_EXE_LINKER_FLAG:STRING=
修改为CMAKE_EXE_LINKER_FLAG:STRING=-lpthread -ldl -lrt
意思是:-lpthread支持线程;-ldl避免未定义dlopen;-lrt避免未定义