1C++ support with the Android NDK 2================================ 3 4 5The Android platform provides a very minimal C++ runtime support library 6(/system/lib/libstdc++) and corresponding headers for it in the NDK. 7 8By default, this 'system' runtime does *not* provide the following: 9 10 - Standard C++ Library support (except a few trivial headers). 11 - C++ exceptions support 12 - RTTI support 13 14However, the NDK provides various "helper C++ runtimes" which can provide them, 15or a subset of these features. 16 17To select the runtime you want to use, define APP_STL inside your 18Application.mk to one of the following values: 19 20 system -> Use the default minimal system C++ runtime library. 21 gabi++_static -> Use the GAbi++ runtime as a static library. 22 gabi++_shared -> Use the GAbi++ runtime as a shared library. 23 stlport_static -> Use the STLport runtime as a static library. 24 stlport_shared -> Use the STLport runtime as a shared library. 25 gnustl_static -> Use the GNU STL as a static library. 26 gnustl_shared -> Use the GNU STL as a shared library. 27 c++_static -> Use the LLVM libc++ as a static library. 28 c++_shared -> Use the LLVM libc++ as a shared library. 29 30The 'system' runtime is the default if there is no APP_STL definition in 31your Application.mk. As an example, to use the static GNU STL, add a line like: 32 33 APP_STL := gnustl_static 34 35To your Application.mk. You can only select a single C++ runtime that all 36your code will depend on. It is not possible to mix shared libraries compiled 37against different C++ runtimes. 38 39IMPORTANT: Defining APP_STL in Android.mk has no effect! 40 41If you are not using the NDK build system, you can still use on of 42STLport, libc++ or GNU STL via "make-standalone-toolchain.sh --stl=". 43see docs/STANDALONE-TOOLCHAIN.html for more details. 44 45The capabilities of the various runtimes vary. See this table: 46 47 C++ C++ Standard 48 Exceptions RTTI Library 49 50 system no no no 51 gabi++ yes yes no 52 stlport yes yes yes 53 gnustl yes yes yes 54 libc++ yes yes yes 55 56# 57 58- - - - 59I. Runtimes overview: 60--------------------- 61 62### I.1. System runtime: 63 64The system runtime only provides a very small number of C++ standard headers. 65 66This corresponds to the actual C++ runtime provided by the Android platform. 67If you use it, your C++ binaries will automatically be linked against the 68system libstdc++. 69 70The only headers provided here are the following: 71 72 cassert cctype cerrno cfloat climits cmath csetjmp csignal cstddef 73 cstdint cstdio cstdlib cstring ctime cwchar new stl_pair.h typeinfo 74 utility 75 76Anything else is _not_ supported, including std::string or std::vector. 77 78 79### I.2. GAbi++ runtime: 80 81This is a new minimalistic runtime that provides the same headers than 82the system one, with the addition of RTTI (RunTime Type Information) and 83exception handling support. 84 85If you insist on using it, read the "RTTI Support" and 86"Static runtime considerations" sections below. 87 88 89### I.3. STLport runtime: 90 91This is a port of STLport (http://www.stlport.org) that can be used on 92Android. It will provide you with a complete set of C++ standard library 93headers, with RTTI and exception handling support. 94 95That's because the library embeds its own copy of GAbi++. 96 97Available as both both static and shared libraries. To use it, use either 98one of these two lines in your Application.mk: 99 100 APP_STL := stlport_shared 101 APP_STL := stlport_static 102 103Note that 'stlport_shared' is preferred, for reasons explained in 104"Static runtime considerations". The shared library file is named 105libstlport_shared.so instead of "libstdc++.so" as on other platforms. 106 107 108### I.4. GNU STL runtime: 109 110This is the GNU Standard C++ Library (a.k.a. libstdc++-v3), providing the 111more features. Note that the shared library file is named "libgnustl_shared.so". 112 113 114### I.5. libC++ runtime: 115 116This is a port of LLVM libc++: http://libcxx.llvm.org/. Note that the shared library 117file is named "libc++_shared.so". 118 119 120Please read the "C++ Exceptions support", "RTTI Support" and 121"Static runtime considerations" sections below. 122 123 124- - - - 125II. Important Considerations: 126----------------------------- 127 128### II.1. C++ Exceptions support: 129 130The NDK toolchain supports C++ exceptions, since NDK r5, however all C++ 131sources are compiled with -fno-exceptions support by default, for 132compatibility reasons with previous releases. 133 134To enable it, use the new LOCAL_CPP_FEATURES variable in your Android.mk, 135as in: 136 137 LOCAL_CPP_FEATURES += exceptions 138 139See docs/ANDROID-MK.html for more details about this variable. 140 141Another way to do the same is to define it in your LOCAL_CPPFLAGS definition 142(but using LOCAL_CPP_FEATURES is preferred), as in: 143 144 LOCAL_CPPFLAGS += -fexceptions 145 146More simply, add a single line to your Application.mk, the setting will 147automatically apply to all your project's NDK modules: 148 149 APP_CPPFLAGS += -fexceptions 150 151IMPORTANT: You *will* have to select a C++ runtime that supports 152 exceptions to be able to link / run your code. 153 154 155### II.2. RTTI support: 156 157Similarly, the NDK toolchain supports C++ RTTI (RunTime Type Information) 158since NDK r5, but all C++ sources are built with -fno-rtti by default for 159compatibility reasons. To enable it, add the following to your module 160declarations: 161 162 LOCAL_CPP_FEATURES += rtti 163 164This will be equivalent to: 165 166 LOCAL_CPPFLAGS += -frtti 167 168Or more simply to your Application.mk: 169 170 APP_CPPFLAGS += -frtti 171 172 173### II.3. Static runtimes: 174 175Please keep in mind that the static library variant of a given C++ runtime 176SHALL ONLY BE LINKED INTO A SINGLE BINARY for optimal conditions. 177 178What this means is that if your project consists of a single shared 179library, you can link against, e.g., stlport_static, and everything will 180work correctly. 181 182On the other hand, if you have two shared libraries in your project 183(e.g. libfoo.so and libbar.so) which both link against the same static 184runtime, each one of them will include a copy of the runtime's code in 185its final binary image. This is problematic because certain global 186variables used/provided internally by the runtime are duplicated. 187 188This is likely to result in code that doesn't work correctly, for example: 189 190 - memory allocated in one library, and freed in the other would leak 191 or even corrupt the heap. 192 193 - exceptions raised in libfoo.so cannot be caught in libbar.so (and may 194 simply crash the program). 195 196 - the buffering of std::cout not working properly 197 198This problem also happens if you want to link an executable and a shared 199library to the same static library. 200 201In other words, if your project requires several shared library modules, 202then use the shared library variant of your C++ runtime. 203 204 205### II.4. Shared runtimes: 206 207If you use the shared library variant of a given C++ runtime, keep in mind 208that you must load it before any library that depends on it when your 209application starts. 210 211As an example, let's consider the case where we have the following modules 212 213 * libfoo.so 214 * libbar.so which is used by libfoo.so 215 * libstlport_shared.so, used by both libfoo and libbar 216 217You will need to load the libraries in reverse dependency order, as in: 218 219 static { 220 System.loadLibrary("stlport_shared"); 221 System.loadLibrary("bar"); 222 System.loadLibrary("foo"); 223 } 224 225Note that you shouldn't use the 'lib' prefix when calling 226System.loadLibrary(), unless you specify the full path as in: 227 228 System.loadLibrary("/path/to/libstlport_shared.so") 229 230Which is not recommended, since this hard-codes the path in your code. 231 232- - - - 233III. EXTRAS: 234------------ 235 236### III.1. STLport-specific issues: 237 238This NDK provides prebuilt static and shared libraries for STLport, 239but you can force it to be rebuilt from sources by defining the following 240in your environment or your Application.mk before building: 241 242 STLPORT_FORCE_REBUILD := true 243 244STLport is licensed under a BSD-style open-source license. See 245sources/cxx-stl/stlport/README for more details about the library. 246 247 248### III.2. GNU libstdc++ license is GPLv3 + linking exception! 249 250Be aware that the GNU libstdc++ is covered by the GPLv3 license (and *not* 251the LGPLv2 or LGPLv3 as some assume), full details available here: 252 253 http://gcc.gnu.org/onlinedocs/libstdc++/manual/license.html 254 255Be sure that you comply with all clauses of this license. 256 257 258### III.3. libc++-specific issues: 259 260"-std=c++11" is turned on by default. 261 262Similiar to GNU libstdc++, you need to explicitly turns on exceptions or rtti 263support in "LOCAL_CPP_FEATURES" if you wish. 264 265It's likely that you need libatomic if you #include <atomic>. Add 266"LOCAL_LDLIBS += -latomic" for ndk-build, and "-latomic" for standalone toolchain. 267Note that -latomic is only available in gcc4.8, not gcc4.6. Clang3.4/3.3 use gcc4.8's 268as/ld/headers/libraries so they get -latomic too. The version of libatomic in gcc4.8 269*may* work for gcc4.6, although it's not tested and you have to copy them manually. 270 271This NDK provides prebuilt static and shared libraries for libc++ 272compiled by clang, but you can force it to be rebuilt from sources by defining 273the following in your environment or your Application.mk before building: 274 275 LIBCXX_FORCE_REBUILD := true 276 277Around 98% of current 4645 tests passes when compiling libc++ with 278clang for all supported ABIs. The remaining fails are mostly in the areas 279of wchar_t and locale Android bionic don't support. Switching locale 280from the default produces the following warning in logcat 281 282 newlocale() WARNING: Trying to set locale to en_US.UTF-8 other than "", "C" or "POSIX" 283 284Using gabi++ as run-time also causes some issues in the nested exception and propagation too, 285which will be addressed when libc++ switches to use libc++abi in the future. 286 287More fails when compiling libc++ with gcc4.8 mostly because the lack of support 288in _Atomic (ETA: gcc 4.9). See platform/ndk.git 28929d9f88ef5a33cd65b4b9977aed628bc195facf3 for details 290 291Using libc++ with gcc4.6 is not recommended (at least not tested at 292this moment) because its c++11 support isn't great 293 294See "black_list*" in 295tests/device/test-libc++-shared-full/jni/Android.mk for tests which fail to 296compile, and tests/device/test-libc++-shared-full/BROKEN_RUN for tests 297which fails to run correctly. 298 299### IV. Future Plans: 300 301 - uSTL support? 302 303