Skip to content

Unable to compile ffmpeg extension with NDK 23 + CMake-3.22 #9933

Closed

Description

@goffioul

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.

Activity

  1. goffioul commented on Feb 4, 2022

    @goffioul
    ContributorAuthor

    After some research, I found these useful references:

    I added the following to extensions/ffmpeg/build.gradle and that fixed the link error:

    android.defaultConfig.externalNativeBuild.cmake.cppFlags = [ '-Wl,-Bsymbolic' ]
    
  2. AquilesCanta commented on Feb 16, 2022

    @AquilesCanta
    Contributor

    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.

  3. goffioul commented on Feb 17, 2022

    @goffioul
    ContributorAuthor

    The change in CMake version as I made in extensions/ffmpeg/build.gradle is indeed not necessary (but the others in build_ffmpeg.sh and the additional link flag in extensions/ffmpeg/build.gradle are; 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:

    1. you'll see a series of warning about using an old CMake:
      https://android.googlesource.com/platform/ndk/+/refs/tags/ndk-r23b/build/cmake/android-legacy.toolchain.cmake#416
    2. if you upgrade to a newer CMake, you'll run into this issue, which is the reason I changed the min CMake version:
      https://gitlab.kitware.com/cmake/cmake/-/issues/22021
  4. goffioul commented on Feb 23, 2022

    @goffioul
    ContributorAuthor

    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)

  5. goffioul commented on Feb 25, 2022

    @goffioul
    ContributorAuthor

    For the record, the link error is still present in 2.17.0 with NDK 23.

  6. AquilesCanta commented on Mar 7, 2022

    @AquilesCanta
    Contributor

    I'll take another look. I was on holiday.

  7. 10 remaining items

  8. tonihei commented on Aug 12, 2022

    @tonihei
    Collaborator

    gradle downloads NDK 21.4.7075529 during the build

    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.

  9. menscikov commented on Aug 12, 2022

    @menscikov

    @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.

  10. tonihei commented on Aug 15, 2022

    @tonihei
    Collaborator

    @menscikov Thanks for the hint, we'll fix this as well.

  11. tonihei commented on Sep 6, 2022

    @tonihei
    Collaborator

    The fix should appear here soon and will be part of the next release.

  12. locked and limited conversation to collaborators on Nov 6, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions