【发布时间】:2017-07-17 08:45:04
【问题描述】:
我一直在尝试将 ffmpeg 编译成一个静态库,以便在我的 android 应用程序中使用它,但我无法让它工作。
我正在使用 FFmpeg 3.2.4 和 ndk r13b,在 Windows 10(Ubuntu 14.04)上使用 bash。
这是我所做的:
我为 x86_64 和 api 21 制作了一个独立的工具链,使用:
python make_standalone_toolchain.py --api 21 --arch x86_64 --install-dir {}-
做了一个配置脚本:
./configure \ --target-os=android \ --arch=x86_64 \ --prefix=/home/david/ffmpeg_x86_64_build \ --cross-prefix=/home/david/x86_64_toolchain/bin/x86_64-linux-android-\ --sysroot=/home/david/x86_64_toolchain/sysroot \ --enable-cross-compile \ --pkg-config-flags="--static" \ --enable-ffmpeg \ --disable-ffplay \ --disable-ffprobe \ --disable-ffserver \ --disable-doc \ --disable-htmlpages \ --disable-manpages \ --disable-podpages \ --disable-txtpages \ --extra-cflags="-fPIC" \ --extra-cxxflags="-fPIC" --disable-shared --enable-static \ --enable-yasm make make install
它生成了一个 FFmpeg 可执行文件,但是当我在我的 API 23 模拟器上运行它时,我收到一条错误消息:error: only position independent executables (PIE) are supported.
即使我使用了-fPic
我该如何解决?另外我不确定我的配置,没有关于如何为我的应用程序需要的每个 ABI(arm、arm64、x86、x86_64、mips、mips64)正确编译它的最新资源。 我看过很多脚本,我对编译原生代码不太熟悉,所以我不确定我需要什么设置,例如 C 标志等。
准确地说我是如何尝试配置 FFmpeg 的:
- 我需要一个静态库
- 我只需要 ffmpeg 命令行实用程序
- 我想为上面列出的每个 ABI 编译库。此配置尝试为 x86_64 编译。
- 当然是在安卓上运行
非常感谢有关如何正确配置和编译它的帮助。
编辑
感谢@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 的头文件,并且它应该在这里链接到这个库。
但如 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 的设置,但我不知道如何正确配置它。
【问题讨论】:
-
日志提示ffmpeg正在寻找libssl,但是你找到的GitHub项目只包含libcrypto。你可以试试github.com/emileb/OpenSSL-for-Android-Prebuilt。
-
-lws2_32 -lgdi32看起来更糟:这些是 Windows 库,我不知道它们是如何到达您的配置的。也许这是一个虚惊,他们会被忽略,我不能告诉 -
是的,成功了,当我使用该库时,我能够编译,只是删除了 .so 文件(它会默认为它们)。非常感谢,我已经坐了很久了。最后一件事,我在 x86 版本上添加了
--disable-asm标志来修复文本重定位。 -
使用预建的 openssl 有点违背了这个库的目的。它有望为您的应用程序提供安全性;来自您无法 100% 信任的来源的二进制文件可能会带来极大的不安全感。
-
我将从源代码编译 openssl 以供生产使用,这只是我自己的试验。谢谢您的警告。
标签: android ffmpeg android-ndk openssl configure