Android Studio gradle 檔案中配置 cmake,及各 arguments 詳解

NO IMAGE

一、簡介

    在 Android Studio 2.2 以上的版本,推薦使用 CMake 來編譯工程裡的 C/C 程式碼(包括 JNI 部分)。
    一般來言,我們只需要關注和編寫 CMakeLists.txt 即可,至於 CMake 如何編譯,以及使用的什麼樣的配置選項是不怎麼關心的(會有一系列預設的配置)。不過,如果你需要更改或者定製化一些編譯的選項,你就需要了解一下如果在 gradle 中配置這些資訊了。

 

二、如何在 gradle 中使用 cmake 的變數

android {
...
defaultConfig {
...
externalNativeBuild {
cmake {
cppFlags "-frtti -fexceptions" // 通常不在這裡配置 cppFlags 了
...
// 使用下面這種語法向變數傳遞引數:
// arguments "-D變數名=引數".
arguments "-DANDROID_ARM_NEON=TRUE",
// 使用下面這種語法向變數傳遞多個引數(引數之間使用空格隔開):
// arguments "-D變數名=引數1 引數2"
"-DANDROID_CPP_FEATURES=rtti exceptions"
}
}
}
buildTypes {...}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
}

在 Module 級別的 build.gradle 檔案中,使用類似上述 cmake 塊中形式配置相關引數。

 

三、CMake 編譯 NDK 所支援的變數配置

變數名引數描述
ANDROID_TOOLCHAINclang (default)
gcc (deprecated)

指定 Cmake 編譯所使用的工具鏈。

使用示例:arguments “-DANDROID_TOOLCHAIN=clang”

ANDROID_PLATFORMAPI版本

指定 NDK 所用的安卓平臺的版本是多少。

使用示例:arguments “-DANDROID_PLATFORM=android-21”

ANDROID_STL

gnustl_static(default)

詳細見附表(C 庫支援)

指定 Cmake 編譯所使用的標準模版庫。

使用示例:arguments “-DANDROID_STL=gnustl_static”

ANDROID_PIEON (android-16 以上預設為 ON)
OFF (android-15 以下預設為 OFF)

使得編譯的 elf 檔案可以載入到記憶體中的任意位置就叫 pie(position independent executables)。
出於安全保護,在 Android 4.4 之後可執行檔案必須是採用PIE編譯的。

使用示例:arguments “-DANDROID_PIE=ON”

ANDROID_CPP_FEATURES空(default)
rtti(支援 RTTI)
exceptions(支援 C  異常)

指定是否需要支援 RTTI(RunTime Type Information)和 C  的異常,預設為空。

使用示例:arguments “-DANDROID_CPP_FEATURES=rtti exceptions”

ANDROID_ALLOW_UNDEFINED_SYMBOLSTRUE
FALSE(default)

指定在編譯時,如果遇到未定義的引用時是否丟擲錯誤。如果要允許這些型別的錯誤,請將該變數設定為 TRUE。

使用示例:arguments “-DANDROID_ALLOW_UNDEFINED_SYMBOLS=TRUE”

ANDROID_ARM_MODEarm
thumb (default)

如果是 thumb 模式,每條指令的寬度是 16 位,如果是 arm 模式,每條指令的寬度是 32 位。

使用示例:arguments “-DANDROID_ARM_MODE=arm”

ANDROID_ARM_NEONTRUE
FALSE(default)

指定在編譯時,是否使用 NEON 對程式碼進行優化。NEON 只適用於 armeabi-v7a 和 x86 ABI,且並非所有基於 ARMv7 的 Android 裝置都支援 NEON,但支援的裝置可能會因其支援標量/向量指令而明顯受益。
更多參考:https://developer.android.com/ndk/guides/cpu-arm-neon#rd

使用示例:arguments “-DANDROID_ARM_NEON=TRUE”

ANDROID_DISABLE_NO_EXECUTETRUE
FALSE(default)

指定在編譯時是否啟動 NX(No eXecute)。NX 是一種應用於 CPU 的技術,幫助防止大多數惡意程式的攻擊。如果要禁用 NX,請將該變數設定為 TRUE。

使用示例:arguments “-DANDROID_DISABLE_NO_EXECUTE=TRUE”

ANDROID_DISABLE_RELROTRUE
FALSE(default)

RELocation Read-Only (RELRO) 重定位只讀,它能夠保護庫函式的呼叫不受攻擊者重定向的影響。如果要禁用 RELRO,請將該變數設定為 TRUE。

使用示例:arguments “-DANDROID_DISABLE_RELRO=FALSE”

ANDROID_DISABLE_FORMAT_STRING_CHECKSTRUE
FALSE(default)

在類似 printf 的方法中使用非常量格式字串時是否丟擲錯誤。如果為 TRUE,即不檢查字串格式。

使用示例:arguments “-DANDROID_DISABLE_FORMAT_STRING_CHECKS=FALSE”

 

四、附表(C 庫支援)

名稱說明功能
libstdc 預設最小系統 C  執行時庫 不適用
gabi _static GAbi  執行時(靜態)。 C  異常和 RTTI
gabi _shared GAbi  執行時(共享)。 C  異常和 RTTI
stlport_static STLport 執行時(靜態)。 C  異常和 RTTI;標準庫
stlport_shared STLport 執行時(共享)。 C  異常和 RTTI;標準庫
gnustl_static GNU STL(靜態)。 C  異常和 RTTI;標準庫
gnustl_shared GNU STL(共享)。 C  異常和 RTTI;標準庫
c _static LLVM libc  執行時(靜態)。 C  異常和 RTTI;標準庫
c _shared LLVM libc  執行時(共享)。 C  異常和 RTTI;標準庫
參考:https://developer.android.com/ndk/guides/cpp-support#system

其它:

​NDK 學習系列:Android NDK 從入門到精通(彙總篇)