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