使用Android NDK r17构建C库(FFmpeg):未定义引用'__mulodi4'

时间:2018-05-11 18:24:42

标签: ffmpeg android-ndk clang sanitizer libgcc

我的问题恰好与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用户非常适合发布解决方法here。但是,我确定在哪里可以找到这个libclang_rt.builtins-i686.a库。以下是我在独立工具链目录中找到的内容:

  

./ lib64下/铛/ 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 build config命令:

./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拉入我的测试项目(一个简单的AAR w / 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文件的那一部分是正确的,但它无法找到任何这些作为参考。

这似乎是人们遇到的一个常见问题,但我看不到找到一个对我有用的解决方法。

1 个答案:

答案 0 :(得分:0)

简答:更新NDK r17。

这是在少数NDK错误中引用的:

基本上Clang正在生成libgcc没有实现的调用。我说而不是,因为对于这个特定的功能,NDK r17似乎不再是这种情况。

如果您仍在使用此功能而且我无法使用任何早期测试用例,您可以尝试使用-lcompiler_rt-extras进行关联。这包含在NDK r17中,并且缺少功能。