Сборка библиотеки C (FFmpeg) с Android NDK r17: неопределенная ссылка на __mulodi4

Моя проблема случается с FFmpeg, но я подозреваю, что это произойдет почти с любой библиотекой Си.

описание проблемы

Мое приложение использует FFmpeg, который скомпилирован с NDK r10e. Я пытаюсь обновить все до 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, Пользователь GitHub по имени sitofe был достаточно хорош, чтобы опубликовать здесь решение. Тем не менее, я уверен, где это найти 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 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. Переключение на другое дезинфицирующее средство

Вместо того, чтобы использовать неопределенное дезинфицирующее средство, я попытался переключиться на адресное дезинфицирующее средство. Это (откровенно) полный удар в темноте, основанный на смутном упоминании о том, что асан доступен в r17 на Google I/O на этой неделе.

В этом случае FFmpeg строит просто отлично!

Однако, когда я пытаюсь включить FFmpeg в свой тестовый проект (простая поддержка AAR с C++, у него просто есть один метод 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.

Кажется, это общая проблема, с которой сталкиваются люди, но я не могу найти обходной путь, который действительно работает для меня.

1 ответ

Краткий ответ: обновление до NDK r17.

Это упоминается в нескольких ошибках NDK:

По сути, Clang генерировал вызовы, которые libgcc не реализует. Я говорю, что было скорее, чем есть, потому что это больше не относится к NDK r17 для этой конкретной функции.

Если вы по-прежнему сталкиваетесь с этим, а я просто не смог ни с одним из предыдущих тестов, вы можете попробовать связать его с -lcompiler_rt-extras, Это включено с NDK r17 и имеет отсутствующие функции.

Другие вопросы по тегам