新建cross-compile文件夹
sudo mkdir /home/pc/cross-compile
sudo chmod -R 777 /home/pc/cross-compile
cd /home/pc/cross-compile
安装编译需要用到的常用工具
sudo apt-get update && apt-get install -y make pkg-config wget
下载ndk并配置环境变量
sudo wget -O android-ndk-r26b-linux.zip --no-check-certificate https://dl.google.com/android/repository/android-ndk-r26b-linux.zip?hl=zh-cn
# 解压
unzip android-ndk-r26b-linux.zip
sudo rm -rf android-ndk-r26b-linux.zip
# 配置ndk环境变量
export ANDROID_NDK=/home/pc/cross-compile/android-ndk-r26b
export NDK_PATH=$ANDROID_NDK/toolchains/llvm/prebuilt/linux-x86_64
export PATH=$PATH:$NDK_PATH
source ~/.bashrc
# 删除环境变量
#unset NDK_PATH
#source ~/.bashrc
查看ndk
ls /home/pc/cross-compile/android-ndk-r26b/toolchains/llvm/prebuilt/linux-x86_64/bin
# 结果:
aarch64-linux-android21-clang i686-linux-android29-clang++
aarch64-linux-android21-clang++ i686-linux-android30-clang
aarch64-linux-android22-clang i686-linux-android30-clang++
aarch64-linux-android22-clang++ i686-linux-android31-clang
aarch64-linux-android23-clang i686-linux-android31-clang++
aarch64-linux-android23-clang++ i686-linux-android32-clang
aarch64-linux-android24-clang i686-linux-android32-clang++
aarch64-linux-android24-clang++ i686-linux-android33-clang
aarch64-linux-android25-clang i686-linux-android33-clang++
aarch64-linux-android25-clang++ i686-linux-android34-clang
aarch64-linux-android26-clang i686-linux-android34-clang++
aarch64-linux-android26-clang++ ld
aarch64-linux-android27-clang ld64.lld
aarch64-linux-android27-clang++ ld.lld
aarch64-linux-android28-clang lld
aarch64-linux-android28-clang++ lldb
aarch64-linux-android29-clang lldb-argdumper
aarch64-linux-android29-clang++ lldb.sh
aarch64-linux-android30-clang lld-link
aarch64-linux-android30-clang++ llvm-addr2line
aarch64-linux-android31-clang llvm-ar
aarch64-linux-android31-clang++ llvm-as
aarch64-linux-android32-clang llvm-bolt
aarch64-linux-android32-clang++ llvm-cfi-verify
aarch64-linux-android33-clang llvm-config
aarch64-linux-android33-clang++ llvm-cov
aarch64-linux-android34-clang llvm-cxxfilt
aarch64-linux-android34-clang++ llvm-dis
armv7a-linux-androideabi21-clang llvm-dwarfdump
armv7a-linux-androideabi21-clang++ llvm-dwp
armv7a-linux-androideabi22-clang llvm-ifs
armv7a-linux-androideabi22-clang++ llvm-lib
armv7a-linux-androideabi23-clang llvm-link
armv7a-linux-androideabi23-clang++ llvm-lipo
armv7a-linux-androideabi24-clang llvm-ml
armv7a-linux-androideabi24-clang++ llvm-modextract
armv7a-linux-androideabi25-clang llvm-nm
armv7a-linux-androideabi25-clang++ llvm-objcopy
armv7a-linux-androideabi26-clang llvm-objdump
armv7a-linux-androideabi26-clang++ llvm-profdata
armv7a-linux-androideabi27-clang llvm-ranlib
armv7a-linux-androideabi27-clang++ llvm-rc
armv7a-linux-androideabi28-clang llvm-readelf
armv7a-linux-androideabi28-clang++ llvm-readobj
armv7a-linux-androideabi29-clang llvm-size
armv7a-linux-androideabi29-clang++ llvm-strings
armv7a-linux-androideabi30-clang llvm-strip
armv7a-linux-androideabi30-clang++ llvm-symbolizer
armv7a-linux-androideabi31-clang llvm-windres
armv7a-linux-androideabi31-clang++ merge-fdata
armv7a-linux-androideabi32-clang remote_toolchain_inputs
armv7a-linux-androideabi32-clang++ sancov
armv7a-linux-androideabi33-clang sanstats
armv7a-linux-androideabi33-clang++ scan-build
armv7a-linux-androideabi34-clang scan-view
armv7a-linux-androideabi34-clang++ x86_64-linux-android21-clang
bisect_driver.py x86_64-linux-android21-clang++
clang x86_64-linux-android22-clang
clang++ x86_64-linux-android22-clang++
clang-17 x86_64-linux-android23-clang
clang-check x86_64-linux-android23-clang++
clangd x86_64-linux-android24-clang
clang-format x86_64-linux-android24-clang++
clang-tidy x86_64-linux-android25-clang
clang-tidy.sh x86_64-linux-android25-clang++
dsymutil x86_64-linux-android26-clang
git-clang-format x86_64-linux-android26-clang++
i686-linux-android21-clang x86_64-linux-android27-clang
i686-linux-android21-clang++ x86_64-linux-android27-clang++
i686-linux-android22-clang x86_64-linux-android28-clang
i686-linux-android22-clang++ x86_64-linux-android28-clang++
i686-linux-android23-clang x86_64-linux-android29-clang
i686-linux-android23-clang++ x86_64-linux-android29-clang++
i686-linux-android24-clang x86_64-linux-android30-clang
i686-linux-android24-clang++ x86_64-linux-android30-clang++
i686-linux-android25-clang x86_64-linux-android31-clang
i686-linux-android25-clang++ x86_64-linux-android31-clang++
i686-linux-android26-clang x86_64-linux-android32-clang
i686-linux-android26-clang++ x86_64-linux-android32-clang++
i686-linux-android27-clang x86_64-linux-android33-clang
i686-linux-android27-clang++ x86_64-linux-android33-clang++
i686-linux-android28-clang x86_64-linux-android34-clang
i686-linux-android28-clang++ x86_64-linux-android34-clang++
i686-linux-android29-clang yasm
下载ffmpeg并解压
sudo wget --no-check-certificate http://ffmpeg.org/releases/ffmpeg-6.1.tar.gz
tar -zxvf ffmpeg-6.1.tar.gz
sudo rm -rf ffmpeg-6.1.tar.gz
编译ffmpeg
cd ffmpeg-6.1
./configure \
--prefix=/home/pc/cross-compile/output/ffmpeg/armv7a-linux-androideabi21 \
--enable-neon \
--enable-hwaccels \
--enable-gpl \
--disable-postproc \
--disable-debug \
--enable-small \
--enable-jni \
--enable-mediacodec \
--enable-decoder=h264_mediacodec \
--enable-static \
--enable-shared \
--disable-doc \
--enable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-avdevice \
--disable-doc \
--disable-symver \
--cross-prefix=$NDK_PATH/bin/arm-linux-androideabi- \
--target-os=android \
--arch=arm \
--cpu=armv7-a \
--cc=$NDK_PATH/bin/armv7a-linux-androideabi21-clang \
--cxx=$NDK_PATH/bin/armv7a-linux-androideabi21-clang++ \
--nm=$NDK_PATH/bin/llvm-nm \
--ar=$NDK_PATH/bin/llvm-ar \
--ranlib=$NDK_PATH/bin/llvm-ranlib \
--strip=$NDK_PATH/bin/llvm-strip \
--pkg-config=/usr/bin/pkg-config \
--enable-cross-compile \
--sysroot=$NDK_PATH/sysroot \
--extra-cflags="-Os -fpic -mfloat-abi=softfp -mfpu=vfp -marm -march=armv7-a " \
--extra-ldflags="$ADDI_LDFLAGS"
生成lib库
make clean
make -j16
make install
编译生成arm64-v8a库
# 我们上面的步骤已经编译生成了armv7-a库,生成arm64-v8a库的步骤类似,只需改几个地方就行了,下面是完整内容:
./configure \
--prefix=/home/pc/cross-compile/output/ffmpeg/aarch64-linux-android21 \
--enable-neon \
--enable-hwaccels \
--enable-gpl \
--disable-postproc \
--disable-debug \
--enable-small \
--enable-jni \
--enable-mediacodec \
--enable-decoder=h264_mediacodec \
--enable-static \
--enable-shared \
--disable-doc \
--enable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-avdevice \
--disable-doc \
--disable-symver \
--cross-prefix=$NDK_PATH/bin/aarch64-linux-android- \
--target-os=android \
--arch=arm64 \
--cpu=armv8-a \
--cc=$NDK_PATH/bin/aarch64-linux-android21-clang \
--cxx=$NDK_PATH/bin/aarch64-linux-android21-clang++ \
--nm=$NDK_PATH/bin/llvm-nm \
--ar=$NDK_PATH/bin/llvm-ar \
--ranlib=$NDK_PATH/bin/llvm-ranlib \
--strip=$NDK_PATH/bin/llvm-strip \
--pkg-config=/usr/bin/pkg-config \
--enable-cross-compile \
--sysroot=$NDK_PATH/sysroot \
--extra-cflags="-march=armv8-a" \
--extra-ldflags="$ADDI_LDFLAGS"
注意事项
这里面最核心的就是编译这步,由于网上资料不全,在这里卡了好久,各种报错。
最核心的几个参数:
--cross-prefix=
--cc=
--cxx=
--nm=
--ar=
--ranlib=
--strip=
--pkg-config=
少了上面那几个参数,编译都编译不过去,
--cross-prefix用于指明交叉编译工具前缀,如v7下是:arm-linux-androideabi- ,而v8下是:aarch64-linux-android- ,这个可以通过查找ndk找到。
--cc用于配置 C 编译器,在这里我们是clang,
--cxx用于配置c++编译器,在这里我们是clang++。
--nm、--ar、--ranlib、--strip这几个选项由于ndk-r26中已经被替换成:llvm-nm、llvm-ar、llvm-ranlib、llvm-strip,所以我们编译时也要把这几个参数替换掉。
--pkg-config用于检查和获取库和头文件信息的工具,我们需要显示指明他的安装路径,不然编译或者make会报错,我们可以通过 “which pkg-config” 命令查找到路径,如果没安装的话,我们可以先通过 “apt-get update && apt-get install -y pkg-config” 安装。
然后是与我们最终生成lib库相关的几个重要参数:
--prefix= :用于指明我们最终生成文件的保存路径,注意需要提前创建目标文件夹并赋予写的权限。
--arch= :如果我们需要生成的是32位,填arm,若是64位,则填arm64。
--cpu= :如果我们需要生成的是32位,填armv7-a,若是64位,则填armv8-a。
--cc= :如果我们需要生成的是32位,填armv7a-linux-androideabi21-clang,若是64位,则填aarch64-linux-android21-clang。android21代表最低支持android21版本,我们还可以根据需求用aarch64-linux-android34-clang。
--cxx= :与--cc类似,不过他用的是clang++,比如:armv7a-linux-androideabi21-clang++
--extra-cflags= :配置编译的架构信息,如果我们需要生成的是32位,填"-Os -fpic -mfloat-abi=softfp -mfpu=vfp -marm -march=armv7-a ",若是64位,则填"-march=armv8-a"。
然后其他参数是配置ffmpeg启用/禁用什么东西,比如:
--enable-shared :代表生成动态库
--enable-static :代表生成静态库
编译生成后的ffmpeg目录结构
对我们最重要的是include和lib。include用于存放头文件,lib用于存放静态库.a,或动态库.so。
FFmpeg 有六个常用的功能模块:
libavformat:多媒体文件或协议的封装和解封装库;
libavcodec:音视频编解码库;
libavfilter:音视频、字幕滤镜库;
libswscale:图像格式转换库;
libswresample:音频重采样库;
libavutil:工具库。
参考:https://mp.weixin.qq.com/s?__biz=MzIwNTIwMzAzNg==&mid=2654162543&idx=1&sn=894a6bfb0f8f652ef53860075af1754b&chksm=8cf39d5cbb84144a9d62fa80cbeed1843aadfe97bf8a30ab02474f98ec86be649d65e301674b&scene=21#wechat_redirect ,非常感谢。