NDK即要支持交叉編譯,還需要支持各個Android版本的編譯,還有一些其他情況的編譯,比如c和c++等。NDK提供了一些編譯選項,用來支持不同的編譯需求。
以前的NDK開發都是在Android.mk
和Appliction.mk
中設置,現在在gradle-experimental
的android.ndk{}
設置編譯選項。
其中包含了設置:編譯器配置,NDK版本,Header頭文件位置,gcc編譯器選項等...
下面介紹下幾個常用的編譯選項。
platformVersion
大部分的App需要向下兼容,會設置minSdkVersion
,從一個低版本的Sdk開始支持。同樣的在低SDK版本上面運行的NDK也必須使用對應的NDK,就需要設置platformVersion
。
設置minSdkVersion
為14,對應的也需要設置platformVersion
也是14:
model{
android{
ndk{
....
platfromVersion=14
}
}
}
也可以使用paltformVersion "android-14"
設置NDK的版本。
toolchain
toolchain
是NDK下的一套文件系統和工具鏈,主要有GCC,編譯adnroid的庫和工具等,是本機編譯工具或交叉編譯工具。
在gradle中直接指定toolchain
和toolchainVersion
:
model {
android {
......
ndk {
......
toolchain "clang"
toolchainVersion "3.5"
}
......
}
}
ABI
Android系統目前支持其中七種不同的CPU架構:ARMv5,ARMv7,x86,MIPS,ARMv8,MIP64,x86_64,每一種都關聯著一個相應的ABI。
Application Binary interface
應用程序二進制接口,定義了二進制文件(尤其是.so文件)是如何運行在相應的系統平臺上的,從使用的指令集,內存到對齊到可用的系統函數庫。在Android系統上,每一CPU架構對應一個ABI。
對應的.so文件會放在對應的ABI文件下面:
一般情況下,考慮到x86系統的市場份額還太小,還有為了減少apk包的大小,可以指定支持的平臺,使用abiFilters
,可以選擇項目支持的平臺,比如只支持armabi
和armeabi-v7a
的配置:
...
ndk {
...
abiFilters.addAll(['armabi', 'armeabi-v7a'])
...
}
...
ldLibs
使用NDK開發Android應用時,會使用到系統自帶的庫,在之前的*.mk
中的LOCAL_LDLIBS
就是用來引用系統庫的,現在使用在Android studio
中可以配置ldLibs
引用系統庫。
例如在項目中鏈接android的log
:
ndk {
...
ldLibs.addAll(['log'])
}
CFlags和CppFlags
CFlag表示用于C編譯器的選項。
CppFlags用來表示用于c++的編譯器選項.
使用ldLibs告訴了鏈接器要鏈接那些庫文件,而在CFlags和CppFlags可以用來指定.h文件的路徑。
例如指定一個.h文件的目錄:
ndk {
...
CFlags.addAll(['-I/usr/local/ssl/android-14/include'])
...
}
CFlag
也是gcc的編譯選項,比如使用-Wall
表示打開警告開發,-g
是要生成調試信用,生成的可執行文件具有和源代碼關聯的可調試信息。
stl
stl是設置c++的運行時庫的選項,默認使用的是libstdc++
最小支持的c++庫。
如果要使用gnustl_static
(靜態鏈接gnustl版本的stl)可以設置為:
ndk {
...
stl = 'gnustl_static'
cppFlags.addAll(['-std=c++11'])
...
}
在這里可以看到NDK支持的對應的c++運行庫,建議使用動態方法鏈接stl,這樣可以減少apk的大小。