Android-NDK-clang 编译 FFmpeg

本文介绍了如何使用Android NDK中的clang工具链编译FFmpeg源码,创建适用于Android平台的libffmpeg.so库。内容涵盖NDK目录结构、编译脚本编写、编译选项详解,以及解决编译过程中的问题,如动态链接器设置和多平台库打包。提供了编译全平台库的脚本和实用建议。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前期准备

  1. 下载 Android-NDK
  2. 下载 FFmpeg 源码 注意:笔者用的是 NDK-21 和 ffmpeg-4.4 进行编译,如果版本不同可能会有所不同。
    测试:mac 与 ubuntu 下的NDK20 - NDK22 和 ffmpeg 4.0 - ffmpeg 4.4,均可使用。


本文你可以了解到

  • NDK20 - NDK22 提供的交叉编译工具链主要目录
  • 使用 clang 交叉编译出 Android 平台可以使用的 libffmpeg.so 库
  • 部分编译细节

一、NDK 提供的交叉编译工具链主要目录与文件

从 NDK20 - NDK22 编译工具链目录结构基本没变,这里以 NDK21 作为演示( NDK 在 windows、linux、mac 中的目录基本一样)

如上图,主要用的就是这几个目录,其中编译 FFmpeg 需要用到的 gcc 库就在 aarch64、arm、x86_64、x86 这几个文件夹中,这里先介绍一下这几个名字在 Android 中的不同平台库的联系。

aarch64:带这个前缀的目录都是与 arm64-v8a 库相关
arm:带这个前缀的目录都是与 armeabi-v7a 库相关
x86_64:带这个前缀的目录都是与 x86_64 库相关
x86:带这个前缀的目录都是与 x86 库相关

1.clang 编译工具

进入目录 llvm->prebuilt->darwin-x86_64->bin 里面都是与交叉编译相关的文件,我们以 clang 进行编译,所以主要关注的是以 clang、clang++ 结尾的文件,clang 用于编译 c 文件clang++ 用于编译 c++ 文件。
 

  • 这里需要注意的是:21 和 i686
  • 21:表示编译出的库支持的最低 Android 版本
  • i686:表示编译出 x86 库平台的编译工具

上面的 NDK 目录名在各系统上的对应形式:
mac:darwin-x86_64
linux:linux-x86_64
windows:windows-x86_64
注意:下面都以 mac 系统下的 NDK 目录进行介绍

2.编译环境,需要用到的库
 

库和头文件所在的目录在 darwin-x86_64 下的 sysroot 目录,其中头文件在 include 目录,库在 lib 目录,了解完这些,就可以开始编译了。

二、使用 clang<

