Repository navigation
Unable to compile ffmpeg extension with NDK 23 + CMake-3.22 #9933
Copy link
Copy link
Closed
Labels
Description
My setup:
- ExoPlayer 2.15.1
- Android NDK 23.1.7779620
- CMake 3.22.2 (using system package from Fedora)
In order to build with this setup, I'm using the following patch:
diff --git a/extensions/ffmpeg/build.gradle b/extensions/ffmpeg/build.gradle
index a9edeaff6b..14d3bc9fbb 100644
--- a/extensions/ffmpeg/build.gradle
+++ b/extensions/ffmpeg/build.gradle
@@ -17,7 +17,8 @@ apply from: "$gradle.ext.exoplayerSettingsDir/common_library_config.gradle"
// failures if ffmpeg hasn't been built according to the README instructions.
if (project.file('src/main/jni/ffmpeg').exists()) {
android.externalNativeBuild.cmake.path = 'src/main/jni/CMakeLists.txt'
- android.externalNativeBuild.cmake.version = '3.7.1+'
+ android.externalNativeBuild.cmake.version = '3.18.0+'
+ android.ndkVersion = '23.1.7779620'
}
dependencies {
diff --git a/extensions/ffmpeg/src/main/jni/build_ffmpeg.sh b/extensions/ffmpeg/src/main/jni/build_ffmpeg.sh
index 7b2e933902..e678d2ef2e 100755
--- a/extensions/ffmpeg/src/main/jni/build_ffmpeg.sh
+++ b/extensions/ffmpeg/src/main/jni/build_ffmpeg.sh
@@ -49,10 +49,10 @@ cd "${FFMPEG_EXT_PATH}/jni/ffmpeg"
--arch=arm \
--cpu=armv7-a \
--cross-prefix="${TOOLCHAIN_PREFIX}/armv7a-linux-androideabi16-" \
- --nm="${TOOLCHAIN_PREFIX}/arm-linux-androideabi-nm" \
- --ar="${TOOLCHAIN_PREFIX}/arm-linux-androideabi-ar" \
- --ranlib="${TOOLCHAIN_PREFIX}/arm-linux-androideabi-ranlib" \
- --strip="${TOOLCHAIN_PREFIX}/arm-linux-androideabi-strip" \
+ --nm="${TOOLCHAIN_PREFIX}/llvm-nm" \
+ --ar="${TOOLCHAIN_PREFIX}/llvm-ar" \
+ --ranlib="${TOOLCHAIN_PREFIX}/llvm-ranlib" \
+ --strip="${TOOLCHAIN_PREFIX}/llvm-strip" \
--extra-cflags="-march=armv7-a -mfloat-abi=softfp" \
--extra-ldflags="-Wl,--fix-cortex-a8" \
${COMMON_OPTIONS}
@@ -64,10 +64,10 @@ make clean
--arch=aarch64 \
--cpu=armv8-a \
--cross-prefix="${TOOLCHAIN_PREFIX}/aarch64-linux-android21-" \
- --nm="${TOOLCHAIN_PREFIX}/aarch64-linux-android-nm" \
- --ar="${TOOLCHAIN_PREFIX}/aarch64-linux-android-ar" \
- --ranlib="${TOOLCHAIN_PREFIX}/aarch64-linux-android-ranlib" \
- --strip="${TOOLCHAIN_PREFIX}/aarch64-linux-android-strip" \
+ --nm="${TOOLCHAIN_PREFIX}/llvm-nm" \
+ --ar="${TOOLCHAIN_PREFIX}/llvm-ar" \
+ --ranlib="${TOOLCHAIN_PREFIX}/llvm-ranlib" \
+ --strip="${TOOLCHAIN_PREFIX}/llvm-strip" \
${COMMON_OPTIONS}
make -j$JOBS
make install-libs
@@ -77,10 +77,10 @@ make clean
--arch=x86 \
--cpu=i686 \
--cross-prefix="${TOOLCHAIN_PREFIX}/i686-linux-android16-" \
- --nm="${TOOLCHAIN_PREFIX}/i686-linux-android-nm" \
- --ar="${TOOLCHAIN_PREFIX}/i686-linux-android-ar" \
- --ranlib="${TOOLCHAIN_PREFIX}/i686-linux-android-ranlib" \
- --strip="${TOOLCHAIN_PREFIX}/i686-linux-android-strip" \
+ --nm="${TOOLCHAIN_PREFIX}/llvm-nm" \
+ --ar="${TOOLCHAIN_PREFIX}/llvm-ar" \
+ --ranlib="${TOOLCHAIN_PREFIX}/llvm-ranlib" \
+ --strip="${TOOLCHAIN_PREFIX}/llvm-strip" \
--disable-asm \
${COMMON_OPTIONS}
make -j$JOBS
@@ -91,10 +91,10 @@ make clean
--arch=x86_64 \
--cpu=x86_64 \
--cross-prefix="${TOOLCHAIN_PREFIX}/x86_64-linux-android21-" \
- --nm="${TOOLCHAIN_PREFIX}/x86_64-linux-android-nm" \
- --ar="${TOOLCHAIN_PREFIX}/x86_64-linux-android-ar" \
- --ranlib="${TOOLCHAIN_PREFIX}/x86_64-linux-android-ranlib" \
- --strip="${TOOLCHAIN_PREFIX}/x86_64-linux-android-strip" \
+ --nm="${TOOLCHAIN_PREFIX}/llvm-nm" \
+ --ar="${TOOLCHAIN_PREFIX}/llvm-ar" \
+ --ranlib="${TOOLCHAIN_PREFIX}/llvm-ranlib" \
+ --strip="${TOOLCHAIN_PREFIX}/llvm-strip" \
--disable-asm \
${COMMON_OPTIONS}
make -j$JOBS
I compile ffmpeg code according to build instructions:
cd extensions/ffmpeg/src/main/jni/
git clone git://source.ffmpeg.org/ffmpeg
(cd ffmpeg && \
git checkout release/4.2)
./build_ffmpeg.sh \
/path/to/ExoPlayer/extensions/ffmpeg/src/main \
/path/to/android-sdk-linux/ndk/23.1.7779620 \
linux-x86_64 \
ac3 mp3
Finally I try to compile the demo app:
./gradlew :demo:assembleWithDecoderExtensionsDebug
Build fails at task :extension-ffmpeg:externalNativeBuildDebug. The output log at the failure is the following (there are actually a bunch of link errors, I just copied the first ones):
[2/2] Linking CXX shared library /path/to/ExoPlayer/extensions/ffmpeg/buildout/intermediates/cmake/debug/obj/arm64-v8a/libffmpegJNI.so
FAILED: /path/to/ExoPlayer/extensions/ffmpeg/buildout/intermediates/cmake/debug/obj/arm64-v8a/libffmpegJNI.so
: && /path/to/android-sdk-linux/ndk/23.1.7779620/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ --target=aarch64-none-linux-android21 --sysroot=/path/to/android-sdk-linux/ndk/23.1.7779620/toolchains/llvm/prebuilt/linux-x86_64/sysroot -fPIC -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fexceptions -frtti -stdlib=libc++ -g -fno-limit-debug-info -Wl,--build-id=sha1 -Wl,--no-rosegment -Wl,--fatal-warnings -Qunused-arguments -Wl,--no-undefined -shared -Wl,-soname,libffmpegJNI.so -o /path/to/ExoPlayer/extensions/ffmpeg/buildout/intermediates/cmake/debug/obj/arm64-v8a/libffmpegJNI.so CMakeFiles/ffmpegJNI.dir/ffmpeg_jni.cc.o -landroid /path/to/ExoPlayer/extensions/ffmpeg/src/main/jni/ffmpeg/android-libs/arm64-v8a/libswresample.a /path/to/ExoPlayer/extensions/ffmpeg/src/main/jni/ffmpeg/android-libs/arm64-v8a/libavcodec.a /path/to/ExoPlayer/extensions/ffmpeg/src/main/jni/ffmpeg/android-libs/arm64-v8a/libavutil.a /path/to/android-sdk-linux/ndk/23.1.7779620/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/aarch64-linux-android/21/liblog.so -static-libstdc++ -latomic -lm && :
ld: error: relocation R_AARCH64_ADR_PREL_PG_HI21 cannot be used against symbol ff_cos_32; recompile with -fPIC
>>> defined in /path/to/ExoPlayer/extensions/ffmpeg/src/main/jni/ffmpeg/android-libs/arm64-v8a/libavcodec.a(fft_float.o)
>>> referenced by fft_neon.S:356 (libavcodec/aarch64/fft_neon.S:356)
>>> fft_neon.o:(fft32_neon) in archive /path/to/ExoPlayer/extensions/ffmpeg/src/main/jni/ffmpeg/android-libs/arm64-v8a/libavcodec.a
ld: error: can't create dynamic relocation R_AARCH64_ADD_ABS_LO12_NC against symbol: ff_cos_32 in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
>>> defined in /path/to/ExoPlayer/extensions/ffmpeg/src/main/jni/ffmpeg/android-libs/arm64-v8a/libavcodec.a(fft_float.o)
>>> referenced by fft_neon.S:356 (libavcodec/aarch64/fft_neon.S:356)
>>> fft_neon.o:(fft32_neon) in archive /path/to/ExoPlayer/extensions/ffmpeg/src/main/jni/ffmpeg/android-libs/arm64-v8a/libavcodec.a
Previously, I was using Android NDK 21.0.6113669 and CMake 3.10.2.4988404 (installed with sdkmanager), which worked fine.
Reactions are currently unavailable
Activity
goffioul commentedon Feb 4, 2022
After some research, I found these useful references:
I added the following to
extensions/ffmpeg/build.gradleand that fixed the link error:AquilesCanta commentedon Feb 16, 2022
Thanks for the report. We will only be fixing build_ffmpeg.sh, though. I don't think CMake is related to the failure, and we don't need to enforce a specific NDK version at gradle level.
A patch will appear below once this is pushed, when we'd appreciate you verify our fix satisfies your usecase.
goffioul commentedon Feb 17, 2022
The change in CMake version as I made in
extensions/ffmpeg/build.gradleis indeed not necessary (but the others inbuild_ffmpeg.shand the additional link flag inextensions/ffmpeg/build.gradleare; the specific NDK version was just specific to my dev setup). However there are a few things to consider when using an older CMake version:https://android.googlesource.com/platform/ndk/+/refs/tags/ndk-r23b/build/cmake/android-legacy.toolchain.cmake#416
https://gitlab.kitware.com/cmake/cmake/-/issues/22021
Depend on llvm-xy bin utils instead of GNU's binutils
Depend on llvm-xy bin utils instead of GNU's binutils
Depend on llvm-xy bin utils instead of GNU's binutils
goffioul commentedon Feb 23, 2022
I see the commit doesn't include the linker flag change. Didn't run into link error when compiling? If not, what NDK version, ffmpeg version and ffmpeg codecs did you test with? (in my case, using NDK 23 and ffmpeg's ac3 + mp3, I get an error at link time)
goffioul commentedon Feb 25, 2022
For the record, the link error is still present in
2.17.0with NDK 23.Depend on llvm-xy bin utils instead of GNU's binutils
AquilesCanta commentedon Mar 7, 2022
I'll take another look. I was on holiday.
10 remaining items
tonihei commentedon Aug 12, 2022
This is the recommended NDK version for the current Android Studio release (Dolphin | 20221.3.1). See https://developer.android.com/studio/projects/install-ndk#default-ndk-per-agp. Using this NDK version works well without modifications as pointed out above.
The issue only reproduces for NDK versions 23.1.7779620 and above (I tested with 25.0.8775105) and can be solved by the additional flags mentioned in #9933 (comment). I'll submit a fix that turns these flags on for the "arm64-v8a" ABI (that's the only one that needs it). Even though the default NDK doesn't have this problem yet, it's likely the default NDK will be updated in an upcoming Android Studio release and it's definitely worth fixing it.
menscikov commentedon Aug 12, 2022
@tonihei i've noticed that you forgot to update CMake version in the AV1 extension.
But latest CMake version is giving an error, i had to use 3.18.1 for AV1.
tonihei commentedon Aug 15, 2022
@menscikov Thanks for the hint, we'll fix this as well.
tonihei commentedon Sep 6, 2022
The fix should appear here soon and will be part of the next release.
Add additional build flags for ffmpeg on "arm64-v8a"
Update CMake version for AV1 extension
Add additional build flags for ffmpeg on "arm64-v8a"
Update CMake version for AV1 extension