使用带有 openssl 的 NDK 静态编译 FFmpeg

Compiling FFmpeg staticly using NDK with openssl

我一直在尝试将 ffmpeg 编译成静态库以便在我的 android 应用程序中使用它,但我无法让它工作。

我正在使用 FFmpeg 3.2.4 和 ndk r13b,在 windows 10(Ubuntu 14.04).

上使用 bash

这是我所做的:

它生成了一个 FFmpeg 可执行文件,但是当我 运行 它在我的 API 23 模拟器上时,我收到一条错误消息:error: only position independent executables (PIE) are supported. 即使我使用了 -fPic

我该如何解决?我也不确定我的配置,没有关于如何为我的应用程序所需的每个 ABI(arm、arm64、x86、x86_64、mips、mips64)正确编译它的最新资源. 我看过很多脚本,我不太熟悉编译本机代码,所以我不确定我需要什么设置,例如 C 标志等。

准确地说我是如何尝试配置 FFmpeg 的:

对于如何正确配置和编译它的一些帮助,我将不胜感激。

编辑

感谢@Alex Cohn,我已经能够编译 ffmpeg,但是我无法使用 --enable-ssl 编译它,但是我遇到了一个问题。

由于我们提供了一个系统根目录,编译器不会在我的主机上寻找文件,因此我们需要从源代码为 android 编译 ssl。 我用过这个库OpenSSL-For-Android,用过预编译库

我在配置文件中添加了这些行:

--extra-cflags='-m32  -fPIE -I./OpenSSL-For-Android/openssl-1.0.2j/include' \
--extra-ldflags='-m32 -Wl,-eh-frame-hdr -Wl,-m,elf_i386 -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now  -fPIE -pie -L./OpenSSL-For-Android/openssl-1.0.2j/lib/x86'

我试着告诉配置,它应该在这里搜索 openssl 的 headers,并且它应该在这里 link 针对这个库。

但是如 config.log 所述,它在这个测试中失败了:

BEGIN /tmp/ffconf.JVeoLDmr.c
    1   extern int SSL_library_init();
    2   int main(void){ SSL_library_init(); }
END /tmp/ffconf.JVeoLDmr.c
/home/david/ndk/toolchains/x86-4.9/prebuilt/linux-x86_64/bin/i686-linux-android-gcc --sysroot=/home/david/ndk/platforms/android-9/arch-x86/ -isysroot /home/david/ndk/platforms/android-9/arch-x86/ -D_ISOC99_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -Dstrtod=avpriv_strtod -DPIC -m32 -fPIE -I./OpenSSL-For-Android/openssl-1.0.2j/include -std=c99 -fomit-frame-pointer -fPIC -pthread -c -o /tmp/ffconf.x5yr8e11.o /tmp/ffconf.JVeoLDmr.c
/home/david/ndk/toolchains/x86-4.9/prebuilt/linux-x86_64/bin/i686-linux-android-gcc -m32 -Wl,-eh-frame-hdr -Wl,-m,elf_i386 -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -fPIE -pie -L./OpenSSL-For-Android/openssl-1.0.2j/lib/x86 --sysroot=/home/david/ndk/platforms/android-9/arch-x86/ -isysroot /home/david/ndk/platforms/android-9/arch-x86/ -Wl,--as-needed -Wl,-z,noexecstack -o /tmp/ffconf.mxzx6kFL /tmp/ffconf.x5yr8e11.o -lssl -lcrypto -lws2_32 -lgdi32 -lm -pthread
/home/david/ndk/toolchains/x86-4.9/prebuilt/linux-x86_64/bin/../lib/gcc/i686-linux-android/4.9.x/../../../../i686-linux-android/bin/ld: error: cannot find -lssl
/home/david/ndk/toolchains/x86-4.9/prebuilt/linux-x86_64/bin/../lib/gcc/i686-linux-android/4.9.x/../../../../i686-linux-android/bin/ld: error: cannot find -lws2_32
/home/david/ndk/toolchains/x86-4.9/prebuilt/linux-x86_64/bin/../lib/gcc/i686-linux-android/4.9.x/../../../../i686-linux-android/bin/ld: error: cannot find -lgdi32
/tmp/ffconf.x5yr8e11.o:ffconf.JVeoLDmr.c:function main: error: undefined reference to 'SSL_library_init' 

