【问题标题】:Undefined Reference - ffmpeg on android ndk未定义的参考 - android ndk 上的 ffmpeg
【发布时间】:2011-12-08 14:29:52
【问题描述】:

我花了很多时间试图弄清楚为什么我在尝试链接到 ffmpeg 时仍然得到“未定义的引用”。 我已经阅读了大部分(如果不是全部)关于该主题的帖子和网站,所以我想我在这里遗漏了一些东西,希望你能帮助我。

我有什么:

我正在使用 Windows 7 + cygwin + crystax r4。 我已经使用 RockPlayer 的 ffmpeg 源代码以及我所做的一些修改编译了 FFMPEG(仅包括/排除解复用器、解码器、编码器......) 编译后得到:

  • 一个名为 armv5te 的新文件夹,其中包括:
  • 一个名为“include”的文件夹,其中包含每个库的 .h 的所有文件夹
  • 一个名为“lib”的文件夹,其中包含所有库的 .a
  • 一个名为 libffmpeg.so 的共享库(检查了 soname,它是 libffmpeg)

共享库也不放在 project/lib/armeabi/libffmpeg.so 上

编译后我尝试编译我的项目并链接它。虽然我的 .cpp 编译正常,但我得到了许多未定义的引用。

这是我的构建脚本:

NDK=/cygdrive/c/Gabriel/Desenvolvimento/SDKs/Android/android-ndk-r4-crystax
PLATFORM=$NDK/build/platforms/android-8/arch-arm/
PREBUILT=$NDK/build/prebuilt/windows/arm-eabi-4.4.0


function build_one
{

./configure --target-os=linux \
    --prefix=$PREFIX \
    --enable-cross-compile \
    --extra-libs="-lgcc" \
    --arch=arm \
    --cc=$PREBUILT/bin/arm-eabi-gcc \
    --cross-prefix=$PREBUILT/bin/arm-eabi- \
    --nm=$PREBUILT/bin/arm-eabi-nm \
    --sysroot=$PLATFORM \
    --extra-cflags=" -O2 -fpic -DANDROID -DHAVE_SYS_UIO_H=1 -Dipv6mr_interface=ipv6mr_ifindex -fasm -Wno-psabi -fno-short-enums  -fno-strict-aliasing -finline-limit=300 $OPTIMIZE_CFLAGS " \
    --disable-shared \
    --enable-static \
    --extra-ldflags="-Wl,-rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib  -nostdlib -lc -lm -ldl -llog" \
    --disable-stripping \
    --disable-debug \
    --disable-symver \
    --disable-ffprobe \
    --disable-devices \
    --disable-avfilter \
    --disable-swscale \
    --disable-ffplay \
    --disable-ffserver \
    --disable-network \
        (many more ...)
    --enable-asm \
    $ADDITIONAL_CONFIGURE_FLAG

#make clean
make  -j4 install

$PREBUILT/bin/arm-eabi-ar d libavcodec/libavcodec.a inverse.o

$PREBUILT/bin/arm-eabi-ld -rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib  -soname libffmpeg.so -shared -nostdlib  -z,noexecstack -Bsymbolic --whole-archive --no-undefined -o $PREFIX/libffmpeg.so libavcodec/libavcodec.a libavformat/libavformat.a libavutil/libavutil.a  -lc -lm -lz -ldl -llog  --warn-once  --dynamic-linker=/system/bin/linker $PREBUILT/lib/gcc/arm-eabi/4.4.0/libgcc.a

}

#arm v5
CPU=armv5te
OPTIMIZE_CFLAGS="-marm -march=$CPU"
PREFIX=./android/$CPU 
ADDITIONAL_CONFIGURE_FLAG=
build_one

这是我的 android.mk:

LOCAL_PATH := $(call my-dir)

#declare the prebuilt library
include $(CLEAR_VARS)
LOCAL_MODULE := ffmpeg-prebuilt
LOCAL_SRC_FILES := $(LOCAL_PATH)/ffmpeg/android/armv5te/libffmpeg.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/ffmpeg/android/armv5te/include
LOCAL_PRELINK_MODULE := true 
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE    := audiocodec
LOCAL_SRC_FILES := ffmpeg_audio.cpp
LOCAL_SHARED_LIBRARY := libffmpeg
LOCAL_C_INCLUDES := $(LOCAL_PATH)/ffmpeg/android/armv5te/include
LOCAL_LDLIBS    := -llog -ljnigraphics -lz -lm $(LOCAL_PATH)/ffmpeg/android/armv5te/libffmpeg.so
include $(BUILD_SHARED_LIBRARY)

结果:

