使用 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.内置*

我在网上发现了一些地方,表明这是由于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 上模糊地提到 asan在 r17 中可用。

在这种情况下,FFmpeg 构建得很好!

但是,当我尝试将 FFmpeg 拉入我的测试项目(一个简单的 AAR C++支持,只有一个调用av_gettime()的 jni 方法时,我收到大量链接器错误:

错误:

错误:未定义对"__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 开始包含在内,并且缺少功能。

相关内容

  • 没有找到相关文章

最新更新