Android gnustl_static VS gnustl_share

微巖發表於2018-01-31

0. 前言

使用gnustl_static,儘量避免使用gnustl_share。此外gnustl將逐步廢棄!

1. gnustl

1.1 簡介

gnustl: Android上的GNU C++庫,對應GNU/Linux系統中的libstdc++。

  • 這個庫和GCC僅僅繫結,但是後期不再更新,最新NDK不再支援
  • 此庫和Clang存在部分衝突

Note: 新版NDK將會刪除此庫,從NDK16開始,被libc++替代。

靜態庫:libgnustl_static.a
動態庫:libgnustl_shared.so

1.2 設定

只能在Application.mk設定

APP_STL := gnustl_shared

or

APP_STL := gnustl_static

2. gnustl_static VS gnustl_share

2.1 gnustl_static

當使用static library時,相關程式碼被連線到編譯輸出庫中,這會造成目標檔案變大。
優點:

  • 目標檔案已經包含所依賴的程式碼,不受執行環境的影響。

缺點:

  • 目標檔案變大,不利於複用

優缺點同標準靜態連線庫相同。

2.2 gnustl_share

動態連結庫:依賴程式碼不編譯到目標檔案中。
優點:

  • 目標檔案體積小。

缺點:

  • 需要動態連結依賴庫,由於gnustl是系統庫,所以不需要額外輸出libgnustl_share.so。但是由於Android系統的碎片化,各個版本的libgnustl_share.so不一致,就導致崩潰或者執行異常問題。

2.3 結論

鑑於gnustl_share存在諸多不穩定問題,所以儘量採用gnustl_static替代gnustl_share。

3. gnustl_share崩潰解決方案

統一採用NDK10中的gnustl_share的庫,然後在Android.mk和程式碼中顯示載入此庫。具體步驟如下:

  1. 使用NDKr9c或者r10e
  2. Copy:
libgnustl_shared.so <= /sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi/
  1. 顯示載入複製出來的gnustl_share
System.loadLibrary("gnustl_shared")

4. 補充

APP_STL的取值:

system(default)系統預設的C++執行庫

stlport_static以靜態連結方式使用的sttport版本的STL

stlport_shared以動態連結方式使用的sttport版本的STL

gnustl_static以靜態連結方式使用的gnustl版本的STL

gnustl_shared以動態連結方式使用的gnustl版本的STL

gabi++_static以靜態連結方式使用的gabi++

gabi++_shared以動態連結方式使用的gabi++

c++_static以靜態連結方式使用的LLVM libc++

c++_shared以動態連結方式使用的LLVM libc++

就目前的情況,LLVM的支援要優於GNU,所以推薦使用“c++_static”

5. Reference

[1] https://developer.android.google.cn/ndk/guides/cpp-support.html?hl=zh-cn#gn
[2] http://forum.cocos.com/t/gnustl/44779/3
[3] https://stackoverflow.com/questions/43089065/what-is-the-difference-between-gnustl-shared-and-gnustl-static-in-android-ndk-li

相關文章