宿主机:Ubuntu16.04 x86
目标平台:RP-RK1808,aarch64
交叉编译工具链:gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu
架构-操作系统-程序二进制接口约定
aarch64-linux-gnu
依赖关系:
opencv(3.4.3)
|--------zlib(1.2.11)
|--------ffmpeg(4.2.1)
|--------x264(20181217(0.161.x))
|--------xvidcore(1.3.3)
注意,网上部分教程说需要下载ffmpeg依赖项
apt-get install libavcodec-dev libavformat-dev libswscale-dev
但是交叉编译并不需要这个,并且这个可能会影响后面的交叉编译,使得看起来找到了ffmpeg依赖项,但是交叉编译之后无法使用。
这是因为直接下载的依赖项是x86架构的,而目标平台是aarch64架构的。
依赖项的查找依靠pkgconfig工具,依靠*.pc文件。
而FFMPEG始终为NO的解决就依靠pkgconfig工具,具体见4.opencv交叉编译
相关源码包以及交叉编译好的文件等有时间了再放链接吧。
注意,本教程因为写的时候离编译较久,可能有许多错误之处,切勿全抄,思考着编译。
以下是本篇文章正文内容。
简单来说,交叉编译就是在宿主机上编译可以在目标机上运行的代码。
前期准备
sudo gedit /root/.bashrc
export PATH=$PATH:/home/rpdzkj/cfan/Source/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin//指定交叉编译工具链目录
export OPENCV_DEPEND=/usr/local/arm/opencv-depend
export OPENCV_INSTALL=/usr/local/arm/opencv-install
source /root/.bashrc//使生效
aarch64+tab//测试,是否会自动补齐出aarch64-linux-gnu-gcc、g++等,补齐则生效
//进入解压得到的zlib文件夹
./configure --prefix=$OPENCV_DEPEND//指定安装目录
之后,对Makefile文件进行修改,修改内容如下:
CC=aarch64-linux-gnu-gcc
LDSHARED=aarch64-linux-gnu-gcc -shared -Wl,-soname,libz.so.1,--version-script,zlib.map
AR=aarch64-linux-gnu-ar
RANLIB=aarch64-linux-gnu-ranlib
最后
make
cd /home/rpdzkj/lib/x264-master
gedit config.mak
CC=aarch64-linux-gnu-gcc
LDSHARED=aarch64-linux-gnu-gcc -shared -Wl,-soname,libz.so.1,--version-script,zlib.map
AR=aarch64-linux-gnu-ar
RANLIB=aarch64-linux-gnu-ranlib
STRIP=aarch64-linux-gnu-strip
make install
报错libx264.a(bitstream-8.o): In function x264_8_bitstream_init': bitstream.c:(.text+0x19c): undefined reference to
x264_8_nal_escape_neon’
bitstream.c:(.text+0x1a0): undefined reference to `x264_8_nal_escape_neon’
很多未定义,我去官网下载了源码包之后解决
cd /home/rpdzkj/lib/xvidcore-1.3.3
cd ./build/generic
./configure --prefix=$OPENCV_DEPEND --host=aarch64-linux --disable-assembly
按照教程来的话,这一步采用的编译工具就是gcc,,虽然说本质上aarch64-gcc就是gcc,但还是修改一下吧。
CC=aarch64-linux-gnu-gcc ./configure --prefix=$OPENCV_DEPEND --host=aarch64-linux --disable-assembly
加了CC,但是没用,还是gcc,算了接着往下走。如果有知道为什么的大佬麻烦请在评论区或者私信告诉下我为什么,不胜感激。
make
完成后看下文件格式
file libxvidcore.so.4.3
ibxvidcore.so.4.3: ELF 64-bit LSB shared object, ARM aarch64,
make install
cd /home/rpdzkj/lib/ffmpeg-4.2.1
./configure --prefix=$OPENCV_DEPEND --enable-shared --disable-static --enable-gpl --enable-cross-compile --arch=aarch64 --disable-stripping --target-os=linux --enable-libx264 --enable-libxvid --cc=aarch64-linux-gnu-gcc --enable-swscale --extra-ldflags=-L$OPENCV_DEPEND/lib --extra-cflags=-I$OPENCV_DEPEND/include --pkg-config=PKGCONFIG --ar=aarch64-linux-gnu-ar --ranlib=aarch64-linux-gnu-ranlib
make
make install
cd opencv-3.4.3
mkdir build
cd ./build
gedit toolchain.cmake
###########user defined#############
set( CMAKE_SYSTEM_NAME Linux )
set( CMAKE_SYSTEM_PROCESSOR aarch64 )
set( CMAKE_C_COMPILER aarch64-linux-gnu-gcc )
set( CMAKE_CXX_COMPILER aarch64-linux-gnu-g++ )
###########user defined#############
set( CMAKE_FIND_ROOT_PATH “/usr/local/arm/opencv-depend” )
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 ../
其实上述toolchain文件并不一定要写,现在的cmake-gui已经有足够多的选项完成上述工作,不过我现在没时间再交叉编译一遍了。
这里只有一个问题,交叉编译好的ffmpeg始终找不到。
上述命令执行完会有提示
openCV disables pkg-config to avoid using of host libraries. Consider using PKG_CONFIG_LIBDIR to specify target SYSROOT
之前一直没注意到这句提示,真的困扰了我很久,不打开pkgconfig的话ffmpeg始终找不到。
WITH_FFMPEG:判断是否引用ffmpeg,设为ON,在CmakeLists里,gui里也可以设置
HAVE_FFMPEG:判断是否有ffmpeg,这个是重点
pkgconfig设置
if(UNIX)
if(NOT APPLE_FRAMEWORK OR OPENCV_ENABLE_PKG_CONFIG)
if(CMAKE_CROSSCOMPILING AND NOT DEFINED ENV{PKG_CONFIG_LIBDIR} AND NOT OPENCV_ENABLE_PKG_CONFIG )
if(NOT PkgConfig_FOUND)
message(STATUS "OpenCV disables pkg-config to avoid using of host libraries. Consider using PKG_CONFIG_LIBDIR to specify target SYSROOT")
elseif(OPENCV_SKIP_PKG_CONFIG_WARNING)
message(WARNING "pkg-config is enabled in cross-compilation mode without defining of PKG_CONFIG_LIBDIR environment variable. This may lead to misconfigured host-based dependencies.")
endif()
elseif(OPENCV_DISABLE_PKG_CONFIG) if(PkgConfig_FOUND)
message(WARNING "OPENCV_DISABLE_PKG_CONFIG flag has no effect")
endif()
else() find_package(PkgConfig QUIET)
endif()
endif()
先尝试启动pkgconfig
cmake-gui通过Add Entry按钮添加 OPENCV_ENABLE_PKG_CONFIG,选bool类型,打勾。
显示
Checking for modules 'libavcodec;libavformat;libavutil;libswscale'
Found libavcodec, version 56.60.100
Found libavformat, version 56.40.101
Found libavutil, version 54.31.100
Found libswscale, version 3.1.101
Checking for module 'libavresample'
No package 'libavresample' found
WARNING: Can't build ffmpeg test code//重点,测试ffmpeg
Video I/O:
DC1394: NO
FFMPEG: NO
avcodec: YES (ver 56.60.100)
avformat: YES (ver 56.40.101)
avutil: YES (ver 54.31.100)
swscale: YES (ver 3.1.101)
avresample: NO
GStreamer: NO
libv4l/libv4l2: NO
v4l/v4l2: linux/videodev2.h
gPhoto2: NO
但是找到的版本号不对,并且ffmpeg始终为NO,这是因为我一开始按网上教程所说下载了ffmpeg依赖项,但是其架构是x86,而我需要aarch64的。
并且ffmpeg找到依赖项后会进行测试,就是因为测试不通过,所以ffmpeg始终为NO。
--- FFMPEG ---
ocv_clear_vars(HAVE_FFMPEG)
if(WITH_FFMPEG)
if(WIN32 AND NOT ARM)
elseif(PKG_CONFIG_FOUND)
ocv_check_modules(FFMPEG libavcodec libavformat libavutil libswscale)
ocv_check_modules(FFMPEG_libavresample libavresample)
else()
message(STATUS "Can't find ffmpeg - 'pkg-config' utility is missing")
endif()
endif(WITH_FFMPEG)
指定pkgconfig路径
cp -r /usr/local/arm/opencv-depend/include/ /home/rpdzkj/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/include
cp -r /usr/local/arm/opencv-depend/lib/ /home/rpdzkj/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/lib
export PKG_CONFIG_PATH=/home/rpdzkj/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/lib/pkgconfig/
最后显示
Video I/O:
DC1394: NO
FFMPEG: YES
avcodec: YES (ver 58.54.100)
avformat: YES (ver 58.29.100)
avutil: YES (ver 56.31.100)
swscale: YES (ver 5.5.100)
avresample: NO
GStreamer: NO
libv4l/libv4l2: NO
v4l/v4l2: linux/videodev2.h
gPhoto2: NO
就可以正常交叉编译opencv了,剩下的可以看网上其他教程,好久之前编译的,现在记不住细节了。
这个是好久之前完成的,拖了好久才开始写博客,好多细节都忘掉了,***可能有很多错误之处,大家交叉编译时不必照抄,更多是思考着进行交叉编译。***不然很容易扎进某个错误里,白白浪费很多精力。发现了错误之处希望大家在评论区指出共同探讨。
参考文献
ubuntu16.04交叉编译opencv 移植到rk1808上
Ubuntu16.04交叉编译OpenCV并移植
Ubuntu上交叉编译opencv及opencv_contrib并移植到ARM板之一
交叉编译opencv时候ffmpeg选项始终为no的解决方法
虚拟机交叉编译openCV详细步骤及bug解决详解