它似乎没有使用我传递给它的预编译共享库(因为它是为 Android 编译的)并且没有找到 openssl 的另一个实例,因为 sysroot 是 Android AOSP 一个(这是我的想法,如果我错了请纠正我 - 我在这个领域经验不足)。 这怎么能解决?我看过一些 PKG-Config 的设置,但我不知道如何正确配置它。

为 armeabi-v7a 尝试此命令行:

../../ffmpeg/configure --target-os=linux --enable-cross-compile \
  --enable-pthreads --enable-small \
  --arch=arm --enable-armv6 --enable-armv6t2 --enable-vfp \
  --enable-armv5te --enable-inline-asm \
  --enable-neon --enable-thumb --enable-fast-unaligned --enable-runtime-cpudetect \
  --cross-prefix=%NDK_ROOT%/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64/bin/arm-linux-androideabi- \
  --sysroot=%NDK_ROOT%/platforms/android-9/arch-arm/ \
  --disable-everything --disable-doc --disable-shared --disable-avdevice \
  --disable-postproc --disable-network --disable-iconv --disable-zlib --disable-ffplay --disable-ffprobe --disable-ffserver --disable-swscale-alpha \
  --enable-demuxer='h264,matroska,mpegts,rawvideo,mpegps,yuv4mpegpipe,flv,mov,mpegvideo,nut,avi' \
  --enable-filter='scale,fps,framestep,pad,crop' --enable-protocol='file,pipe' \
  --enable-muxer='h264,rawvideo,yuv4mpegpipe,matroska,mpegts,mp4,mov,nut,avi' \
  --enable-bsf=h264_mp4toannexb --enable-parser=mpeg4video \
  --enable-encoder=rawvideo --enable-decoder=rawvideo \
  --extra-cflags='-march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=softfp -fPIE' \
  --extra-ldflags='-fPIE -pie'

这是 x86 的:

../../ffmpeg/configure --target-os=linux --enable-cross-compile \
  --enable-pthreads --enable-small \
  --arch=x86 --enable-runtime-cpudetect --enable-yasm \
  --cross-prefix=%NDK_ROOT%/toolchains/x86-4.9/prebuilt/windows-x86_64/bin/i686-linux-android- \
  --sysroot=%NDK_ROOT%/platforms/android-9/arch-x86/ \
  --disable-everything --disable-doc --disable-shared --disable-avdevice \
  --disable-postproc --disable-network --disable-iconv --disable-zlib --disable-ffplay --disable-ffprobe --disable-ffserver --disable-swscale-alpha \
  --enable-demuxer='h264,matroska,mpegts,rawvideo,mpegps,yuv4mpegpipe,flv,mov,mpegvideo,nut,avi' \
  --enable-filter='scale,fps,framestep,pad,crop' --enable-protocol='file,pipe' \
  --enable-muxer='h264,rawvideo,yuv4mpegpipe,matroska,mpegts,mp4,mov,nut,avi' \
  --enable-bsf=h264_mp4toannexb --enable-parser=mpeg4video \
  --enable-encoder=rawvideo --enable-decoder=rawvideo \
  --extra-cflags='-m32  -fPIE' \
  --extra-ldflags='-m32 -Wl,-eh-frame-hdr -Wl,-m,elf_i386 -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now  -fPIE -pie'

我更喜欢 运行 configure 不是来自 ffmpeg 目录,而是来自 obj/local/armeabi-v7aobj/local/x86 - 这样我可以将目标文件保存在单独的目录中,并且可以 make 用于不同的 ABI 而无需 运行ning ./configure 再次。我这里不需要 NDK 独立工具链。

您需要 yasm 才能针对 x86 进行编译。 --enable- 标志集适合我当前的需要,不一定适合您的需要。