Shell脚本-动手编译FFmpeg
1.Cmake交叉编译Android动态库
交叉编译:Linux上编译Android的so
ndk 16的以上版本自带交叉编译工具链
cmake -DANDROID_NDK=${NDK_PATH} \ # ndk的安装目录(空格 \回车,相当于所有命令弄到同一行)
-DCMAKE_TOOLCHAIN_FILE=${NDK_PATH}/build/cmake/android.toolchain.cmake \ # cmake 交叉编译工具链
-DANDROID_ABI="armeabi-v7a" \ # 指定CPU
-DANDROID_NATIVE_API_LEVEL=19 \ # 指定最低版本
..
2.配置NDK环境
在NDKr17以后,NDK 不再支持32位和64位 MIPS 和ARM v5(armeabi)
所以现在NDK中只支持armeabi-v7a,armeabi-v8a,x86,x86_64四类
注意如果是虚拟机的linux系统 需要把要拷贝的文件放到桌面,然后通过ctrl+c复制,最后在虚拟机上 ctrl+v复制
- 下载NDK
- 将下载好的linux系统的ndk,
拷贝
到linux系统的/lib
目录下新建的ndk目录
并解压
,需要root权限 - 配置环境变量
配置环境变量: 配置环境变量 vim /etc/profile 文件最后面输入: export NDK_PATH=/lib/ndk/android-ndk-r21b export PATH=$NDK_PATH:$PATH 使环境变量生效 source /etc/profile
2.1 NDK中交叉编译工具的变化
在ndkr17c 以后默认使用的变成了clang
,而不是gcc
2.1.1. 交叉编译工具位置的变化:
在 NDK r19以前的 ndk 内置了一个可以自动生成交叉编译工具(toolchain) 的.py文件,放在
ndk路径下面的build/tool/make_standalone_toolchain.py
要生成toolchain,使用下面的命令
$NDK_HOME/build/tools/make_standalone_toolchain.py --arch arm --api 21 --install-dir /Users/fczhao/Desktop
后面的几个都是必要的
--arch 指定了生成的toolchain要在哪个CPU框架中使用
--api 指定了生成的toolchain要在哪个Android API 中使用
--install-dir 生成的toolchain的路径
但是NDK r19以后的NDK已经内置了这些文件,如果运行上面的命令,会出现这样的日志
WARNING:__main__:make_standalone_toolchain.py is no longer necessary. The
#$NDK/toolchains/llvm/prebuilt/darwin-x86_64/bin 这个路径已经有了我们要生成的文件
$NDK/toolchains/llvm/prebuilt/darwin-x86_64/bin directory contains target-specific scripts that perform
the same task. For example, instead of:
$ python $NDK/build/tools/make_standalone_toolchain.py \
--arch arm --api 21 --install-dir toolchain
$ toolchain/bin/clang++ src.cpp
Instead use:
$ $NDK/toolchains/llvm/prebuilt/darwin-x86_64/bin/armv7a-linux-androideabi21-clang++ src.cpp
Installation directory already exists. Use --force.
3.手写FFmpeg编译脚本
关于版本问题:学习尽量使用最新的版本(api过时,api改进),开发尽量使用大众的版本(方便查询解决问题)版本3.3.9
第三方库编译的通用思想:
- 首先先看下
README.md
文件 - 编译项目(动静态库)需要 Makefile 管理,如果
已经有写好的Makefile可以尝试着用make命令去编译
,如果没有需要自己写Makefile
或者采用cmake
构建 - 如果Makefile报错需要解决,一般情况下都是Makefile的一些配置文件没生成,所以一般需要先运行
configure
文件 - 生成配置文件之后,再次运行make,但是编译后的文件(elf,so,a)只能在当前类型系统上运行。如果需要跑到android或ios那么需要
交叉编译
。因此我们一般都需要往configure文件里面传一些交叉编译参数
./configure --help > help.txt
:将configure 的帮助说明写到help.txt
中去
NDKr16以上的版本NDKr19
以下需要我们自己去生成android版本的交叉编译链 ,NDKr19以上不需要
1. 创建目录 /lib/ndk/android-ndk-r21b/android-toolchains/android-19/arch-arm
2. 进入 /lib/ndk/android-ndk-r21b/build/tools 目录下
3. 执行命令:
sudo ./make_standalone_toolchain.py --arch arm --api 19 --install-dir /lib/ndk/android-ndk-r16b/android-toolchains/android-19/arch-arm
如果出现 Installation directory already exists. Use --force.
在上条命令最后面加上 --force就行
ndk-r16b和ffmpeg3.3.9
的脚本文件请查看ffmpeg_build_r16b.sh,还需要注意修改configure里生成文件名的方式:
按 esc 键输入 /build setting 查找
# SLIBNAME_WITH_MAJOR='$(SLIBNAME).$(LIBMAJOR)'
# LIB_INSTALL_EXTRA_CMD='$$(RANLIB) "$(LIBDIR)/$(LIBNAME)"'
# SLIB_INSTALL_NAME='$(SLIBNAME_WITH_VERSION)'
# SLIB_INSTALL_LINKS='$(SLIBNAME_WITH_MAJOR) $(SLIBNAME)'
# 替换成如下
SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)'
LIB_INSTALL_EXTRA_CMD='$$(RANLIB)"$(LIBDIR)/$(LIBNAME)"'
SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)'
SLIB_INSTALL_LINKS='$(SLIBNAME)'
ndk-r16b和ffmpeg3.3.9
的脚本文件请查看ffmpeg_build_r21b.sh
4.编译遇到的问题
clang is unable to create an executable file. C compiler test failed.
C compiler test failed.
If you think configure made a mistake, make sure you are using the latest
version from Git. If the latest version fails, report the problem to the
ffmpeg-user@ffmpeg.org mailing list or IRC #ffmpeg on irc.freenode.net.
Include the log file "config.log" produced by configure as this will help
solving the problem.
当遇到这个问题的时候
大部分是NDK支持平台错了
sudo uname --m
如果显示i686,你安装的是32位操作系统
如果显示 x86_64,你安装的是64位操作系统
下载的时候按下面
android-ndk64-r10b-linux-x86.tar
支持的是32位操作系统
android-ndk64-r10b-linux-x86_64.tar.bz2
支持的是64位操作系统
5.如何适配so框架
目前支持有不同的 7 中 cpu 的架构,ARMv5
,ARMv7(2010年)
,ARMv8
,x86(2011年)
,mips(2012年)
,mip64
,x86_64
。
每一种架构都关联着一种ABI
。 现在一般只需要arm架构就行
armv5,armv7(32位),armv8(64位):高版本会兼容低版本的,因此只需要放一个低版本的就可以了,armeabi或者armeabi-v7a(现在一般都是v7a,AS上只支持v7以上的,AS4.1提示后面上架到google play 的应用都需要支持64位的)
armeabi:v5因为比较旧,因此早期缺少浮点计算的硬件支持,在需要大量计算是有一定的性能影响。