Question

I am working on an Android app. To proceed I must use the libav with the Android NDK. I am compiling static libraries of libav for arm, armv7, x86 and mips with this script:

#!/bin/sh

message () {
    echo "=========================================="
    echo "== $1"
    echo "=========================================="
}

NDK=~/Documents/adt-bundle/ndk-r9

PROGDIR=`dirname $0`
PROGDIR=`cd $PROGDIR && pwd`

LIBAV=$PROGDIR/src/libav-9.9.tar.gz

for ABI in armeabi armeabi-v7a x86 mips; do

    case $ABI in
        armeabi)
            TOOLCHAIN=arm-linux-androideabi-4.8
            TOOLCHAIN_DIR=$PROGDIR/toolchains/android-9-arm
            TOOLCHAIN_PREFIX=arm-linux-androideabi-
            EXTRA_CFLAGS=""
            EXTRA_LDFLAGS=""
            ;;
        armeabi-v7a)
            TOOLCHAIN=arm-linux-androideabi-4.8
            TOOLCHAIN_DIR=$PROGDIR/toolchains/android-9-arm
            TOOLCHAIN_PREFIX=arm-linux-androideabi-
            EXTRA_CFLAGS="-march=armv7-a -mfloat-abi=softfp -mfpu=neon"
            EXTRA_LDFLAGS="-march=armv7-a -Wl,--fix-cortex-a8"
            ;;
        x86)
            TOOLCHAIN=x86-4.8
            TOOLCHAIN_DIR=$PROGDIR/toolchains/android-9-x86
            TOOLCHAIN_PREFIX=i686-linux-android-
            EXTRA_CFLAGS=""
            EXTRA_LDFLAGS=""
            ;;
        mips)
            TOOLCHAIN=mipsel-linux-android-4.8
            TOOLCHAIN_DIR=$PROGDIR/toolchains/android-9-mips
            TOOLCHAIN_PREFIX=mipsel-linux-android-
            EXTRA_CFLAGS=""
            EXTRA_LDFLAGS=""
            ;;
    esac

    if [ ! -d $TOOLCHAIN_DIR ] ; then
        $NDK/build/tools/make-standalone-toolchain.sh --platform=android-9 --install-dir=$TOOLCHAIN_DIR --toolchain=$TOOLCHAIN
    fi

    BUILDDIR="$PROGDIR/build/$ABI"
    INCDIR="$PROGDIR/include/$ABI"
    LIBDIR="$PROGDIR/lib/$ABI"

    LIBAV_DIR="$BUILDDIR/libav-9.9"
    LIBAV_BUILD_DIR="$LIBAV_DIR-build"

    if [ ! -d $LIBAV_DIR ] ; then
        mkdir -p $LIBAV_DIR
        tar -xf $LIBAV -C `dirname $LIBAV_DIR`
    fi

    export PATH="$TOOLCHAIN_DIR/bin:$PATH"
    export SYSROOT="$TOOLCHAIN_DIR/sysroot"
    export CC="${TOOLCHAIN_PREFIX}gcc"
