田海立@CSDN 2020-11-20
Android源码中有内置的LLVM c++ STL和libstdc++标准库,为了支持内置的应用,也会选取NDK的标准库内置其中,本文介绍这些STL以及Android Source模块如何来指定其所要使用的标准库。
一、STL相关的模块
Android source中的编译单位是模块/Module,下面看stl相关的Module。
1) libc++ [Shared]
2) libc++_static [Static]
external/libcxx/Android.bp
libc++_static.a --(whole_static_libs)--> libc++abi.a
libc++.so --(whole_static_libs)--> libc++_static.a
3) libc++abi [Static]
external/libcxxabi/Android.bp
libc++abi.a
4) libstdc++.so
5) libstdc++.a
bionic/libc/Android.bp
libstdc++.so
libstdc++.a
6) c++_static
7) c++_shared
prebuilts/ndk/current/sources/cxx-stl/llvm-libc++/Android.mk
c++_static
c++_shared
libc++abi被打包在libc++中,一般不单独使用。所以,Android Source中有下列stl库相关的Module:
- libc++/libc++_static: llvm c++ stl库。这是Android版本内置的与Android发布绑定的库。
- libstdc++:仅仅包含new/delete的库,非完全stl,完全stl需使用上面的libc++。这是与Android发布绑定的库。
- c++_static/c++_shared:这内置的NDK里的stl,与NDK发布版本里的stl对应。
二、程序中指定STL
2.1 Android.mk中通过LOCAL_NDK_STL_VARIANT指定NDK stl
LOCAL_NDK_STL_VARIANT
可选:none / system / c++_static / c++_shared
如果未设置,默认为system
指定了该变量,需要设置 LOCAL_SDK_VERSION
指定system
lib: libstdc++
include: $(my_ndk_source_root)/cxx-stl/system/include
指定c++(c++_static/c++shared)
include: $(my_ndk_source_root)/cxx-stl/llvm-libc++/include \
$(my_ndk_source_root)/cxx-stl/llvm-libc++abi/include \
$(my_ndk_source_root)/android/support/include \
lib
c++_static:
$(my_ndk_source_root)/cxx-stl/llvm-libc++/libs/$(my_cpu_variant)/libc++_static.a \
$(my_ndk_source_root)/cxx-stl/llvm-libc++/libs/$(my_cpu_variant)/libc++abi.a
c++_shared:
$(my_ndk_source_root)/cxx-stl/llvm-libc++/libs/$(my_cpu_variant)/libc++_shared.so
+= $(my_ndk_source_root)/cxx-stl/llvm-libc++/libs/$(my_cpu_variant)/libandroid_support.a
for armeabi armeabi-v7a
+= $(my_ndk_source_root)/cxx-stl/llvm-libc++/libs/$(my_cpu_variant)/libunwind.a
2.2 Android.bp里指定stl
在Android.bp中指定使用的STL,按是否指定sdk version分两种情况:
1) 指定了sdk verion
stl: "" / "c++_shared" / "c++_static" / "libc++" / "libc++_static" / "none"
"" -> "ndk_system"
"c++_shared" -> "ndk_libc++_shared"
"c++_static" -> "ndk_libc++_static"
"libc++" -> "ndk_libc++_shared"
"libc++_static" -> "ndk_libc++_static"
"none" -> ""
上面第一行是stl可以指定的标示;下面是stl标示又对应的stl。
【注】指定了sdk verson,并用stl指定c++ stl时:
- c++_shared和libc++都是使用了NDK里的llvm动态库;c++_static和libc++_static都是使用了NDK里的llvm静态库
- 如果指定了空,使用的是NDK里的system库
2) 未指定sdk verion
stl: "libc++" / "libc++_static" / "none" / ""
"libc++" -> "libc++"
"libc++_static" -> "libc++static"
"none" -> ""
"" -> "libc++_static" for static
-> "libc++" for shared
同样,上面第一行是stl可以指定的标示;下面是stl标示又对应的stl。
【注】未指定sdk verson,并用stl指定c++ stl时:
- libc++和libc++_static指定的是android source中的stl,并非NDK里的stl
- 如果指定了空,会根据所要编译的模块是动态库还是静态库而选择android source中libc++和libc++_static。
三、总结
总结一下:
- Android Source中的STL:内置的libc++/libc++_static/system;内置的NDK版本中的libc++_shared/libc++_static/system(system也就是android source中的libstdc++);
- Android.mk中通过LOCAL_NDK_STL_VARIANT指定NDK里的STL;
- Android.bp中指定了sdk_version,通过stl指定的stl是NDK里的STL;
- Android.bp中未指定sdk_version,通过stl指定的stl是android系统里的STL;且stl未指定的情况下,默认也会用android系统里的对应的STL。