Android NDK中的c++ STL

田海立@CSDN 2020-11-25html

Android NDK(Native Development Kit)提供了一套基於c/c++開發Android應用的工具。基於c/c++開發須要STL (Standard Template Library/標準模版庫),本文描述Android NDK中提供的STL。android

  1. Android NDK開發是基於Android的,可是不綁定具體某一個Android版本,一個NDK發佈版能夠支持多個Android版本。
  2. NDK開發不管靜態庫仍是動態庫,libc++都是用NDK裏的發佈版本打包在應用裏:動態庫直接在apk裏帶上libc++_shared.so;靜態庫已經把程序須要的STL的代碼直接打到應用程序或其所用的native庫裏。

 

1、Android NDK中的c++運行庫

Android NDK中提供下列c++運行庫。c++

其中的各個運行庫:bash

  • libc++:是LLVM c++標準庫。從NDK r18以後是惟一的STL(GNU stl和stlport從 r18開始從NDK中被移除)
    NDK裏提供了libc++的動態庫和靜態庫:
        - 動態庫: libc++_shared.so
        - 靜態庫: libc++_static.a
    注意: 雖然都是LLVM的c++ STL,此處NDK裏的libc++不是Android源碼中編譯出的c++系統STL(libc++.so),此處的libc++是基於NDK開發時,NDK中已經編譯好的庫。若是NDK開發的應用用到libc++_shared.so, .so會被打包到編譯出的APK裏;用到libc++_static.a, .a裏被用到的程序會被打到使用者的程序中的。也就是發佈應用時,會帶着stl一塊兒發佈,不依賴Android版本內部的stl。



  • system:非徹底stl,徹底stl需使用上面的libc++。這是與Android發佈綁定的庫
    System運行庫指的是Android版本里的/system/lib/libstdc++.so,提供基本的c++運行支持, 提供new/delete支持,僅提供c標準庫的c++封裝,好比<cstdio>。
    也不提供Exception Handling和RTTI支持。

  • none:沒有標準庫支持。

】以上是Android NDK r18以後的c++運行庫。在以前的NDK中還提供了gnustl,是GNU的c++ STL,一樣包含了動態庫"gnustl_shared"(libgnustl_shared.so)以及靜態庫"gnustl_static"(libgnustl_static.a)支持。在那些版本的NDK裏有多於一種的真正徹底STL可供選擇。ide

 

2、NDK開發時選擇STL

NDK開發時,能夠用下面方式指定c++運行庫。工具

運行庫在「c++_shared」,「c++_static」,「none」或「system」中選擇其一,其中c++_shared」,「c++_static」分別對應libc++的動態庫和靜態庫。gradle

2.1 cmake編譯指定STL

不經過ANDROID_STL指定STL的狀況下缺省是c++_static。ui

能夠在Module級別的build.gradle文件中經過變量ANDROID_STL變量指定一個運行庫:「c++_shared」,「c++_static」,「none」或「system」中選擇其一。google

ANDROID_STL
  可選:none / system / c++_static / c++_shared
  若是未設置,默認爲c++_static

2.2 ndk-build裏指定STL

不經過APP_STL指定STL的狀況下缺省是nonespa

能夠在Application.mk文件中經過變量APP_STL變量指定一個運行庫:「c++_shared」,「c++_static」,「none」或「system」中選擇其一。

APP_STL
  可選:none / system / c++_static / c++_shared
  若是未設置,默認爲none

2.3 clang編譯指定STL

clang編譯能夠直接指定link flag。缺省是c++_shared。若是要指定靜態庫,用「-static-libstdc++」【這裏只是連接選項,不是源碼編譯時的libstdc++,這裏選擇的實際是c++_static】

 

3、 c++特性支持

libc++這個STL支持Exception處理和RTTI。

3.1 Exception

缺省ndk-build裏Exception處理機制是關閉的;缺省cmake編譯Exception處理機制是打開的。

能夠用下面方式打開Exception處理:

1)  整個程序範圍打開,在Application.mk裏添加:

APP_CPPFLAGS := -fexceptions

2) 在一個Module級別,在Android.mk裏添加:

LOCAL_CPP_FEATURES := exceptions
# or
LOCAL_CPPFLAGS := -fexceptions

3.2 RTTI

缺省ndk-build裏RTTI是關閉的;缺省cmake編譯RTTI是打開的。

能夠用下面方式打開RTTI:

1)  整個程序範圍打開,在Application.mk裏添加:

APP_CPPFLAGS := -frtti

2) 在一個Module級別,在Android.mk裏添加:

LOCAL_CPP_FEATURES := rtti
# or
LOCAL_CPPFLAGS := -frtti

 

4、NDK版本變化

目前Android SDK裏能夠直接下載到的NDK的版本(r16 ~r21)裏的STL、支持的Android 版本及其變化總結以下:

NDK Release Date STL Supported SDK (API) Arch
gabi++ gnustl libc++ libc++abi stlport system
16b 2017-12 √ (preferred) 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27 MIPS deprecated
r17c 2018-06 √ (deprecated) √ (deprecated) √ (default) √ (deprecated) 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28 (Android9) MIPS removed
r18b 2018-08 √ (removed) √ (removed) √ (removed) 14, 1516, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28 require 64-bit support
r19c 2019-01 14, 1516, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28  
r20b 2019-06 14, 1516, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29 (Android10)  
r21d 2020-06 14, 1516, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 (Android11)  

重大變化(表中已經明確以顏色/刪除線等方式標註)總結以下:

STL變化:

  • r16開始優選libc++;r17開始libc++是缺省的stl,
  • gnustl在r17開始被標註過期而且在r18中被移除;

NDK支持Android版本的變化:

  • Android9(API 28)在NDK r17開始支持;
  • Android10(API 29)在NDK r20開始支持;
  • Android11(API 30)在NDK r21開始支持;
  • Android4.0.x(API 14/15)從NDK r18開始再也不支持

 

5、總結

總結一下:

  1. Android NDK開發是基於Android的,可是不綁定具體某一個Android版本,一個Android NDK發佈版能夠支持多個Android版本。
  2. NDK開發不管靜態庫仍是動態庫,libc++都是用NDK裏的發佈版本打包在應用裏:動態庫直接在apk裏帶上libc++_shared.so;靜態庫已經把程序須要的STL代碼直接打到應用程序或其所用的native庫裏。
  3. Android NDK中的STL:libc++_shared / libc++_static / system,其中libc++是完整的STL;
  4. NDK開發,cmake和ndk-build方式均可以指定其所用的STL;
  5. libc++支持Exception處理和RTTI,ndk-build須要編譯時打開;
  6. NDK歷史上在r18前還支持gnustl;
  7. 對Android新版本的支持隨着NDK版本更新不斷加入;過期的Android支持也會移除。

 


附:參考及進一步閱讀

相關文章
相關標籤/搜索