前言
在移动应用开发中,常常需要使用多媒体处理库和加密库。FFmpeg 是一个强大的多媒体处理框架,x264 用于视频编码,fdk-aac 提供高质量的 AAC 音频编码,openssl 提供加密功能,而 libmp3 可以处理 MP3 音频文件。在 macOS 下,通过 NDK(Native Development Kit)环境进行这些库的交叉编译,可以生成适用于 Android 平台的动态库(.so文件)。本文将详细介绍在 macOS 下进行这些库的编译过程。
一、前期准备
(一)明确编译目标
确定需要编译的库的版本和功能需求,以及生成的 .so 文件将用于哪些 Android 平台(如 armeabi-v7a、arm64-v8a 等)。
(二)安装必要软件和工具
- 安装 NDK:下载并安装适用于 macOS 的 Android NDK(Native Development Kit)。选择合适的 NDK 版本,以确保与目标 Android 设备的兼容性。可以从 Android 官方网站下载 NDK。
- NDK此次编译选择的是21.4.7075529,AndroidStudio的 的 SDK Manager下载的
- 安装 Homebrew:Homebrew 是 macOS 上的包管理工具,可以方便地安装各种软件和库。打开终端,输入以下命令安装 Homebrew:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
二、安装必需的库和依赖库
(一)安装依赖库
- 安装 yasm:FFmpeg 在编译过程中可能需要 yasm 来进行汇编优化。使用 Homebrew 安装 yasm:
brew install yasm
- 安装 nasm:某些版本的 FFmpeg 可能需要 nasm。同样使用 Homebrew 安装:
brew install nasm
三、源代码下载
X264
官网下载 www.videolan.org/developers/…
fdk-aac
www.linuxfromscratch.org/blfs/view/s…
ffmpeg4.2.1
libmp3lame
编译
交叉编译重要参数:
--prefix:安装的目录--cross-prefix:交叉编译的前缀路径,后面会拼接gcc、ld等--sysroot:编译过程会去这个目录下找依赖相关的类等--enable-pic:生成与路径无关静/动态库--extra-cflags:编译过程需要传递的参数,相关参数参考
编译x264
X264在NDK21使用clang编译(NDK在版本r17c之后使用clang编译)
1)x264默认使用gcc编译,我们需要修改修改x264库跟目录下的configure
a. 找到CC="${CC-${cross_prefix}gcc}" 这里的CC是我们需要添加到环境变量的clang编译器路径,我们直接在脚本里定义CC变量即可。 b. 把全局的${cross_prefix}gcc-改成${cross_prefix}-;也就是把拼接中的gcc去掉。
2)脚本文件:创建一个名为 build_x264.sh 的脚本文件
#!/bin/bash
# 定义变量
NDK=/Users/dabao/Library/Android/sdk/ndk/21.4.7075529
# 定义 NDK 的路径,这里存放了 Android 原生开发工具包。
SYSROOT=$NDK/toolchains/llvm/prebuilt/darwin-x86_64/sysroot
# 定义系统根目录,用于指定编译过程中使用的系统头文件和库文件的位置。
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/darwin-x86_64
# 定义工具链的路径,包含了编译 Android 应用所需的各种工具。
API=21
# 定义 Android API 级别。
build_x264() {
cd /Users/dabao/Desktop/build/ffmpeg/ffmpeg/ffmpeg_build/x264-master
# 切换到 x264 源代码目录。
local android_cpu="$1"
# 接收传入的参数,代表 Android CPU 架构名称。
local arch_prefix="$2"
# 接收传入的参数,代表架构前缀。
local optimize_cflags="$3"
# 接收传入的参数,代表优化编译标志。
local prefix_tag="$4"
# 接收传入的参数,代表前缀标签。
PREFIX=/Users/dabao/Desktop/build/ffmpeg/ffmpeg/ffmpeg_build/output/x264/$android_cpu
# 定义输出目录的路径,根据不同的 Android CPU 架构进行区分。
export CC=$TOOLCHAIN/bin/$arch_prefix$API-clang
# 设置 C 编译器环境变量,指定特定架构和 API 级别的 clang 编译器。
export CXX=$TOOLCHAIN/bin/$arch_prefix$API-clang++
# 设置 C++编译器环境变量,指定特定架构和 API 级别的 clang++编译器。
CROSS_PREFIX=$TOOLCHAIN/bin/$prefix_tag
# 定义交叉编译前缀,用于在编译过程中指定工具的路径。
EXTRA_CFLAGS="-D__ANDROID_API__=$API -isysroot $NDK/sysroot -I$NDK/sysroot/usr/include/$arch_prefix -Os -fPIC $optimize_cflags"
# 设置额外的编译标志,包括定义 Android API 级别、指定系统根目录、包含特定架构的头文件路径、进行优化以及启用位置无关代码。
if [ "$android_cpu" = "armv8-a" ]; then
HOST=aarch64-linux-android
else
HOST=arm-linux
fi
# 根据传入的 Android CPU 架构名称设置主机名称。如果是 "armv8-a",则设置为主机为 aarch64-linux-android,否则为 arm-linux。
./configure \
--prefix=${PREFIX} \
--cross-prefix=${CROSS_PREFIX} \
--sysroot=$SYSROOT \
--host=${HOST} \
--disable-asm \
--enable-shared \
--enable-static \
--disable-opencl \
--enable-pic \
--disable-cli \
--extra-cflags="$EXTRA_CFLAGS" || exit 0
# 运行 x264 的配置脚本,设置各种编译选项,包括输出目录、交叉编译前缀、系统根目录、主机名称、禁用汇编、启用共享库和静态库、禁用 OpenCL、启用位置无关代码以及设置额外的编译标志。如果配置失败,则退出脚本。
make clean
# 清理之前的编译结果。
make -j8
# 进行编译,使用 8 个并发任务加快编译速度。
make install V=1
# 安装编译结果,并输出详细的安装过程信息。
echo -e "building for android $android_cpu completed "
# 输出编译完成的提示信息
}
build_x264 "armeabi-v7a" "armv7a-linux-androideabi" "-march=armv7-a" "arm-linux-androideabi-"
# 调用 build_x264 函数,传入参数以编译 armeabi-v7a 架构的 x264。
build_x264 "armv8-a" "aarch64-linux-android" "-march=armv8-a" "aarch64-linux-android-"
# 调用 build_x264 函数,传入参数以编译 armv8-a 架构的 x264。
- 运行 chmod +x build_x264.sh 赋予脚本可执行权限。
- 运行 ./build_x264.sh 执行脚本进行编译。
编译 fdk-aac
重要参数跟x264的差不过的。
编译前的操作
将libfdkaac/libSBRdec/src/lpp_tran.cpp中的__ANDROID__改成__ANDROID_OFF__;也就是去掉log/log.h,因为ndk中没有这玩意。