#    export CXX="${TOOLCHAIN_PREFIX}g++"
#    export LD="${TOOLCHAIN_PREFIX}ld"
#    export AR="${TOOLCHAIN_PREFIX}ar"
    export CFLAGS="-O3 $EXTRA_CFLAGS"
    export LDFLAGS="-static $EXTRA_LDFLAGS"

    (message "Configuring libav for Android $ABI" \
    && cd $LIBAV_DIR \
    && sh ./configure \
        --prefix=$LIBAV_BUILD_DIR \
        --enable-cross-compile \
        --cross-prefix=$TOOLCHAIN_PREFIX \
        --sysroot=$SYSROOT \
        --target-os=linux \
        --extra-cflags="$CFLAGS" \
        --extra-ldflags="$LDFLAGS" \
        --arch="$ABI" \
        --disable-pthreads \
        --disable-programs \
        --disable-doc \
        --disable-avdevice \
        --disable-avformat \
        --disable-avfilter \
        --disable-avresample \
        --disable-network \
        --disable-everything \
        --enable-decoder=h264 \
        --enable-decoder=mpeg4 \
    \
    && message "Making libav for Android ($ABI)" \
    && make \
    \
    && message "Installing libav for Android ($ABI)" \
    && make install \
    && mkdir -pv $INCDIR $LIBDIR \
    && mkdir -pv $INCDIR/libavcodec \
    && cp -pv $LIBAV_BUILD_DIR/include/libavcodec/*.h $INCDIR/libavcodec \
    && cp -pv $LIBAV_BUILD_DIR/lib/libavcodec.a $LIBDIR \
    && mkdir -pv $INCDIR/libavutil \
    && cp -pv $LIBAV_BUILD_DIR/include/libavutil/*.h $INCDIR/libavutil \
    && cp -pv $LIBAV_BUILD_DIR/lib/libavutil.a $LIBDIR \
    && mkdir -pv $INCDIR/libswscale \
    && cp -pv $LIBAV_BUILD_DIR/include/libswscale/*.h $INCDIR/libswscale \
    && cp -pv $LIBAV_BUILD_DIR/lib/libswscale.a $LIBDIR) || exit 1

done

The compilation is doing well. I get libavcodec, libavutil and libswscale compiled for the 4 architectures.

My problem comes when linking these libraries with my project for the x86 architecture (it works with arm and mips!). Here is the output of the ndk-build all -k command:

Compile++ thumb  : stream <= jni.cpp
Compile++ thumb  : stream <= parser.cpp
Compile++ thumb  : stream <= stream.cpp
Compile++ thumb  : stream <= surface.cpp
Compile++ thumb  : stream <= thread.cpp
Compile++ thumb  : stream <= decoder.cpp
Compile++ thumb  : stream <= utils.cpp
StaticLibrary  : libstdc++.a
SharedLibrary  : libstream.so
Install        : libstream.so => libs/armeabi-v7a/libstream.so
Compile++ thumb  : stream <= jni.cpp
Compile++ thumb  : stream <= parser.cpp
Compile++ thumb  : stream <= stream.cpp
Compile++ thumb  : stream <= surface.cpp
Compile++ thumb  : stream <= thread.cpp
Compile++ thumb  : stream <= decoder.cpp
Compile++ thumb  : stream <= utils.cpp
StaticLibrary  : libstdc++.a
SharedLibrary  : libstream.so
Install        : libstream.so => libs/armeabi/libstream.so
Compile++ x86    : stream <= jni.cpp
Compile++ x86    : stream <= parser.cpp
Compile++ x86    : stream <= stream.cpp
Compile++ x86    : stream <= surface.cpp
Compile++ x86    : stream <= thread.cpp
Compile++ x86    : stream <= decoder.cpp
Compile++ x86    : stream <= utils.cpp
StaticLibrary  : libstdc++.a
SharedLibrary  : libstream.so
/home/camtrace/Documents/adt-bundle/ndk-r9/toolchains/x86-4.6/prebuilt/linux-x86/bin/../lib/gcc/i686-linux-android/4.6/../../../../i686-linux-android/bin/ld: internal error in relocate_section, at /s/ndk-toolchain/src/build/../binutils/binutils-2.21/gold/i386.cc:2980
collect2: ld returned 1 exit status
make: *** [obj/local/x86/libstream.so] Error 1
Compile++ mips   : stream <= jni.cpp
Compile++ mips   : stream <= parser.cpp
Compile++ mips   : stream <= stream.cpp
Compile++ mips   : stream <= surface.cpp
Compile++ mips   : stream <= thread.cpp
Compile++ mips   : stream <= decoder.cpp
Compile++ mips   : stream <= utils.cpp
StaticLibrary  : libstdc++.a
SharedLibrary  : libstream.so
Install        : libstream.so => libs/mips/libstream.so
make: Target `all' not remade because of errors.

Here is my Android.mk file:

LOCAL_PATH := $(call my-dir)


#
# Libjpeg-turbo

include $(CLEAR_VARS)
LOCAL_MODULE            := turbojpeg
LOCAL_SRC_FILES         := prebuilts/lib/$(TARGET_ARCH_ABI)/libturbojpeg.a
LOCAL_EXPORT_C_INCLUDES := jni/prebuilts/include/$(TARGET_ARCH_ABI)
include $(PREBUILT_STATIC_LIBRARY)


#
# Libav

include $(CLEAR_VARS)
LOCAL_MODULE            := libavcodec
LOCAL_SRC_FILES         := prebuilts/lib/$(TARGET_ARCH_ABI)/libavcodec.a
LOCAL_EXPORT_C_INCLUDES := jni/prebuilts/include/$(TARGET_ARCH_ABI)
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE            := libavutil
LOCAL_SRC_FILES         := prebuilts/lib/$(TARGET_ARCH_ABI)/libavutil.a
LOCAL_EXPORT_C_INCLUDES := jni/prebuilts/include/$(TARGET_ARCH_ABI)
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE            := libswscale
LOCAL_SRC_FILES         := prebuilts/lib/$(TARGET_ARCH_ABI)/libswscale.a
LOCAL_EXPORT_C_INCLUDES := jni/prebuilts/include/$(TARGET_ARCH_ABI)
include $(PREBUILT_STATIC_LIBRARY)


#
# My code

include $(CLEAR_VARS)
LOCAL_MODULE := stream
LOCAL_SRC_FILES := \
    src/jni.cpp \
    src/parser.cpp \
    src/stream.cpp \
    src/surface.cpp \
    src/thread.cpp \
    src/decoder.cpp \
    src/utils.cpp
LOCAL_STATIC_LIBRARIES := turbojpeg libavcodec libavutil libswscale
LOCAL_CFLAGS := -Wall -Werror
LOCAL_LDLIBS := -landroid -llog
include $(BUILD_SHARED_LIBRARY)
Was it helpful?

Solution

I was able to successfully build ffmpeg libs for android using the build scripts from here http://code.google.com/p/dolphin-player/source/checkout. They then linked with my app fine.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top