Android NDK中的c++ STL

田海立@CSDN 2020-11-25

Android NDK(Native Development Kit)提供了一套基于c/c++开发Android应用的工具。基于c/c++开发需要STL (Standard Template Library/标准模版库),本文描述Android NDK中提供的STL。

  1. Android NDK开发是基于Android的,但是不绑定具体某一个Android版本,一个NDK发布版可以支持多个Android版本。
  2. NDK开发无论静态库还是动态库,libc++都是用NDK里的发布版本打包在应用里:动态库直接在apk里带上libc++_shared.so;静态库已经把程序需要的STL的代码直接打到应用程序或其所用的native库里。

 

一、Android NDK中的c++运行库

Android NDK中提供下列c++运行库。

其中的各个运行库:

  • 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和stlport,gnustl是GNU的c++ STL,同样包含了动态库"gnustl_shared"(libgnustl_shared.so)以及静态库"gnustl_static"(libgnustl_static.a)支持;stlport同样包含了动态库"stlport_shared"(libstlport_shared.so)以及静态库"stlport_static"(libstlport_static.a)支持。在那些版本的NDK里有多于一种的真正完全STL可供选择。

 

二、NDK开发时选择STL

NDK开发时,可以用下面方式指定c++运行库。

运行库在“c++_shared”,“c++_static”,“none”或“system”中选择其一,其中c++_shared”,“c++_static”分别对应libc++的动态库和静态库。

2.1 cmake编译指定STL

不通过ANDROID_STL指定STL的情况下缺省是c++_static。

可以在Module级别的build.gradle文件中通过变量ANDROID_STL变量指定一个运行库:“c++_shared”,“c++_static”,“none”或“system”中选择其一。


  
  
  1. ANDROID_STL
  2. 可选:none / system / c++_static / c++_shared
  3. 如果未设置,默认为c++_static

2.2 ndk-build里指定STL

不通过APP_STL指定STL的情况下缺省是none

可以在Application.mk文件中通过变量APP_STL变量指定一个运行库:“c++_shared”,“c++_static”,“none”或“system”中选择其一。


  
  
  1. APP_STL
  2. 可选:none / system / c++_static / c++_shared
  3. 如果未设置,默认为none

2.3 clang编译指定STL

clang编译可以直接指定link flag。缺省是c++_shared。如果要指定静态库,用“-static-libstdc++”【这里只是链接选项,不是源码编译时的libstdc++,这里选择的实际是c++_static】

 

三、 c++特性支持

libc++这个STL支持Exception处理和RTTI。

3.1 Exception

缺省ndk-build里Exception处理机制是关闭的;缺省cmake编译Exception处理机制是打开的。

可以用下面方式打开Exception处理:

1)  整个程序范围打开,在Application.mk里添加:

APP_CPPFLAGS := -fexceptions
  
  

2) 在一个Module级别,在Android.mk里添加:


  
  
  1. LOCAL_CPP_FEATURES := exceptions
  2. # or
  3. LOCAL_CPPFLAGS := -fexceptions

3.2 RTTI

缺省ndk-build里RTTI是关闭的;缺省cmake编译RTTI是打开的。

可以用下面方式打开RTTI:

1)  整个程序范围打开,在Application.mk里添加:

APP_CPPFLAGS := -frtti
  
  

2) 在一个Module级别,在Android.mk里添加:


  
  
  1. LOCAL_CPP_FEATURES := rtti
  2. # or
  3. LOCAL_CPPFLAGS := -frtti

 

四、NDK版本变化

目前Android SDK里可以直接下载到的NDK的版本(r16 ~r21)里的STL、支持的Android 版本及其变化总结如下:

NDKRelease DateSTLSupported SDK (API)Arch
gabi++gnustllibc++libc++abistlportsystem
16b2017-12√ (preferred)14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27MIPS deprecated
r17c2018-06√ (deprecated)√ (deprecated)√ (default)√ (deprecated)14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28 (Android9)MIPS removed
r18b2018-08√ (removed)√ (removed)√ (removed)14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28require 64-bit support
r19c2019-0114, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28 
r20b2019-0614, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29 (Android10) 
r21d2020-0614, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 (Android11) 

重大变化(表中已经明确以颜色/删除线等方式标注)总结如下:

STL变化:

  • r16开始优选libc++;r17开始libc++是缺省的stl,
  • gnustl和stlport在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开始不再支持

 

五、总结

总结一下:

  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和stlport;
  7. 对Android新版本的支持随着NDK版本更新不断加入;过时的Android支持也会移除。

 


附1:参考及进一步阅读

 

附2:修正历史

  • 2020-11-25 第一版
  • 2020-12-02 历史上完整STL还包含stlport,增加相应的描述。

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值