操作系统: Mac OSX
NDK: android-ndk-r10e-darwin-x86_64
编译目标: librtmp.a librtmp.so
简介
Android 官方提供了三种编译方式,分别是 prebuild 工具,standalone toolchain 工具,ndk-build 工具。
prebuild 工具,是官方提供的预编译好的工具,使用时需要手动指定系统头文件和链接库文件;
standalone toolchain 工具,已经内置了系统头文件和链接库文件,并且提供一些高级用法;
ndk-build 工具,依赖于 GNU Make 的编译系统,使用时需要 Android.mk Application.mk 配合;
由于 librtmp 官方已经在源码中提供了 Makefile 编译脚本,替换脚本中的 GCC AR LD 变量是很方便的,因此我们选择使用 standalone toolchain 工具的方式来编译 librtmp 库。
简单的操作步骤如下:
安装NDK;
制作Standalone Toolchain;
编译librtmp库;
安装NDK
Android 官网提供的下载地址 Android NDK r10e (已失效)
百度云盘提供的下载镜像包 Android NDK r10e
如果是zip包,解压到任意位置即可;
如果是bin包,需要授予可执行权限,运行安装;
chmod a+x android-ndk-r10e-darwin-x86_64.bin ./android-ndk-r10e-darwin-x86_64.bin
|
关于如何使用 Standalone Toolchain 官网已经给出了详细的文档 Standalone Toolchain;
注: 如果你觉得英文比较难懂,可以查看我的中文翻译 Standalone Toolchain(中文翻译)
制作支持 arm, arm64, mips, mips64, x86, x86_64 六种架构的 Standalone Toolchain 工具,下面提供简单的一键生成脚本:build-toolchain.sh
注: 使用脚本前需要定义 $ANDROID_NDK 系统环境变量,指向上一步安装的NDK根目录。
#! /bin/sh
mkdir -p $HOME/Documents/app/Android-NDK-Toolchain/arm $ANDROID_NDK/build/tools/make-standalone-toolchain.sh --arch=arm --platform=android-21 --toolchain=arm-linux-androideabi-4.9 --system=darwin-x86_64 --install-dir=$HOME/Documents/app/Android-NDK-Toolchain/arm
mkdir -p $HOME/Documents/app/Android-NDK-Toolchain/arm64 $ANDROID_NDK/build/tools/make-standalone-toolchain.sh --arch=arm64 --platform=android-21 --toolchain=aarch64-linux-android-4.9 --system=darwin-x86_64 --install-dir=$HOME/Documents/app/Android-NDK-Toolchain/arm64
mkdir -p $HOME/Documents/app/Android-NDK-Toolchain/mips $ANDROID_NDK/build/tools/make-standalone-toolchain.sh --arch=mips --platform=android-21 --toolchain=mipsel-linux-android-4.9 --system=darwin-x86_64 --install-dir=$HOME/Documents/app/Android-NDK-Toolchain/mips
mkdir -p $HOME/Documents/app/Android-NDK-Toolchain/mips64 $ANDROID_NDK/build/tools/make-standalone-toolchain.sh --arch=mips64 --platform=android-21 --toolchain=mips64el-linux-android-4.9 --system=darwin-x86_64 --install-dir=$HOME/Documents/app/Android-NDK-Toolchain/mips64
mkdir -p $HOME/Documents/app/Android-NDK-Toolchain/x86_64 $ANDROID_NDK/build/tools/make-standalone-toolchain.sh --arch=x86_64 --platform=android-21 --toolchain=x86_64-4.9 --system=darwin-x86_64 --install-dir=$HOME/Documents/app/Android-NDK-Toolchain/x86_64
mkdir -p $HOME/Documents/app/Android-NDK-Toolchain/x86 $ANDROID_NDK/build/tools/make-standalone-toolchain.sh --arch=x86 --platform=android-21 --toolchain=x86-4.9 --system=darwin-x86_64 --install-dir=$HOME/Documents/app/Android-NDK-Toolchain/x86
echo ------------ echo now ndk toolchain at: $HOME/Documents/app/Android-NDK-Toolchain echo ------------
|
运行脚本后,默认生成的工具位于 $HOME/Documents/app/Android-NDK-Toolchain。
编译librtmp库
在开始之前,我们需要了解几个概念,编译librtmp库需要使用哪些编译工具,需要兼容哪些CPU架构,如何选择合适的ABI?
需要使用哪些编译工具?###
C/C++编译器 CC;
静态库打包工具 AR;
动态库链接工具 LD;
需要兼容哪些CPU架构?###
注: 这里挖了一个坑,等待有人来填~
如何选择合适的ABI?###
关于 Android 系统支持的 ABI 列表,官方已经给出了说明,Supported ABIs,这里我们只摘取其中有用的部分进行讲讲解:
ABI的定义主要是为了照顾不同指令集的兼容性,详细的对应关系如下:
armeabi 兼容 ARMV5TE,更高版本ARMV5,Thumb-1 指令集,不支持硬件 float 运算;
armeabi-v7a 兼容 armeabi,Thumb-2,VFPv3-D16,其他可选指令集,不兼容 ARMv5, ARMv6 设备;
arm64-v8a 兼容 AArch-64 指令集;
x86 兼容 x86 (IA-32),MMX,SSE,SSE2,SSE3,SSSE3 指令集,不支持 MOVBE,SSE4 指令集;
x86_64 兼容 x86-64,MMX,SSE,SSE2,SSE3,SSSE3,SSE4.1, SSE4.2,POPCNT 指令集;
mips 兼容 MIPS32r1,更高版本MIPS32 指令集,使用硬件float并指定CPU:FPU时钟比为2:1;不支持 micromips,MIPS16 指令集;
mips64 兼容 MIPS64r6 指令集;
弄清楚了上面这些内容后,我们开始配置相应的GCC选项来适配不同的CPU架构和指令集;
GNU GCC 官方提供的ARM架构可用选项 ARM Options
GNU GCC 官方提供的x86架构可用选项 x86 Options
GNU GCC 官方提供的MIPS架构可用选项 MIPS Options
整理后,
armeabi 选项 -march=armv5te -msoft-float
armeabi-v7a 选项 -march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=softfp -mthumb
arm64-v8a 选项 -march=armv8-a
x86 选项 -mtune=intel -m32 -mmmx -msse2 -msse3 -mssse3
x86_64 选项 -mtune=intel -m64 -mmmx -msse2 -msse3 -mssse3 -msse4.1 -msse4.2 -mpopcnt
mips 选项 -march=mips32 -mfp32 -msoft-float -mno-micromips
mips64 选项 -march=mips64r6
注: 由于MIPS未找到同时使用硬件float并指定CPU:FPU时钟比为2:1的设置方法,因此使用软件float代替。
改造Makefile
下面改造librtmp库自带的Makefile脚本来适配产生不同兼容性的库,
注释掉CC AR LD 改为使用系统环境变量,注释 CRYPTO 来禁用 SSL,为 CFLAGS 增加系统环境变量 $(ARCH_CFLAGS) 输入,
#CC=$(CROSS_COMPILE)gcc #LD=$(CROSS_COMPILE)ld #AR=$(CROSS_COMPILE)ar
#CRYPTO=OPENSSL
CFLAGS=-Wall $(ARCH_CFLAGS) $(XCFLAGS) $(INC) $(DEF) $(OPT) $(SO_DEF)
|
改造完成之后,就可以使用下面的命令来生成librtmp库了,
## armeabi-v7a export CC=$HOME/Documents/app/Android-NDK-Toolchain/arm/bin/arm-linux-androideabi-gcc export LD=$HOME/Documents/app/Android-NDK-Toolchain/arm/bin/arm-linux-androideabi-ld export AR=$HOME/Documents/app/Android-NDK-Toolchain/arm/bin/arm-linux-androideabi-ar export ARCH_CFLAGS=-march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=softfp -mthumb make all
## armeabi export CC=$HOME/Documents/app/Android-NDK-Toolchain/arm/bin/arm-linux-androideabi-gcc export LD=$HOME/Documents/app/Android-NDK-Toolchain/arm/bin/arm-linux-androideabi-ld export AR=$HOME/Documents/app/Android-NDK-Toolchain/arm/bin/arm-linux-androideabi-ar export ARCH_CFLAGS=-march=armv5te -msoft-float make all
## arm64-v8a export CC=$HOME/Documents/app/Android-NDK-Toolchain/arm64/bin/aarch64-linux-android-gcc export LD=$HOME/Documents/app/Android-NDK-Toolchain/arm64/bin/aarch64-linux-android-ld export AR=$HOME/Documents/app/Android-NDK-Toolchain/arm64/bin/aarch64-linux-android-ar export ARCH_CFLAGS=-march=armv8-a make all
## x86 export CC=$HOME/Documents/app/Android-NDK-Toolchain/x86/bin/i686-linux-android-gcc export LD=$HOME/Documents/app/Android-NDK-Toolchain/x86/bin/i686-linux-android-ld export AR=$HOME/Documents/app/Android-NDK-Toolchain/x86/bin/i686-linux-android-ar export ARCH_CFLAGS=-march=i686 -mtune=i686 -m32 -mmmx -msse2 -msse3 -mssse3 make all
## x86_64 export CC=$HOME/Documents/app/Android-NDK-Toolchain/x86_64/bin/x86_64-linux-android-gcc export LD=$HOME/Documents/app/Android-NDK-Toolchain/x86_64/bin/x86_64-linux-android-ld export AR=$HOME/Documents/app/Android-NDK-Toolchain/x86_64/bin/x86_64-linux-android-ar export ARCH_CFLAGS=-march=core-avx-i -mtune=core-avx-i -mx32 -mmmx -msse2 -msse3 -mssse3 -msse4.1 -msse4.2 -mpopcnt make all
## mips export CC=$HOME/Documents/app/Android-NDK-Toolchain/mips/bin/mipsel-linux-android-gcc export LD=$HOME/Documents/app/Android-NDK-Toolchain/mips/bin/mipsel-linux-android-ld export AR=$HOME/Documents/app/Android-NDK-Toolchain/mips/bin/mipsel-linux-android-ar export ARCH_CFLAGS=-march=mips32 -mfp32 -msoft-float make all
## mips64 export CC=$HOME/Documents/app/Android-NDK-Toolchain/mips64/bin/mips64el-linux-android-gcc export LD=$HOME/Documents/app/Android-NDK-Toolchain/mips64/bin/mips64el-linux-android-ld export AR=$HOME/Documents/app/Android-NDK-Toolchain/mips64/bin/mips64el-linux-android-ar export ARCH_CFLAGS=-march=mips64r6 make all
|
librtmp库适用范围
librtmp.a适用范围
Android 项目中,其他 so 动态链接库可以引入librtmp头文件,并链接librtmp.a;
librtmp.so适用范围
Android 项目中,其他 so 动态链接库可以链接librtmp.so;
注: 由于这种编译方法并未引入 jni.h 头文件,也未定义 java native method 方法,因此并不能在 JAVA 层直接调用;
参考
Standalone Toolchain
Standalone Toolchain(中文翻译)
Supported ABIs
GNU GCC ARM Options
GNU GCC x86 Options
GNU GCC MIPS Options
List of CPU architectures
ARM Thumb Thumb-2指令集