ffmpeg - 使用 Android NDK r17 构建 C 库 (FFmpeg):未定义对“__mulodi4”的引用
问题描述
我的问题恰好出在 FFmpeg 上,但我怀疑几乎所有 C 库都会发生这种情况。
问题描述
我的应用程序使用使用 NDK r10e 编译的 FFmpeg。我正在尝试将所有内容更新到 NDK r17,同时也切换到 clang,因为 Google 更喜欢我们使用它而不是 gcc。
我的第一步是构建 FFmpeg。
为此,我使用该make_standalone_toolchain.py
脚本为 x86 架构创建了一个独立的工具链,如下所示:
make_standalone_toolchain.py --arch x86 --api 21 --install-dir ~/Development/ndk-toolchains/x86
然后我配置FFmpeg构建如下:
TOOLCHAIN_DIR=~/Development/ndk-toolchains/x86
./configure \
--prefix=$(pwd)/android/x86 \
--cross-prefix=$TOOLCHAIN_DIR/bin/i686-linux-android- \
--target-os=android \
--arch=x86 \
--enable-cross-compile \
--disable-asm \
--toolchain=clang-usan \
--disable-stripping \
--extra-cflags="-m32" \
--sysroot=$TOOLCHAIN_DIR/sysroot/
然后我按如下方式构建它:
make clean
make -j4
make install
一切似乎都编译得很好,但我得到了几个链接器错误,它们都说同样的话:
未定义对“__mulodi4”的引用
我尝试过的解决方案
1. 链接 libclang_rt.builtins*
我在网上发现了一些地方,这表明这是由于 libgcc 不提供__mulodi4
. 一个名为 sitsofe 的 github 用户非常好,可以在这里发布一个解决方法。但是,我确定在哪里可以找到这个libclang_rt.builtins-i686.a
库。这是我在独立工具链目录中找到的内容:
./lib64/clang/6.0.2/lib/linux/libclang_rt.builtins-x86_64.a ./lib64/clang/6.0.2/lib/linux/libclang_rt.builtins-i386.a ./lib64/clang/6.0. 2/lib/linux/libclang_rt.builtins-aarch64-android.a ./lib64/clang/6.0.2/lib/linux/libclang_rt.builtins-mips64-android.a ./lib64/clang/6.0.2/lib/ linux/libclang_rt.builtins-x86_64-android.a ./lib64/clang/6.0.2/lib/linux/libclang_rt.builtins-i686-android.a ./lib64/clang/6.0.2/lib/linux/libclang_rt。 builtins-arm-android.a ./lib64/clang/6.0.2/lib/linux/libclang_rt.builtins-mips-android.a
图书馆libclang_rt.builtins-i686-android.a
看起来很近,但(我认为)没有雪茄。当我尝试链接到它时,我得到了同样的错误:
未定义对“__mulodi4”的引用
这是我的新 FFmpeg 构建配置命令:
./configure \
--prefix=$(pwd)/android/x86 \
--cross-prefix=$TOOLCHAIN_DIR/bin/i686-linux-android- \
--target-os=android \
--arch=x86 \
--enable-cross-compile \
--disable-asm \
--toolchain=clang-usan \
--disable-stripping \
--extra-cflags="-m32" \
--extra-ldflags="-L${TOOLCHAIN_DIR}/lib64/clang/6.0.2/lib/linux/libclang_rt.builtins-i686-android.a" \
--sysroot=$TOOLCHAIN_DIR/sysroot/
我检查-v
以确保该行已添加到链接器标志中,并且确实如此。但是,我不知道这个库是否应该工作,更不用说我是否正确地将它添加到链接器标志中。无论如何,我在这里做的事情是行不通的。
2.切换到不同的消毒剂
我没有使用未定义的清理程序,而是尝试切换到地址清理程序。(坦率地说)这是一次彻头彻尾的暗中尝试,基于在本周 Google I/O 的 r17 中模糊地提到了 asan。
在这种情况下,FFmpeg 构建得很好!
但是,当我尝试将 FFmpeg 拉入我的测试项目(一个简单的带有 C++ 支持的 AAR,它只有一个调用 的 jni 方法时av_gettime()
,我得到了大量的链接器错误:
错误:错误:未定义引用“__asan_option_detect_stack_use_after_return”
错误:错误:未定义引用“__asan_stack_malloc_0”
错误:错误:未定义引用“__asan_report_load4”
错误:错误:未定义引用“__asan_report_load4”
错误:错误:未定义引用“__asan_shadow_memory_dynamic_address”
错误:错误:未定义引用“__asan_option_detect_stack_use_after_return”
错误:错误:未定义引用“__asan_stack_malloc_0”
错误:错误:未定义引用“__asan_report_load4”
错误:错误:未定义引用“__asan_report_load4”
错误:错误:未定义引用“__asan_shadow_memory_dynamic_address'
错误:错误:未定义引用“__asan_option_detect_stack_use_after_return”
错误:错误:未定义引用“__asan_stack_malloc_0”
错误:错误:未定义引用“__asan_report_store4”
错误:错误:未定义引用“__asan_report_store4”
错误:错误:未定义引用“__asan_init”
错误:错误:未定义对“__asan_version_mismatch_check_v9”的引用
所以似乎找到了FFmpeg库就好了,说明我的CMake文件的那部分是正确的,但是它找不到这些asan引用中的任何一个。
这似乎是人们遇到的一个常见问题,但我找不到真正适合我的解决方法。
解决方案
简短的回答:更新到 NDK r17。
这在少数 NDK 错误中提到:
- https://github.com/android-ndk/ndk/issues/184
- https://github.com/android-ndk/ndk/issues/294(根本原因,不一样的症状)
- https://github.com/android-ndk/ndk/issues/506
本质上,Clang 正在生成 libgcc 未实现的调用。我说是而不是因为对于这个特定功能的 NDK r17 似乎不再是这种情况。
如果您仍然遇到此问题并且我无法使用任何早期的测试用例,您可以尝试使用-lcompiler_rt-extras
. 这包含在 NDK r17 中,并且具有缺失的功能。
推荐阅读
- python - 错误:未找到密码学==3.2.1 的匹配分布
- angular - Nx e2e 文件夹结构
- python - 从 python 中的 webElement 中查找 xpath
- flutter - 错误状态:Stream 已被收听。(useStream 不会关闭流)
- node.js - 由第 3 方服务处理身份验证时的授权代码流
- c# - 如何在 .NET Framework 4.8 中使用 accessdatabaseengine_X64 运行 Microsoft Office 版本:18.2008.12711.0?
- reactjs - 在页面索引更改后获取数据
- spring-batch - Spring Batch ResourceAware - 在 ClassifierCompositeItemWriter 中获取资源名称
- atlassian-sourcetree - 由于身份验证失败错误,Sourcetree github 无法获取/拉取/推送
- java - 尝试从返回 null 的哈希映射值数组中创建哈希映射键数组