1 C++ support with the Android NDK 2 ================================ 3 4 5 The Android platform provides a very minimal C++ runtime support library 6 (/system/lib/libstdc++) and corresponding headers for it in the NDK. 7 8 By 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 14 However, the NDK provides various "helper C++ runtimes" which can provide them, 15 or a subset of these features. 16 17 To select the runtime you want to use, define APP_STL inside your 18 Application.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 30 The 'system' runtime is the default if there is no APP_STL definition in 31 your Application.mk. As an example, to use the static GNU STL, add a line like: 32 33 APP_STL := gnustl_static 34 35 To your Application.mk. You can only select a single C++ runtime that all 36 your code will depend on. It is not possible to mix shared libraries compiled 37 against different C++ runtimes. 38 39 IMPORTANT: Defining APP_STL in Android.mk has no effect! 40 41 If you are not using the NDK build system, you can still use on of 42 STLport, libc++ or GNU STL via "make-standalone-toolchain.sh --stl=". 43 see docs/STANDALONE-TOOLCHAIN.html for more details. 44 45 The 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 - - - - 59 I. Runtimes overview: 60 --------------------- 61 62 ### I.1. System runtime: 63 64 The system runtime only provides a very small number of C++ standard headers. 65 66 This corresponds to the actual C++ runtime provided by the Android platform. 67 If you use it, your C++ binaries will automatically be linked against the 68 system libstdc++. 69 70 The 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 76 Anything else is _not_ supported, including std::string or std::vector. 77 78 79 ### I.2. GAbi++ runtime: 80 81 This is a new minimalistic runtime that provides the same headers than 82 the system one, with the addition of RTTI (RunTime Type Information) and 83 exception handling support. 84 85 If you insist on using it, read the "RTTI Support" and 86 "Static runtime considerations" sections below. 87 88 89 ### I.3. STLport runtime: 90 91 This is a port of STLport (http://www.stlport.org) that can be used on 92 Android. It will provide you with a complete set of C++ standard library 93 headers, with RTTI and exception handling support. 94 95 That's because the library embeds its own copy of GAbi++. 96 97 Available as both both static and shared libraries. To use it, use either 98 one of these two lines in your Application.mk: 99 100 APP_STL := stlport_shared 101 APP_STL := stlport_static 102 103 Note that 'stlport_shared' is preferred, for reasons explained in 104 "Static runtime considerations". The shared library file is named 105 libstlport_shared.so instead of "libstdc++.so" as on other platforms. 106 107 108 ### I.4. GNU STL runtime: 109 110 This is the GNU Standard C++ Library (a.k.a. libstdc++-v3), providing the 111 more features. Note that the shared library file is named "libgnustl_shared.so". 112 113 114 ### I.5. libC++ runtime: 115 116 This is a port of LLVM libc++: http://libcxx.llvm.org/. Note that the shared library 117 file is named "libc++_shared.so". 118 119 120 Please read the "C++ Exceptions support", "RTTI Support" and 121 "Static runtime considerations" sections below. 122 123 124 - - - - 125 II. Important Considerations: 126 ----------------------------- 127 128 ### II.1. C++ Exceptions support: 129 130 The NDK toolchain supports C++ exceptions, since NDK r5, however all C++ 131 sources are compiled with -fno-exceptions support by default, for 132 compatibility reasons with previous releases. 133 134 To enable it, use the new LOCAL_CPP_FEATURES variable in your Android.mk, 135 as in: 136 137 LOCAL_CPP_FEATURES += exceptions 138 139 See docs/ANDROID-MK.html for more details about this variable. 140 141 Another 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 146 More simply, add a single line to your Application.mk, the setting will 147 automatically apply to all your project's NDK modules: 148 149 APP_CPPFLAGS += -fexceptions 150 151 IMPORTANT: 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 157 Similarly, the NDK toolchain supports C++ RTTI (RunTime Type Information) 158 since NDK r5, but all C++ sources are built with -fno-rtti by default for 159 compatibility reasons. To enable it, add the following to your module 160 declarations: 161 162 LOCAL_CPP_FEATURES += rtti 163 164 This will be equivalent to: 165 166 LOCAL_CPPFLAGS += -frtti 167 168 Or more simply to your Application.mk: 169 170 APP_CPPFLAGS += -frtti 171 172 173 ### II.3. Static runtimes: 174 175 Please keep in mind that the static library variant of a given C++ runtime 176 SHALL ONLY BE LINKED INTO A SINGLE BINARY for optimal conditions. 177 178 What this means is that if your project consists of a single shared 179 library, you can link against, e.g., stlport_static, and everything will 180 work correctly. 181 182 On 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 184 runtime, each one of them will include a copy of the runtime's code in 185 its final binary image. This is problematic because certain global 186 variables used/provided internally by the runtime are duplicated. 187 188 This 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 198 This problem also happens if you want to link an executable and a shared 199 library to the same static library. 200 201 In other words, if your project requires several shared library modules, 202 then use the shared library variant of your C++ runtime. 203 204 205 ### II.4. Shared runtimes: 206 207 If you use the shared library variant of a given C++ runtime, keep in mind 208 that you must load it before any library that depends on it when your 209 application starts. 210 211 As 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 217 You 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 225 Note that you shouldn't use the 'lib' prefix when calling 226 System.loadLibrary(), unless you specify the full path as in: 227 228 System.loadLibrary("/path/to/libstlport_shared.so") 229 230 Which is not recommended, since this hard-codes the path in your code. 231 232 - - - - 233 III. EXTRAS: 234 ------------ 235 236 ### III.1. STLport-specific issues: 237 238 This NDK provides prebuilt static and shared libraries for STLport, 239 but you can force it to be rebuilt from sources by defining the following 240 in your environment or your Application.mk before building: 241 242 STLPORT_FORCE_REBUILD := true 243 244 STLport is licensed under a BSD-style open-source license. See 245 sources/cxx-stl/stlport/README for more details about the library. 246 247 248 ### III.2. GNU libstdc++ license is GPLv3 + linking exception! 249 250 Be aware that the GNU libstdc++ is covered by the GPLv3 license (and *not* 251 the LGPLv2 or LGPLv3 as some assume), full details available here: 252 253 http://gcc.gnu.org/onlinedocs/libstdc++/manual/license.html 254 255 Be 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 262 Similiar to GNU libstdc++, you need to explicitly turns on exceptions or rtti 263 support in "LOCAL_CPP_FEATURES" if you wish. 264 265 It's likely that you need libatomic if you #include <atomic>. Add 266 "LOCAL_LDLIBS += -latomic" for ndk-build, and "-latomic" for standalone toolchain. 267 Note that -latomic is only available in gcc4.8, not gcc4.6. Clang3.4/3.3 use gcc4.8's 268 as/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 271 This NDK provides prebuilt static and shared libraries for libc++ 272 compiled by clang, but you can force it to be rebuilt from sources by defining 273 the following in your environment or your Application.mk before building: 274 275 LIBCXX_FORCE_REBUILD := true 276 277 Around 98% of current 4645 tests passes when compiling libc++ with 278 clang for all supported ABIs. The remaining fails are mostly in the areas 279 of wchar_t and locale Android bionic don't support. Switching locale 280 from 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 284 Using gabi++ as run-time also causes some issues in the nested exception and propagation too, 285 which will be addressed when libc++ switches to use libc++abi in the future. 286 287 More fails when compiling libc++ with gcc4.8 mostly because the lack of support 288 in _Atomic (ETA: gcc 4.9). See platform/ndk.git 289 29d9f88ef5a33cd65b4b9977aed628bc195facf3 for details 290 291 Using libc++ with gcc4.6 is not recommended (at least not tested at 292 this moment) because its c++11 support isn't great 293 294 See "black_list*" in 295 tests/device/test-libc++-shared-full/jni/Android.mk for tests which fail to 296 compile, and tests/device/test-libc++-shared-full/BROKEN_RUN for tests 297 which fails to run correctly. 298 299 ### IV. Future Plans: 300 301 - uSTL support? 302 303