Home | History | Annotate | Download | only in text
      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