MAC平台编译ffmpeg生成so文件(总结遇到的问题)
16lz
2021-01-25
一、编译脚本
1. Arm平台编译脚本
ADDI_CFLAGS="-marm"API=26PLATFORM=arm-linux-androideabiCPU=armv7-aNDK=/Users/a360/Library/Android/sdk/ndk-bundle # 修改成自己本地的ndk路径。SYSROOT=$NDK/platforms/android-$API/arch-arm/ISYSROOT=$NDK/sysrootASM=$ISYSROOT/usr/include/$PLATFORMTOOLCHAIN=$NDK/toolchains/$PLATFORM-4.9/prebuilt/darwin-x86_64OUTPUT=/Users/a360/Android/Video/ffmpeg-4.0.3/android/arm-v7 #自己指定一个输出目录,用来放生成的文件的。function build {./configure \--prefix=$OUTPUT \--enable-shared \--disable-static \--disable-doc \--disable-ffmpeg \--disable-ffplay \--disable-ffprobe \--disable-avdevice \--disable-doc \--disable-symver \--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \--target-os=android \--arch=arm \--enable-cross-compile \--sysroot=$SYSROOT \--extra-cflags="-I$ASM -isysroot $ISYSROOT -Os -fpic -marm" \--extra-ldflags="-marm" \$ADDITIONAL_CONFIGURE_FLAGmake cleanmakemake install}build
2. x86平台编译脚本
API=26CPU=x86NDK=/Users/a360/Library/Android/sdk/ndk-bundle # 修改成自己本地的ndk路径。SYSROOT=$NDK/platforms/android-$API/arch-x86/ISYSROOT=$NDK/sysrootASM=$ISYSROOT/usr/include/x86_64-linux-androidTOOLCHAIN=$NDK/toolchains/x86-4.9/prebuilt/darwin-x86_64OUTPUT=/Users/a360/Android/Video/ffmpeg-4.0.3/android/$CPU #自己指定一个输出目录,用来放生成的文件的。function build {./configure \--prefix=$OUTPUT \--enable-shared \--disable-static \--disable-doc \--disable-ffmpeg \--disable-ffplay \--disable-ffprobe \--disable-avdevice \--disable-doc \--disable-symver \--cross-prefix=$TOOLCHAIN/bin/i686-linux-android- \--target-os=android \--arch=$CPU \--enable-cross-compile \--sysroot=$SYSROOT \--extra-cflags="-I$ASM -isysroot $ISYSROOT -Os -fpic " \$ADDITIONAL_CONFIGURE_FLAGmake cleanmake -j8make install}build
3. 编译成一个so文件
ADDI_CFLAGS="-marm"API=21PLATFORM=arm-linux-androideabiCPU=armv7-aNDK=/Users/a360/Library/Android/sdk/android-ndk-r14b # 修改成自己本地的ndk路径。SYSROOT=$NDK/platforms/android-$API/arch-arm/ISYSROOT=$NDK/sysrootASM=$ISYSROOT/usr/include/$PLATFORMTOOLCHAIN=$NDK/toolchains/$PLATFORM-4.9/prebuilt/darwin-x86_64PREFIX=./ff-onelib/$CPU #自己指定一个输出目录,用来放生成的文件的。function build {./configure \--prefix=$PREFIX \--enable-cross-compile \--enable-runtime-cpudetect \--arch=arm \--cc=$TOOLCHAIN/bin/arm-linux-androideabi-gcc \--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \--disable-stripping \--target-os=android \--enable-gpl --enable-static --disable-shared --enable-nonfree --enable-version3 --enable-small \--enable-neon --enable-mediacodec --enable-asm \--enable-zlib --disable-ffprobe --disable-ffplay --enable-ffmpeg --disable-debug \--enable-jni \--sysroot=$SYSROOT \--extra-cflags="-fpic -mfpu=neon -marm -march=armv7-a" \make cleanmake -j16make install}build$TOOLCHAIN/bin/arm-linux-androideabi-ld \-rpath-link=$SYSROOT/usr/lib \-L$SYSROOT/usr/lib \-soname libffmpeg.so \-shared -nostdlib \-Bsymbolic \--whole-archive --no-undefined \-o $PREFIX/libffmpeg.so \$PREFIX/lib/libavcodec.a \$PREFIX/lib/libavfilter.a \$PREFIX/lib/libswresample.a \$PREFIX/lib/libavformat.a \$PREFIX/lib/libavutil.a \$PREFIX/lib/libswscale.a \$PREFIX/lib/libpostproc.a \$PREFIX/lib/libavdevice.a \-lc -lm -lz -ldl -llog \$TOOLCHAIN/lib/gcc/arm-linux-androideabi/4.9.x/libgcc.a
二、遇到的问题总结
1. API设置为26时编译出来的so文件,在6.0及以上版本的手机上运行没有问题,6.0以下的版本就崩溃了,出现java.lang.UnsatisfiedLinkError
解决办法:编译so文件的时候要把API设置到23以下,这样才能兼容6.0以前到版本。原因是so库中需要符号stdout,stderr,而在"\ndk\platforms\android-23\arch-arm\usr\lib\libc.so"中,是可以查看到stdout这个符号的,但是在低于android-23版本的libc中是没有这个符号的,为了兼容低于android-23的系统,ndk编译的程序,需要设置API小于23
2. 设置为API小于23到时候,编译so库时出现了链接问题
cmdutils.o:cmdutils.c:function log_callback_help: error: undefined reference to 'stdout'ffmpeg_opt.o:ffmpeg_opt.c:function assert_file_overwrite: error: undefined reference to 'stderr'ffmpeg.o:ffmpeg.c:function check_keyboard_interaction: error: undefined reference to 'stderr'ffmpeg.o:ffmpeg.c:function print_sdp: error: undefined reference to 'stdout'ffmpeg.o:ffmpeg.c:function print_report.part.7: error: undefined reference to 'stderr'ffmpeg.o:ffmpeg.c:function main: error: undefined reference to 'stderr'libavfilter/libavfilter.a(vf_psnr.o):vf_psnr.c:function init: error: undefined reference to 'stdout'libavfilter/libavfilter.a(vf_psnr.o):vf_psnr.c:function uninit: error: undefined reference to 'stdout'
解决办法:编译时,NDK的版本要低于14,高于14的版本没有stdrr和stdout的定义
3. 当使用NDK14版本编译生成.a文件之后,合并成.so文件(只是在编译x86的时候遇到了),出现了/tmp/77a95b0085967f7191ad958665724b6f/sysroot/usr/include/unistd.h:173: error: undefined reference to '__page_size'的错误
解决办法:可能是NDK 14的问题,换一个平台合成就好了
更多相关文章
- 一款常用的 Squid 日志分析工具
- GitHub 标星 8K+!一款开源替代 ls 的工具你值得拥有!
- RHEL 6 下 DHCP+TFTP+FTP+PXE+Kickstart 实现无人值守安装
- Linux 环境下实战 Rsync 备份工具及配置 rsync+inotify 实时同步
- android 添加视频、图片、录音上传(一)
- [Unity][安卓]Unity和Android(安卓)Studio 3.0 交互通讯(1)Android
- Android(安卓)CircleMenu 圆形旋转菜单
- Android(安卓)GET,POST向服务器端发送数据(发送)
- Android(安卓)ColorStateList使用方法