背景:我们经常在ndk开发中会使用到第三方库,例如ffmpeg、libjpeg等等第三方开源库来完成我们的项目需求,这时候通常我们需要提前将第三方库编译成动态库或者静态库来使用,这时候交叉编译就派上用场了。
对于交叉编译等还没有概念的同学请自行google了解一下先,否则接下来可能会一头雾水。简单说交叉编译就是在A平台下编译B平台上可以使用的二进制库文件。
环境
操作系统:mac os 10.13.5
ndk版本:android-ndk-r10d
编译器:clang
环境注意事项
- 在mac中gcc默认链接到自家的llvm,并不是真正的gcc,例如我们查看一下gcc的版本号
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 9.1.0 (clang-902.0.39.2)
Target: x86_64-apple-darwin17.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
当然用过的人都知道clang+llvm比gcc好用不要太多,这里我们也不去切换成gcc编译,如果有需要的同学,请参考将Mac OS系统的C、C++编译器从默认的Clang切换到 GCC
- 我们这里选用了android-ndk-r10d的ndk开发包,虽然历史比较久,但是也是可以用的,这里没有特别的版本要求,可以自行切换到其他版本的开发包上。
选择工具链
我们知道android平台目前的架构有armeabi
、armeabi-v7a
、arm64-v8a
、x86
、x86_64
、mips
,在编译不同平台架构的库时,我们需要指定不同的交叉编译链来完成编译的工作。
这里具体对应工具链的地址是在android-ndk-r10d/toolchains
目录中
制作工具链
NDK提供make-standalone-toolchain.sh shell脚本以允许我们从命令行执行定制的工具链安装,脚本位于$NDK/build/tools/
目录中,其中$NDK
是NDK的安装根目录,本文中也就是android-ndk-r10d
目录,自行编写一个脚本
#!/bin/sh
export DEV=${HOME}/Library/Android/sdk
export NDK_HOME=${DEV}/android-ndk-r10d
platform=android-21
shmake=$NDK_HOME/build/tools/make-standalone-toolchain.sh
archs=(
'arm'
'arm64'
'x86'
'x86_64'
'mips'
'mips64'
)
toolchains=(
'arm-linux-androideabi-4.9'
'aarch64-linux-android-4.9'
'x86-4.9'
'x86_64-4.9'
'mipsel-linux-android-4.9'
'mips64el-linux-android-4.9'
)
echo $NDK_HOME
num=${#archs[@]}
for ((i=0;i<$num;i++))
do
sh $shmake --arch=${archs[i]} --platform=$platform --install-dir=$HOME/Chain/android-toolchain/${archs[i]} --toolchain=${toolchains[i]}
done
ssmake命令介绍:
--arch 架构名称
--platform 目标api
--install-dir 工具链生成位置
--toolchain 默认情况下,构建系统使用32位、基于ARM的 GCC 4.8工具链,这里我们统一修改为4.9版本
最后把这个脚本保存为make_toolchain.sh
,运行该脚本后,会在--install-dir
的制定目录下生成对应的工具链文件夹
总结
这里我们就将各个架构平台下的交叉编译工具链做好了,下篇文章会讲一下如何利用这几个工具链来编译第三方库。