Linux aarch64-linux-gnu-交叉编译x264、ffmpeg、opencv并移植
前沿:
1. 在一台ubuntu20.4系统上已经安装aarch64-linux-gnu交叉编译器。
2. 所有库编译引用路径应放置在移植不受影响的路径下,例如/opt/
路径下,任意linux平台均可存在或直接创建即可,或将x264
和ffmpeg
放入opencv
编译的指定路径下,本次编译移植过程全部放在/opt/
路径下。
3. 此次交叉编译平台的内核版本为Linux ubuntu 5.15.0-105-generic
,所以在移植到arm64
平台的内核版本应大于等于Linux ubuntu 5.15.0-105-generic
(不同的内核版本适配不同的 gcc/g++、cmake 版本)。
安装依赖
sudo apt --fix-broken install
# 安装gcc和g++
sudo apt-get install gcc-aarch64-linux-gnu
sudo apt-get install g++-aarch64-linux-gnu
1. x264
- 源码下载:x264
- 放置在
/opt/
路径下解压之后,执行命令安装编译,将编译的库放置在./x264/tmp
路径下:
cd ./x264/
./configure --host=aarch64-linux-gnu --prefix=$PWD/tmp --enable-shared --disable-asm
vi config.mak # 修改内容以支持交叉编译
CC=aarch64-linux-gnu-gcc
LD=aarch64-linux-gnu-gcc -o
AR=aarch64-linux-gnu-gcc-ar rc
RANLIB=aarch64-linux-gnu-gcc-ranlib
STRIP=aarch64-linux-gnu-strip
make && make install # 生成了bin/include/lib三个文件夹及其内容
2. ffmpeg
-
源码下载:ffmpeg-4.1.3
-
放置在
/opt/
路径下解压之后,执行命令安装编译,将编译的库放置在./ffmpeg-4.1.3/tmp
路径下:
cd ./ffmpeg-4.1.3/
./configure --enable-cross-compile --cross-prefix=aarch64-linux-gnu- \
--arch=arm64 --target-os=linux --cc=aarch64-linux-gnu-gcc --prefix=$PWD/tmp \
--enable-shared --enable-pic --disable-static --enable-gpl --enable-nonfree \
--enable-pthreads --enable-ffmpeg --disable-ffplay --enable-swscale \
--disable-armv5te --disable-armv6 --disable-armv6t2 --disable-stripping \
--enable-libx264 --extra-cflags=-I$PWD/../x264/tmp/include \
--extra-ldflags=-L$PWD/../x264/tmp/lib
make && make install
ls -l tmp/ # 生成了bin/include/lib/share四个文件夹及其内容
- 在编译好的ffmpeg库文件夹中创建ffmpeg-config.cmake文件内容为:(根据自己的库版本编写)
set(FFMPEG_PATH "${CMAKE_CURRENT_LIST_DIR}")
set(FFMPEG_EXEC_DIR "${FFMPEG_PATH}/bin")
set(FFMPEG_LIBDIR "${FFMPEG_PATH}/lib")
set(FFMPEG_INCLUDE_DIRS "${FFMPEG_PATH}/include")
set(FFMPEG_LIBRARIES
${FFMPEG_LIBDIR}/libavformat.so
${FFMPEG_LIBDIR}/libavdevice.so
${FFMPEG_LIBDIR}/libavcodec.so
${FFMPEG_LIBDIR}/libavutil.so
${FFMPEG_LIBDIR}/libswscale.so
${FFMPEG_LIBDIR}/libswresample.so
${FFMPEG_LIBDIR}/libavfilter.so
${FFMPEG_LIBDIR}/libpostproc.so
/opt/x264/tmp/lib/libx264.so
)
set(FFMPEG_libavformat_FOUND TRUE)
set(FFMPEG_libavdevice_FOUND TRUE)
set(FFMPEG_libavcodec_FOUND TRUE)
set(FFMPEG_libavutil_FOUND TRUE)
set(FFMPEG_libswscale_FOUND TRUE)
set(FFMPEG_libswresample_FOUND TRUE)
set(FFMPEG_libavfilter_FOUND TRUE)
set(FFMPEG_libpostproc_FOUND TRUE)
set(FFMPEG_libavcodec_VERSION 58.35.100)
set(FFMPEG_libavdevice_VERSION 58.5.100)
set(FFMPEG_libavfilter_VERSION 7.40.101)
set(FFMPEG_libavformat_VERSION 58.20.100)
set(FFMPEG_libavutil_VERSION 56.22.100)
set(FFMPEG_libpostproc_VERSION 55.3.100)
set(FFMPEG_libswresample_VERSION 3.3.100)
set(FFMPEG_libswscale_VERSION 5.3.100)
set(FFMPEG_FOUND TRUE)
set(FFMPEG_LIBS ${FFMPEG_LIBRARIES})
3. opencv-4.5.5
- opencv的交叉编译工具链在…/opencv-4.5.5/platforms/linux路径下,linux文件夹下是一些.cmake文件,对应不同的移植对象,所以选择aarch64-gnu.toolchain.cmake工具链,在进行编译前,需要修改cmake文件,修改platform/linux/aarch64-gnu.toolchain.cmake,改为如下:
set(CMAKE_SYSTEM_PROCESSOR aarch64)
set(GCC_COMPILER_VERSION "" CACHE STRING "GCC Compiler version")
set(CMAKE_C_COMPILER /usr/bin/aarch64-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER /usr/bin/aarch64-linux-gnu-g++)
set(GNU_MACHINE "aarch64-linux-gnu" CACHE STRING "GNU compiler triple")
include("${CMAKE_CURRENT_LIST_DIR}/arm.toolchain.cmake")
- 将编译的库放入
../opencv_arm64
路径下,且编译为集成库libopencv_world.a
文件
cd ./opencv-4.5.5/
sudo cmake -D CMAKE_INSTALL_PREFIX=../opencv_arm64 -D CMAKE_TOOLCHAIN_FILE=../platforms/linux/aarch64-gnu.toolchain.cmake -D CMAKE_BUILD_TYPE=Release -D WITH_FFMPEG=ON -D FFMPEG_DIR=/opt/ffmpeg-4.1.3/tmp -D WITH_1394=OFF -D WITH_GTK=OFF -D BUILD_opencv_world=ON -D OPENCV_DOWNLOAD_MIRROR_ID=gitcode -D OPENCV_ENABLE_NONFREE=ON -D BUILD_TIFF=ON -D OPENCV_GENERATE_PKGCONFIG=ON ..
sudo make -j8
sudo make install
- 编译结束后进入 opencv_arm64 文件夹,里面生成bin,include,lib,share四个文件夹。
因为移植到ARM64平台上调用opencv库时会调用在编译opencv时链接的x264、ffmpeg库路径,所以在配置编译时和最终引用时候保持路径一致,例如我这里在交叉编译opencv时候引用x264放在/opt/x264/tmp/lib/libx264.so下,引用ffmpeg放在/opt/ffmpeg-4.1.3/tmp下,所以在交叉编译后需要将x264和ffmpeg也放在ARM64平台相同的路径下,这里推荐将x264和ffmpeg放在opencv源码文件夹下,防止移植后路径不匹配。
4. 移植
将以上步骤安装编译的 x264 和 ffmpeg-4.1.3 和 opencv-4.5.5 目录下 opencv_arm64 文件夹成压缩文件x264.tar.gz、ffmpeg-4.1.3.tar.gz、 opencv_arm64.tar.gz,
然后移植到
ARM64
平台/opt/
路径下,再依次解压
x264
、ffmpeg
,将opencv
解压的opencv_arm64
放在/usr/lib/
路径下并改名为opencv
。
ARM64
平台和x86
交叉编译平台都需要配置引用库的环境变量,两个平台均进入root
用户 添加环境变量,在最后一行加入:
vi ~/.bashrc
export PKG_CONFIG_PATH=/usr/lib/opencv/lib/pkgconfig:$PKG_CONFIG_PATH
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/opencv/lib
export PKG_CONFIG_PATH=/home/fmsh/ffmpeg-4.1.3/tmp/lib/pkgconfig:$PKG_CONFIG_PATH
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/ffmpeg-4.1.3/tmp/lib
export PKG_CONFIG_PATH=/home/fmsh/x264/tmp/lib/pkgconfig/:$PKG_CONFIG_PATH
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/x264/tmp/lib
- 使能环境变量
source ~/.bashrc
- 在源码文件
CMakeLists.txt
中加入链接库
set(x264_libs_DIR /opt/x264/tmp/lib)
set(x264_headers_DIR /opt/x264/tmp/include)
add_library(x264 SHARED IMPORTED )
#指定所添加依赖库的导入路径
set_target_properties(x264 PROPERTIES IMPORTED_LOCATION ${x264_libs_DIR}/libx264.so )
set(ffmpeg_libs_DIR /opt/ffmpeg-4.1.3/tmp/lib)
set(ffmpeg_headers_DIR /opt/ffmpeg-4.1.3/tmp/include)
#对于find_package找不到的外部依赖库,可以用add_library添加
# SHARED表示添加的是动态库
# IMPORTED表示是引入已经存在的动态库
add_library( avcodec SHARED IMPORTED )
#指定所添加依赖库的导入路径
set_target_properties( avcodec PROPERTIES IMPORTED_LOCATION ${ffmpeg_libs_DIR}/libavcodec.so )
add_library( avfilter SHARED IMPORTED )
set_target_properties( avfilter PROPERTIES IMPORTED_LOCATION ${ffmpeg_libs_DIR}/libavfilter.so )
add_library( swresample SHARED IMPORTED )
set_target_properties( swresample PROPERTIES IMPORTED_LOCATION ${ffmpeg_libs_DIR}/libswresample.so )
add_library( swscale SHARED IMPORTED )
set_target_properties( swscale PROPERTIES IMPORTED_LOCATION ${ffmpeg_libs_DIR}/libswscale.so )
add_library( avformat SHARED IMPORTED )
set_target_properties( avformat PROPERTIES IMPORTED_LOCATION ${ffmpeg_libs_DIR}/libavformat.so )
add_library( avutil SHARED IMPORTED )
set_target_properties( avutil PROPERTIES IMPORTED_LOCATION ${ffmpeg_libs_DIR}/libavutil.so )
SET(OpenCV_DIR /usr/lib/opencv/lib/cmake/opencv4)
find_package(OpenCV REQUIRED)
include_directories(
${x264_headers_DIR}
${ffmpeg_headers_DIR}
)
target_link_libraries(
x264
opencv_world
avformat avfilter avcodec avutil swresample swscale
)
以上,将 x264、ffmpeg、opencv 成功移植到ARM64
平台上,可进行调用ffmpeg
编解码图像数据和调用opencv
进行打开或保存视频文件。