这个交叉编译折磨了我好几天,刚刚实践成功,迫不及待的跟大家分享一下,希望对你有用哦。
操作环境:Ubuntu 14.04
编译器:arm-linux-guneabi-gcc
Cmake版本:2.8.12.2
Cmake-gui:版本与cmake相同
目标主机:T717
Opencv版本:3.1.0
依赖库版本:
Libz:zlib-1.2.11 下载网址:https://sourceforge.net/projects/libpng/files/zlib/1.2.11/zlib-1.2.11.tar.gz/download?use_mirror=nchc&download=
Libx264:x264-snapshot-20191124-2245
下载网址:http://www.videolan.org/developers/x264.html
Libxvid:xvidcore-1.3.5
下载网址:https://labs.xvid.com/source/
Ffmpeg:ffmpeg-4.2.1
下载网址:http://ffmpeg.org/download.html
一、安装依赖项
在终端依次执行以下操作:
(1)安装pkg-config
sudo apt-get install pkg-config
sudo apt-get install libgtk2.0-dev
(2)安装依赖项
sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev
这几项与视频解码相关,不安装的话后面 opencv make时会出现下图情况:
参考:https://my.oschina.net/u/1250206/blog/850302
二、安装依赖库
(1)目标主机安装目录构建
移植opencv其实不难,重点在于弄清安装路径和编译器,只要不和本地opencv弄混,理论上来讲就没问题了。我们首先在开发主机上构建一个临时安装环境,便于交叉编译过程依赖库的搜索以及方便最后向目标主机转移安装,还有最重要的一点就是防止与开发主机环境弄混。终端执行:
cd home/xlb/opt/ #这里的xlb是我的用户名
mkdir arm
本文的安装目录是home文件夹下的opt文件夹,注意与系统目录下的opt文件夹区分开。将前文所提到的依赖库和opencv源码解压到opt文件夹下,接下来先对依赖库进行交叉编译并安装到临时安装目录opt/arm下。
(2)交叉编译libz
cd /home/xlb/zlib-1.2.11 #进入zlib源码目录
./configure --prefix=/home/xlb/opt/arm --shared #prefix参数指定了临时安装目录
配置完成后会生成makefile文件,需要对makefile文件进行修改,适配交叉编译工具链。
终端执行:
gedit Makefile #用编辑器打开Makefile文件并进行以下对应部分的修改
CC = arm-linux-gnueabi-gcc #交叉编译工具链
AR = arm-linux-gnueabi-ar
RANLIB = arm-linux-gnueabi-ranlib
LDSHARED = arm-linux-gnueabi-gcc -shared -wl, -soname,libz.so.1,--version-script,zlib.map
修改完成后,保存,下一步进行编译和安装。终端执行:
make
make install
可能出现的错误:
xlb@xlb-VirtualBox:~/opt/zlib-1.2.11$ make
arm-linux-gnueabi-gcc -O3 -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN -I. -c -o example.o test/example.c
make: arm-linux-gnueabi-gcc: Command not found
make: *** [example.o] Error 127
解决办法:
需要把交叉编译器所在的目录加到环境变量中,在终端执行:
sudo –s
cd etc
gedit profile
打开profile文件后,添加export PATH=$PATH:/home/user/linux/bin,冒号后是交叉编译工具arm-linux-gnueabi-gcc所在目录。修改完成后保存并关闭。
终端执行以下命令使环境变量修改立即生效:
source /etc/profile/
参考:https://blog.csdn.net/polarisyj86/article/details/89395083
(2)交叉编译libx264
在终端执行以下命令:
cd /home/xlb/opt/ x264-snapshot-20191124-2245
CC=arm-linux-gnueabi-gcc ./configure --enable-shared --host=arm-linux-gnueabi --disable-asm --prefix=/home/xlb/opt/arm
没有错误的话,继续执行:
make
make install
(3)交叉编译libxvid
在终端依次执行:
cd /home/xlb/opt/ xvidcore-1.3.5
cd build/generic #切换到编译脚本所在的目录
./configure --prefix=/home/xlb/opt/arm --host=arm-linux-gnueabi --disable-assembly
如果看到一堆yes说明配置没有问题,继续执行:
make
make install
(4)交叉编译ffmpeg
在终端执行:
cd /home/xlb/opt/ffmpeg-4.2.1
./configure --prefix=/home/xlb/opt/arm --enable-shared --disable-static --enable-gpl --enable-cross-compile --arch=arm --disable-stripping --target-os=linux --enable-libx264 --enable-libxvid --cc=arm-linux-gnueabi-gcc --enable-swscale --extra-cflags=-I/home/xlb/opt/arm/include/ --extra-ldflags=-L/home/xlb/opt/arm/lib/
注意,刷最后两句是前面三个依赖库的安装目录,如果不加上可能会报libx264 not found错误。
到这里如果没有报错,就可以进行编译安装了,终端执行:
make
make install
三、交叉编译opencv
(1)设置工具链toolchain.cmake
在用cmake编译之前首先要构建工具链cmake文件,在终端执行:
cd home/xlb/opt
cd opencv-3.1.0/
mkdir arm-build
cd ./arm-build
gedit toolchain.cmake
在打开的toolchain.cmake文件中添加以下内容:
set( CMAKE_SYSTEM_NAME Linux )
set( CMAKE_SYSTEM_PROCESSOR arm )
set( CMAKE_C_COMPILER arm-linux-gnueabi-gcc )
set( CMAKE_CXX_COMPILER arm-linux-gnueabi-g++ )
set( CMAKE_FIND_ROOT_PATH "/home/xlb/opt/arm/lib" ) #这里要和上面编译安装的目录对应
set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER )
set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY )
set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY )
#最后这四个参数非常重要,如果设置不对,可能编译完成后,仍然找不到。
保存关闭后,在终端执行
cmake -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake ../ #注意这里空格和.的个数
完成后显示如下图所示,FFMPEG对应部分都显示为yes,说明没有问题,可以继续下一步操作。如果FFMPEG为NO,解决方法见以下链接内容:https://blog.csdn.net/m0_37967533/article/details/99623736
(2)对opencv进行cmake配置
如果pc机没有安装cmake,在终端执行以下命令进行安装:
sudo apt-get install cmake cmake-gui
依旧在arm-build目录下,输入以下命令打开cmake界面程序:
cmake-gui
按照下图所示进行设置,其中where is the source code选择opencv源码目录, where to build the binaries为存放生成的编译文件的位置,CMAKE_INSTALL_PREFIX选择自己的安装路径。
点击configure,在弹出框中选择最后一项,然后点击next,如下图所示:
然后进行交叉工具链信息配置,在“operating system”填入Linux或arm-Linux,C Compolers选择交叉编译器arm-linux-gnueabi-gcc,C++ Compolers选择交叉编译器arm-linux-gnueabi-g++,Target Root选择交叉编译器所在路径,然后点击Finish。
根据需要(你用到的库)勾选配置文件,可参考如下选取方式:
去掉 WITH_CUDA
去掉 WITH_GTK
去掉 WITH_1394
去掉 WITH_GSTREAMER
去掉 WITH_LIBV4L
去掉 WITH_TIFF
去掉 BUILD_OPENEXR
去掉 WITH_OPENEXR
去掉 BUILD_opencv_ocl
去掉 WITH_OPENCL
参考链接:https://blog.csdn.net/ajianyingxiaoqinghan/article/details/70194392
依次点击Configure和Generate,生成makefile文件。此时修改在/opencv-3.1.0/opencv-con文件夹中的CMakeCache.txt:CMAKE_EXE_LINKER_FLAGS选项本来为空,在后面加上:-lpthread -lrt。
(3)编译opencv
在opencv-con文件夹下执行:
make
make install
等待较长一段时间后,opencv的交叉编译就完成了。
四、可能出现的错误及处理方法
错误一:
../../3rdparty/lib/libzlib.a(gzlib.c.obj):relocation R_ARM_THM_MOVW_ABS_NC against `a local symbol' can not beused when making a shared object; recompile with –fPIC
解决方式:3rdparty/zlib/CMakeFiles/zlib.dir/flags.make文件的C_FLAGS中添加-fPIC,即C_FLAGS = -W -Wall 改为 C_FLAGS = -fPIC -W –Wall。类似的错误可能出现多次,需要将3rdparty文件夹下的每一个第三方库文件夹内的flags.make都做修改。
错误二:
./../lib/libopencv_ocl.so: undefined reference to `dlopen'
../../lib/libopencv_ocl.so: undefined reference to `dlsym'
collect2: error: ld returned 1 exit status
make[2]: *** [bin/opencv_perf_ocl] Error 1
make[1]: *** [modules/ocl/CMakeFiles/opencv_perf_ocl.dir/all]Error 2
make: *** [all] Error 2
解决方式:出现这个错误的原因是没有找到dl库,需要修改build里面的CMakeCache.txt,在CMAKE_EXE_LINKER_FLAGS= -lpthread -lrt -ldl即可。
错误三:
配置完ffmpeg,make过程中出现如下错误
解决方式:
应该是版本过老的问题,最新版本接口有所调整,去http://ffmpeg.org/download.html下载最新版本的ffmpeg即可解决该问题。
错误四:
ffmpeg 安装时报ERROR: libx264 not found 异常。
解决方式:前文已经提及,在配置时加上最后两句,该部分告诉了编译器依赖库的安装位置。
../configure --prefix=/home/hrx/build_opencv/opencv_depend/ --enable-gpl --enable-shared --cross-prefix=arm-poky-linux-gnueabi- --cc="arm-poky-linux-gnueabi-gcc -march=armv7-a -mthumb-interwork -mfloat-abi=hard -mfpu=neon -mtune=cortex-a7" --enable-cross-compile --arch=arm --target-os=linux --enable-nonfree --enable-pthreads --enable-ffplay --extra-cflags=-I/opt/arm/include/ --extra-ldflags=-L/opt/arm/lib/
如果还是不行,考虑路径错误或者检查命令的空格、分隔符等是否有错误。
错误四:
编译opencv时报下图错误
解决方式:
这个在前文中已经说过,在第三方库的flag.make文件中加入-fPIC。如果还不行,参考https://www.bbsmax.com/A/x9J2DWmed6/,将ffmpeg静态库更改为使用动态库,即在终端进入opencv源码目录,执行:
sed -i -e 's/libavformat\.a/libavformat.so/g' \
-e 's/libavutil\.a/libavutil.so/g' \
-e 's/libswscale\.a/libswscale.so/g' \
-e 's/libavresample\.a/libavresample.so/g' \
-e 's/libavcodec\.a/libavcodec.so/g' \
cmake/OpenCVFindLibsVideo.cmake
如果有其他问题欢迎站内提问