Static linking FFmpeg libraries on android

Viewed 1452

I am trying to build FFmpeg for android as static libraries on a MacOS Sierra machine.

Following is my buildscript.sh which is very much based upon the one in here

#!/bin/bash

cd ffmpeg-3.3.4

NDK=/path/to/android/ndk/android-ndk-r15c
SYSROOT=$NDK/platforms/android-21/arch-arm64/
TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64
AR=$TOOLCHAIN/bin/arm-linux-androideabi-ar
CPREFIX=$TOOLCHAIN/bin/arm-linux-androideabi-
CC=$TOOLCHAIN/bin/arm-linux-androideabi-gcc
CXX=$TOOLCHAIN/bin/arm-linux-androideabi-g++
LD=$TOOLCHAIN/bin/arm-linux-androideabi-ld
RANLIB=$TOOLCHAIN/bin/arm-linux-androideabi-ranlib
STRIP=$TOOLCHAIN/bin/arm-linux-androideabi-strip
X264LIB=$X264/android/arm/lib/
X264INC=$X264/android/arm/include/

function build_ffmpeg_android {

./configure \
    --prefix=$PREFIX \
    --disable-stripping
    --arch=arm \
    --cpu=cortex-a8 \
    --target-os=linux \
    --enable-cross-compile \
    --enable-pic \
    --disable-programs \
    --enable-static \
    --disable-shared \
    --cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
    --disable-doc \
    --enable-postproc \
    --enable-swscale \
    --enable-avfilter \
    --enable-avresample \
    --disable-opencl \
    --disable-securetransport \
    --enable-gpl \
    --sysroot=$SYSROOT \
    --extra-cflags="-Os -fpic $ADDI_CFLAGS -I$X264INC"  \
    --extra-ldflags="$ADDI_LDFLAGS -s -L$X264LIB -lx264" \
    --enable-gpl \
    --enable-decoders \
    --enable-encoders \
    --enable-muxers \
    --enable-demuxers \
    --enable-parsers \
    --enable-protocols \
    --enable-filters \
    --enable-avresample \
    --enable-libfreetype \
    --disable-indevs \
    --enable-indev=lavfi \
    --disable-outdevs \
    --enable-hwaccels \
    --enable-ffmpeg \
    --disable-ffplay \
    --disable-ffprobe \
    --disable-ffserver \
    --disable-network \
    --enable-libx264 \
    --enable-zlib \
    --enable-muxer=md5
    make clean
    make -j9
    make install
}

CPU=arm
PREFIX=$(pwd)/android/$CPU
ADDI_CFLAGS="-marm"

build_ffmpeg_android

The output of above script is placed inside ffmpeg-3.3.4/android/arm.

My issue:
When trying to link to these .a libraries from my app using -lavformat -lavcodec -lswscale -lavutil -lavfilter -lswresample -lavdevice,
I get the following linker error for each of them

:-1: error: error: avformat: no archive symbol table (run ranlib)
:-1: error: error: avcodec: no archive symbol table (run ranlib)
:-1: error: error: swscale: no archive symbol table (run ranlib)
:-1: error: error: avutil: no archive symbol table (run ranlib)
:-1: error: error: avfilter: no archive symbol table (run ranlib)
:-1: error: error: swresample: no archive symbol table (run ranlib)
:-1: error: error: avdevice: no archive symbol table (run ranlib)

Looking at this discussion here, I am doing it correct by selecting arm-linux-androideabi-ar in CPREFIX.

Trying to solve the error, I've also added the following configure flag for ranlib to be picked up specifically for android but doesn't seem to help.

RANLIB=$TOOLCHAIN/bin/arm-linux-androideabi-ranlib

My Questions:

  • What else am I missing here?
  • What is needed in my buildscript.sh to pick the correct ranlib & stop complaining about archive symbol table when linking from my app?
2 Answers

Following are the correct configure flags:

./configure \
  --prefix=$PREFIX \
  --disable-stripping \
  --arch=arm \
  --cpu=armv5te \
  --disable-asm \
  --target-os=linux \
  --enable-cross-compile \
  --enable-debug \
  --enable-pic \
  --disable-programs \
  --enable-static \
  --disable-shared \
  --cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
  --disable-doc \
  --enable-postproc \
  --enable-swscale \
  --enable-avfilter \
  --enable-avresample \
  --disable-opencl \
  --disable-securetransport \
  --sysroot=$SYSROOT \
  --enable-videotoolbox \
  --enable-avresample \
  --disable-symver \
  --extra-cflags="-O3 -Wall -pipe -std=c99 -ffast-math -fstrict-aliasing -Werror=strict-aliasing -Wno-psabi -Wa,--noexecstack -DANDROID -DNDEBUG-march=armv5te -mtune=arm9tdmi -msoft-float"
  $ADDITIONAL_CONFIGURE_FLAG
  make clean
  make -j9
  make install

Note that following cflags make the difference on android

--extra-cflags="-O3 -Wall -pipe -std=c99 -ffast-math -fstrict-aliasing -Werror=strict-aliasing -Wno-psabi -Wa,--noexecstack -DANDROID -DNDEBUG-march=armv5te -mtune=arm9tdmi -msoft-float"

Spent a day trying to build ffmpeg with updated x265 for Android.

x265 successfully compiles into static library, but when its time to include it in ffmpeg, I'm getting error:

...aarch64-linux-android/bin/ld.gold: error: x265: no archive symbol table (run ranlib)
clang: error: linker command failed with exit code 1 (use -v to see invocation)
C compiler test failed.

It is really hard to find any information about this error in the web and I've tried nearly everything. But... in my case all you have to do is to update your CMAKE version.

cmake 3.20.5 is installed but outdated
==> Upgrading cmake
  3.20.5 -> 3.21.0 

Before this I had cmake 3.10.2.4988404 and everything worked as expected, then Homebrew updated cmake as a dependency for some package and headache begun. To sum up: 'stable' versions of cmake for ffmpeg+x265 are 3.10.2 and 3.21.0

Related