title: Undefined references while using ffmpeg 2.1.1 for Android
body: <p>I'm building ffmpeg following the same pattern as <a href="https://github.com/halfninja/android-ffmpeg-x264" rel="nofollow">halfninja's build</a>: make the ffmpeg's <code>main</code> available from Java through JNI. I built ffmpeg with the following options:</p>
  
  <pre><code>./configure \
      --prefix=$PREFIX \
      --disable-shared \
      --enable-static \
      --disable-doc \
      --disable-ffmpeg \
      --disable-ffplay \
      --disable-ffprobe \
      --disable-ffserver \
      --disable-doc \
      --disable-symver \
      --cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
      --target-os=linux \
      --arch=arm \
      --enable-cross-compile \
      --sysroot=$SYSROOT \
      --extra-cflags="-Os -fpic $ADDI_CFLAGS" \
      --extra-ldflags="$ADDI_LDFLAGS"</code></pre>
  
  <p><code>$PREFIX</code>, <code>TOOLCHAIN</code>, … being set to corresponding folders from my NDK. <code>$ADDI_CFLAGS</code> is set to <code>-marm</code> and <code>$ADDI_LDFLAGS</code> and <code>$ADDITIONAL_CONFIGURE_FLAGS</code> are both unset. The resulting static libraries are created:</p>
  
  <pre>$ ls -1 android/arm/lib/
  libavcodec.a
  libavdevice.a
  libavfilter.a
  libavformat.a
  libavutil.a
  libswresample.a
  libswscale.a
  pkgconfig</pre>
  
  <p>I expose them with an <code>Android.mk</code> file, ffmpeg being built in <code>$NDK/sources/ffmpeg-2.1.1</code>:</p>
  
  <pre><code>LOCAL_PATH:= $(call my-dir)
  
  include $(CLEAR_VARS)
  LOCAL_MODULE:= libavdevice
  LOCAL_SRC_FILES:= lib/libavdevice.a
  LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
  include $(PREBUILT_STATIC_LIBRARY)
  
  include $(CLEAR_VARS)
  LOCAL_MODULE:= libavcodec
  LOCAL_SRC_FILES:= lib/libavcodec.a
  LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
  include $(PREBUILT_STATIC_LIBRARY)
  
  include $(CLEAR_VARS)
  LOCAL_MODULE:= libavformat
  LOCAL_SRC_FILES:= lib/libavformat.a
  LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
  include $(PREBUILT_STATIC_LIBRARY)
  
  include $(CLEAR_VARS)
  LOCAL_MODULE:= libswscale
  LOCAL_SRC_FILES:= lib/libswscale.a
  LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
  include $(PREBUILT_STATIC_LIBRARY)
  
  include $(CLEAR_VARS)
  LOCAL_MODULE:= libavutil
  LOCAL_SRC_FILES:= lib/libavutil.a
  LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
  include $(PREBUILT_STATIC_LIBRARY)
  
  include $(CLEAR_VARS)
  LOCAL_MODULE:= libavfilter
  LOCAL_SRC_FILES:= lib/libavfilter.a
  LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
  include $(PREBUILT_STATIC_LIBRARY)
  
  include $(CLEAR_VARS)
  LOCAL_MODULE:= libwsresample
  LOCAL_SRC_FILES:= lib/libswresample.a
  LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
  include $(PREBUILT_STATIC_LIBRARY)</code></pre>
  
  <p>So, up to there, everything looks good. Now, I try to build the <code>ffmpeg</code> binary equivalent as a static library. I copied (and didn't change a single character for now) <code>ffmpeg.c</code>, <code>ffmpeg.h</code>, <code>cmdutils.c</code>, <code>cmdutils.h</code>, <code>ffmpeg_opt.c</code>and <code>ffmpeg_filter.c</code> in my <code>jni</code> folder. I also have two directly JNI-related files in this folder (copied from halfninja's build, I just changed the package name). Here's the relevant <code>Android.mk</code>:</p>
  
  <pre><code>LOCAL_PATH := $(call my-dir)
  
  include $(CLEAR_VARS)
  LOCAL_C_INCLUDES := /Applications/android-ndk-r9b/sources/ffmpeg-2.1.1
  LOCAL_CFLAGS := -Wdeprecated-declarations
  LOCAL_MODULE := videokit
  ANDROID_LIB := -landroid
  LOCAL_LDLIBS += -llog -ljnigraphics -lz 
  LOCAL_SRC_FILES := videokit/com_rfc_video_ffmpeg_Videokit.c videokit/ffmpeg.c videokit/cmdutils.c videokit/ffmpeg_opt.c videokit/ffmpeg_filter.c
  LOCAL_SHARED_LIBRARIES := libavdevice libavformat libavfilter libavcodec libwscale libavutil libswresample libswscale libpostproc
  include $(BUILD_SHARED_LIBRARY)
  $(call import-module,ffmpeg-2.1.1/android/arm)</code></pre>
  
  <p>Everything compiles fine, but doesn't link. Here are the first errors:</p>
  
  <pre>[armeabi] SharedLibrary  : libvideokit.so
  /Applications/android-ndk-r9b/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: ./obj/local/armeabi/objs/videokit/videokit/cmdutils.o: in function print_all_libs_info.constprop.5:jni/videokit/cmdutils.c:1063: error: undefined reference to 'swresample_version'
  /Applications/android-ndk-r9b/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: ./obj/local/armeabi/objs/videokit/videokit/cmdutils.o: in function print_all_libs_info.constprop.5:jni/videokit/cmdutils.c:1063: error: undefined reference to 'swresample_configuration'
  /Applications/android-ndk-r9b/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: ./obj/local/armeabi/objs/videokit/videokit/cmdutils.o: in function opt_default:jni/videokit/cmdutils.c:558: error: undefined reference to 'swr_get_class'
  /Applications/android-ndk-r9b/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: ./obj/local/armeabi/objs/videokit/videokit/cmdutils.o: in function opt_default:jni/videokit/cmdutils.c:561: error: undefined reference to 'swr_alloc'
  /Applications/android-ndk-r9b/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: ./obj/local/armeabi/objs/videokit/videokit/cmdutils.o: in function opt_default:jni/videokit/cmdutils.c:563: error: undefined reference to 'swr_free'
  /Applications/android-ndk-r9b/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: ./obj/local/armeabi/objs/videokit/videokit/ffmpeg_opt.o: in function show_help_default:jni/videokit/ffmpeg_opt.c:2464: error: undefined reference to 'swr_get_class'</pre>
  
  <p>What I don't understand is that these functions are defined and available in <code>libswresample.a</code>, which I'm linking to:</p>
  
  <pre>arm-linux-androideabi-nm /Applications/android-ndk-r9b/sources/ffmpeg-2.1.1/android/arm/lib/libswresample.a  | grep -i -e swr_get_class -e swresample_version
  000001d4 T swr_get_class
  00000178 T swresample_version</pre>
  
  <p>What am I doing wrong? Is there another, maybe simpler way to expose ffmpeg as a static library available via JNI? (I don't use halfninja's because I need at least ffmpeg 1.1, while his is in 0.9).</p>