Compile++ thumb: audiocodec <= /cygdrive/c/Gabriel/Desenvolvimento/Workspace/FFM
PEG/jni/ffmpeg_audio.cpp
SharedLibrary  : libaudiocodec.so
/cygdrive/c/Gabriel/Desenvolvimento/Workspace/FFMPEG/obj/local/armeabi/objs/audi
ocodec/ffmpeg_audio.o: In function `Java_gabriel_audioslower_pro_ffmpegDecoder_r
eadSamples':
/cygdrive/c/Gabriel/Desenvolvimento/Workspace/FFMPEG/jni/ffmpeg_audio.cpp:172: u
ndefined reference to `avcodec_decode_audio3(AVCodecContext*, short*, int*, AVPa
cket*)'
/cygdrive/c/Gabriel/Desenvolvimento/Workspace/FFMPEG/jni/ffmpeg_audio.cpp:178: u
ndefined reference to `av_read_frame(AVFormatContext*, AVPacket*)'
/cygdrive/c/Gabriel/Desenvolvimento/Workspace/FFMPEG/obj/local/armeabi/objs/audi
ocodec/ffmpeg_audio.o: In function `Java_gabriel_audioslower_pro_ffmpegDecoder_s
eekToPosMS':
/cygdrive/c/Gabriel/Desenvolvimento/Workspace/FFMPEG/jni/ffmpeg_audio.cpp:147: u
ndefined reference to `av_rescale_q(long long, AVRational, AVRational)'
/cygdrive/c/Gabriel/Desenvolvimento/Workspace/FFMPEG/jni/ffmpeg_audio.cpp:150: u
ndefined reference to `av_seek_frame(AVFormatContext*, int, long long, int)'
/cygdrive/c/Gabriel/Desenvolvimento/Workspace/FFMPEG/jni/ffmpeg_audio.cpp:151: u
ndefined reference to `avcodec_flush_buffers(AVCodecContext*)'
/cygdrive/c/Gabriel/Desenvolvimento/Workspace/FFMPEG/jni/ffmpeg_audio.cpp:152: u
ndefined reference to `av_read_frame(AVFormatContext*, AVPacket*)'
/cygdrive/c/Gabriel/Desenvolvimento/Workspace/FFMPEG/obj/local/armeabi/objs/audi
ocodec/ffmpeg_audio.o: In function `Java_gabriel_audioslower_pro_ffmpegDecoder_c
loseFile':
/cygdrive/c/Gabriel/Desenvolvimento/Workspace/FFMPEG/jni/ffmpeg_audio.cpp:82: un
defined reference to `avcodec_close(AVCodecContext*)'
/cygdrive/c/Gabriel/Desenvolvimento/Workspace/FFMPEG/jni/ffmpeg_audio.cpp:83: un
defined reference to `av_free(void*)'
/cygdrive/c/Gabriel/Desenvolvimento/Workspace/FFMPEG/jni/ffmpeg_audio.cpp:84: un
defined reference to `av_close_input_file(AVFormatContext*)'
/cygdrive/c/Gabriel/Desenvolvimento/Workspace/FFMPEG/obj/local/armeabi/objs/audi
ocodec/ffmpeg_audio.o: In function `Java_gabriel_audioslower_pro_ffmpegDecoder_o
penAudioFile':
/cygdrive/c/Gabriel/Desenvolvimento/Workspace/FFMPEG/jni/ffmpeg_audio.cpp:37: un
defined reference to `av_open_input_file(AVFormatContext**, char const*, AVInput
Format*, int, AVFormatParameters*)'
/cygdrive/c/Gabriel/Desenvolvimento/Workspace/FFMPEG/jni/ffmpeg_audio.cpp:44: un
defined reference to `av_find_stream_info(AVFormatContext*)'
/cygdrive/c/Gabriel/Desenvolvimento/Workspace/FFMPEG/jni/ffmpeg_audio.cpp:52: un
defined reference to `avcodec_find_decoder(CodecID)'
/cygdrive/c/Gabriel/Desenvolvimento/Workspace/FFMPEG/jni/ffmpeg_audio.cpp:60: un
defined reference to `avcodec_open(AVCodecContext*, AVCodec*)'
/cygdrive/c/Gabriel/Desenvolvimento/Workspace/FFMPEG/jni/ffmpeg_audio.cpp:67: un
defined reference to `av_malloc(unsigned int)'
/cygdrive/c/Gabriel/Desenvolvimento/Workspace/FFMPEG/jni/ffmpeg_audio.cpp:70: un
defined reference to `av_read_frame(AVFormatContext*, AVPacket*)'
/cygdrive/c/Gabriel/Desenvolvimento/Workspace/FFMPEG/obj/local/armeabi/objs/audi
ocodec/ffmpeg_audio.o: In function `JNI_OnLoad':
/cygdrive/c/Gabriel/Desenvolvimento/Workspace/FFMPEG/jni/ffmpeg_audio.cpp:25: un
defined reference to `av_register_all()'
collect2: ld returned 1 exit status
make: *** [/cygdrive/c/Gabriel/Desenvolvimento/Workspace/FFMPEG/obj/local/armeab
i/libaudiocodec.so] Error 1

有趣的是,来自 ffmpeg 的一些函数,如 av_register_all(),现在确实显示在未定义引用列表中。

关于我可以做些什么来解决它的任何想法?我花了 3 天的时间试图让事情顺利进行.. 谢谢!

【问题讨论】:

    标签: android ffmpeg android-ndk


    【解决方案1】:

    尝试添加

    LOCAL_ALLOW_UNDEFINED_SYMBOLS := true
    

    到你的makefile。

    【讨论】:

      【解决方案2】:

      也许您忘记将 ffmpeg 标头包装为 C:

      extern "C"
      {
      #include "avcodec.h"
      }
      

      【讨论】:

      • 谢谢,你的帖子救了我!我相当确定所有库都从输出提供给链接器,并且包含路径设置正确,所以我束手无策。
      • 要是我早点看到这个就好了!谢谢!!
      猜你喜欢
      • 1970-01-01
      • 2013-01-16
      • 2014-01-10
      • 1970-01-01
      • 2012-02-10
      • 1970-01-01
      • 1970-01-01
      • 2017-03-17
      • 1970-01-01
      相关资源
      最近更新 更多