PKG_CONFIG_PATH="/home/chang/dev/mpp/mpp_build/install/usr/local/lib/pkgconfig" ./configure --target-os=android --arch=aarch64 --prefix=/home/chang/dev/ffmpeg-rockchip/rk3576 --enable-cross-compile --cross-prefix=$TOOLCHAIN/bin/llvm- --sysroot=/opt/android-ndk-r26b/toolchains/llvm/prebuilt/linux-x86_64/sysroot --cc=$TOOLCHAIN/bin/${TARGET}-clang --cxx=$TOOLCHAIN/bin/${TARGET}-clang++ --enable-rkmpp --enable-libdrm --enable-shared --enable-version3 --disable-static --disable-doc --disable-programs --pkg-config=/home/chang/dev/mpp/mpp_build/install/usr/local/lib/pkgconfig ERROR: libdrm not found using pkg-config 出现这个问题为什么?这是日志/opt/android-ndk-r26b/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android34-clang --sysroot=/opt/android-ndk-r26b/toolchains/llvm/prebuilt/linux-x86_64/sysroot -D_ISOC99_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -Dstrtod=avpriv_strtod -DPIC -std=c11 -fPIE -fomit-frame-pointer -fPIC -pthread -c -o /tmp/ffconf.MDjIb8zP/test.o /tmp/ffconf.MDjIb8zP/test.c /tmp/ffconf.MDjIb8zP/test.c:3:24: warning: cast to smaller integer type 'int' from 'float (*)(float, float)' [-Wpointer-to-int-cast] int main(void){ return (int) foo; } ^~~~~~~~~ 1 warning generated. /opt/android-ndk-r26b/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android34-clang --sysroot=/opt/android-ndk-r26b/toolchains/llvm/prebuilt/linux-x86_64/sysroot -Wl,--as-needed -Wl,-z,noexecstack -fPIE -pie -o /tmp/ffconf.MDjIb8zP/test /tmp/ffconf.MDjIb8zP/test.o -lm require_pkg_config libdrm libdrm xf86drm.h drmGetVersion check_pkg_config libdrm libdrm xf86drm.h drmGetVersion test_pkg_config libdrm libdrm xf86drm.h drmGetVersion false --exists --print-errors libdrm ERROR: libdrm not found using pkg-config
03-25
<think>好的,我现在需要帮助用户解决他们在编译FFmpeg时遇到的libdrm未找到的问题。首先,用户提供的错误信息显示,在配置过程中,pkg-config无法找到libdrm库,导致编译失败。我需要分析可能的原因,并给出解决方案。 用户提供的配置命令中,PKG_CONFIG_PATH指向了/home/chang/dev/mpp/mpp_build/install/usr/local/lib/pkgconfig,这可能包含了Rockchip MPP库的pkg-config文件,但libdrm可能并未安装在该路径下。因此,首先需要确认libdrm是否已经正确安装,并且其pkg-config文件(如libdrm.pc)是否存在于PKG_CONFIG_PATH指定的目录中。 接下来,用户是在为Android交叉编译FFmpeg,使用了Android NDK工具链。这种情况下,libdrm可能需要针对Android平台进行交叉编译,而用户可能没有正确安装或配置适用于Android的libdrm库。通常,系统上安装的libdrm可能是为桌面环境编译的,无法在交叉编译Android时使用,因此用户可能需要自行编译适用于Android的libdrm,并确保其pkg-config路径被正确设置。 此外,用户可能在配置时指定了--enable-libdrm,但libdrm的pkg-config文件未被正确找到。需要检查libdrm的安装路径,确认是否存在对应的.pc文件,并确保PKG_CONFIG_PATH包含了该路径。如果用户没有为Android编译libdrm,可能需要下载libdrm源码,使用NDK工具链进行交叉编译,安装到指定目录,然后将该目录添加到PKG_CONFIG_PATH中。 另一个可能的问题是,即使libdrm已安装,但版本不兼容或pkg-config配置有误。需要验证libdrm的版本是否符合FFmpeg的要求,并检查.pc文件的内容是否正确,特别是前缀、库目录和包含目录是否指向正确的交叉编译路径。 总结可能的解决步骤:1. 确认libdrm是否已正确安装并适用于Android平台;2. 检查PKG_CONFIG_PATH是否包含libdrm的.pc文件路径;3. 必要时重新编译libdrm并正确配置环境变量。</think>这个错误的核心原因是**交叉编译环境未找到适用于Android平台的libdrm开发库**。以下是逐步分析及解决方案: --- ### **问题根源分析** 1. **`PKG_CONFIG_PATH`路径覆盖问题** 你在命令中设置了`PKG_CONFIG_PATH="/home/chang/dev/mpp/mpp_build/install/usr/local/lib/pkgconfig"`,该路径仅包含Rockchip MPP库的配置,但**未包含Android平台的libdrm库的.pc文件**。 ⇒ **pkg-config无法找到Android版libdrm的元数据**。 2. **Android交叉编译的特殊性** 系统默认安装的libdrm(如`/usr/lib/pkgconfig/libdrm.pc`)是为x86/arm64桌面环境编译的,而**Android NDK需要的是针对Android架构(aarch64)的libdrm库**。 ⇒ **直接使用系统libdrm会导致ABI不兼容**。 3. **缺失Android版libdrm开发包** FFmpeg的`--enable-libdrm`选项要求存在Android可用的libdrm头文件和库文件,但你的编译环境中**未正确安装或配置这些文件**。 --- ### **解决方案** #### **步骤1:为Android交叉编译libdrm库** 1. **下载libdrm源码** ```bash git clone https://gitlab.freedesktop.org/mesa/drm.git cd drm ``` 2. **配置Android交叉编译参数** 替换`TOOLCHAIN`和`SYSROOT`为你的NDK路径(根据用户原命令中的路径): ```bash meson setup build-android/ \ --cross-file android-cross.txt \ # 需手动创建交叉编译文件 -Dprefix=/path/to/android-libdrm/install # 指定安装路径 ``` **创建`android-cross.txt`交叉编译配置**: ```ini [binaries] c = '/opt/android-ndk-r26b/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android34-clang' cpp = '/opt/android-ndk-r26b/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android34-clang++' ar = 'aarch64-linux-android-ar' strip = 'aarch64-linux-android-strip' [properties] sys_root = '/opt/android-ndk-r26b/toolchains/llvm/prebuilt/linux-x86_64/sysroot' pkg_config_libdir = '/path/to/android-libdrm/install/lib/pkgconfig' [host_machine] system = 'android' cpu_family = 'aarch64' cpu = 'armv8' endian = 'little' ``` 3. **编译并安装libdrm** ```bash meson compile -C build-android/ meson install -C build-android/ ``` --- #### **步骤2:更新FFmpeg编译配置** 1. **扩展`PKG_CONFIG_PATH`** 在原有路径基础上,添加Android版libdrm的pkgconfig目录: ```bash export PKG_CONFIG_PATH="/home/chang/dev/mpp/mpp_build/install/usr/local/lib/pkgconfig:/path/to/android-libdrm/install/lib/pkgconfig" ``` 2. **验证libdrm是否可被检测** 手动运行pkg-config检查: ```bash pkg-config --exists --print-errors libdrm ``` ⇒ 若无错误输出,则配置成功。 3. **重新执行FFmpeg配置命令** 保持原有参数不变,确保`PKG_CONFIG_PATH`包含libdrm路径。 --- ### **关键验证点** - **检查libdrm.pc文件存在性** 确认`/path/to/android-libdrm/install/lib/pkgconfig/libdrm.pc`存在且内容正确,例如: ```ini prefix=/path/to/android-libdrm/install libdir=${prefix}/lib includedir=${prefix}/include Name: libdrm Description: Userspace interface to kernel DRM services Version: 2.4.115 Libs: -L${libdir} -ldrm Cflags: -I${includedir} -I${includedir}/libdrm ``` - **确保NDK版本兼容性** 使用Android NDK r26b时,需确认libdrm的编译选项与API Level 34(Android 14)兼容。 --- ### **附加建议** - **静态链接libdrm(可选)** 若动态链接仍有问题,可尝试将libdrm静态编译FFmpeg中: ```bash --extra-cflags="-I/path/to/android-libdrm/install/include" \ --extra-ldflags="-L/path/to/android-libdrm/install/lib -ldrm" ``` - **检查NDK sysroot路径** 确保`--sysroot`参数指向的路径包含Android的头文件和库(如`<drm.h>`应在`sysroot/usr/include/libdrm/`下)。 通过以上步骤,应能解决`ERROR: libdrm not found using pkg-config`问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值