Search code examples
ffmpegandroid-ndkstatic-librariesstatic-linkingconfigure

Static linking FFmpeg libraries on android


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?

Solution

  • 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"