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 
     28 The 'system' runtime is the default if there is no APP_STL definition in
     29 your Application.mk. As an example, to use the static GNU STL, add a line like:
     30 
     31         APP_STL := gnustl_static
     32 
     33 To your Application.mk. You can only select a single C++ runtime that all
     34 your code will depend on. It is not possible to mix shared libraries compiled
     35 against different C++ runtimes.
     36 
     37 IMPORTANT: Defining APP_STL in Android.mk has no effect!
     38 
     39 If you are not using the NDK build system, you can still use the GNU STL,
     40 see docs/STANDALONE-TOOLCHAIN.html for more details.
     41 
     42 The capabilities of the various runtimes vary. See this table:
     43 
     44                     C++       C++   Standard
     45                   Exceptions  RTTI    Library
     46 
     47         system        no       no        no
     48         gabi++       yes      yes        no
     49         stlport      yes      yes       yes
     50         gnustl       yes      yes       yes
     51 
     52 
     53 #
     54 
     55 - - - -
     56 I. Runtimes overview:
     57 ---------------------
     58 
     59 ### I.1. System runtime:
     60 
     61 The system runtime only provides a very small number of C++ standard headers.
     62 
     63 This corresponds to the actual C++ runtime provided by the Android platform.
     64 If you use it, your C++ binaries will automatically be linked against the
     65 system libstdc++.
     66 
     67 The only headers provided here are the following:
     68 
     69         cassert cctype cerrno cfloat climits cmath csetjmp csignal cstddef
     70         cstdint cstdio cstdlib cstring ctime cwchar new stl_pair.h typeinfo
     71         utility
     72 
     73 Anything else is _not_ supported, including std::string or std::vector.
     74 
     75 
     76 ### I.2. GAbi++ runtime:
     77 
     78 This is a new minimalistic runtime that provides the same headers than
     79 the system one, with the addition of RTTI (RunTime Type Information) and
     80 exception handling support.
     81 
     82 If you insist on using it, read the "RTTI Support" and
     83 "Static runtime considerations" sections below.
     84 
     85 
     86 ### I.3. STLport runtime:
     87 
     88 This is a port of STLport (http://www.stlport.org) that can be used on
     89 Android. It will provide you with a complete set of C++ standard library
     90 headers, with RTTI and exception handling support.
     91 
     92 That's because the library embeds its own copy of GAbi++.
     93 
     94 Available as both both static and shared libraries. To use it, use either
     95 one of these two lines in your Application.mk:
     96 
     97       APP_STL := stlport_shared
     98       APP_STL := stlport_static
     99 
    100 Note that 'stlport_shared' is preferred, for reasons explained in
    101 "Static runtime considerations".
    102 
    103 
    104 ### I.4. GNU STL runtime:
    105 
    106 This is the GNU Standard C++ Library (a.k.a. libstdc++-v3), providing the
    107 more features. Note that the shared library file is named "libgnustl_shared.so"
    108 instead of "libstdc++.so" as on other platforms.
    109 
    110 If you want to use it, please read the "C++ Exceptions support",
    111 "RTTI Support" and "Static runtime considerations" sections below.
    112 
    113 
    114 
    115 - - - -
    116 II. Important Considerations:
    117 -----------------------------
    118 
    119 ### II.1. C++ Exceptions support:
    120 
    121 The NDK toolchain supports C++ exceptions, since NDK r5, however all C++
    122 sources are compiled with -fno-exceptions support by default, for
    123 compatibility reasons with previous releases.
    124 
    125 To enable it, use the new LOCAL_CPP_FEATURES variable in your Android.mk,
    126 as in:
    127 
    128         LOCAL_CPP_FEATURES += exceptions
    129 
    130 See docs/ANDROID-MK.html for more details about this variable.
    131 
    132 Another way to do the same is to define it in your LOCAL_CPPFLAGS definition
    133 (but using LOCAL_CPP_FEATURES is preferred), as in:
    134 
    135         LOCAL_CPPFLAGS += -fexceptions
    136 
    137 More simply, add a single line to your Application.mk, the setting will
    138 automatically apply to all your project's NDK modules:
    139 
    140         APP_CPPFLAGS += -fexceptions
    141 
    142 IMPORTANT: You *will* have to select a C++ runtime that supports
    143            exceptions to be able to link / run your code.
    144 
    145 
    146 ### II.2. RTTI support:
    147 
    148 Similarly, the NDK toolchain supports C++ RTTI (RunTime Type Information)
    149 since NDK r5, but all C++ sources are built with -fno-rtti by default for
    150 compatibility reasons. To enable it, add the following to your module
    151 declarations:
    152 
    153         LOCAL_CPP_FEATURES += rtti
    154 
    155 This will be equivalent to:
    156 
    157         LOCAL_CPPFLAGS += -frtti
    158 
    159 Or more simply to your Application.mk:
    160 
    161         APP_CPPFLAGS += -frtti
    162 
    163 
    164 ### II.3. Static runtimes:
    165 
    166 Please keep in mind that the static library variant of a given C++ runtime
    167 SHALL ONLY BE LINKED INTO A SINGLE BINARY for optimal conditions.
    168 
    169 What this means is that if your project consists of a single shared
    170 library, you can link against, e.g., stlport_static, and everything will
    171 work correctly.
    172 
    173 On the other hand, if you have two shared libraries in your project
    174 (e.g. libfoo.so and libbar.so) which both link against the same static
    175 runtime, each one of them will  include a copy of the runtime's code in
    176 its final binary image. This is problematic because certain global
    177 variables used/provided internally by the runtime are duplicated.
    178 
    179 This is likely to result in code that doesn't work correctly, for example:
    180 
    181   - memory allocated in one library, and freed in the other would leak
    182     or even corrupt the heap.
    183 
    184   - exceptions raised in libfoo.so cannot be caught in libbar.so (and may
    185     simply crash the program).
    186 
    187   - the buffering of std::cout not working properly
    188 
    189 This problem also happens if you want to link an executable and a shared
    190 library to the same static library.
    191 
    192 In other words, if your project requires several shared library modules,
    193 then use the shared library variant of your C++ runtime.
    194 
    195 
    196 ### II.4. Shared runtimes:
    197 
    198 If you use the shared library variant of a given C++ runtime, keep in mind
    199 that you must load it before any library that depends on it when your
    200 application starts.
    201 
    202 As an example, let's consider the case where we have the following modules
    203 
    204   * libfoo.so
    205   * libbar.so which is used by libfoo.so
    206   * libstlport_shared.so, used by both libfoo and libbar
    207 
    208 You will need to load the libraries in reverse dependency order, as in:
    209 
    210         static {
    211           System.loadLibrary("stlport_shared");
    212           System.loadLibrary("bar");
    213           System.loadLibrary("foo");
    214         }
    215 
    216 Note that you shouldn't use the 'lib' prefix when calling
    217 System.loadLibrary(), unless you specify the full path as in:
    218 
    219     System.loadLibrary("/path/to/libstlport_shared.so")
    220 
    221 Which is not recommended, since this hard-codes the path in your code.
    222 
    223 - - - -
    224 III. EXTRAS:
    225 ------------
    226 
    227 ### III.1. STLport-specific issues:
    228 
    229 This NDK provides prebuilt static and shared libraries for STLport,
    230 but you can force it to be rebuilt from sources by defining the following
    231 in your environment or your Application.mk before building:
    232 
    233     STLPORT_FORCE_REBUILD := true
    234 
    235 STLport is licensed under a BSD-style open-source license. See
    236 sources/cxx-stl/stlport/README for more details about the library.
    237 
    238 
    239 ### III.2. GNU libstdc++ license is GPLv3 + linking exception!
    240 
    241 Be aware that the GNU libstdc++ is covered by the GPLv3 license (and *not*
    242 the LGPLv2 or LGPLv3 as some assume), full details available here:
    243 
    244     http://gcc.gnu.org/onlinedocs/libstdc++/manual/license.html
    245 
    246 Be sure that you comply with all clauses of this license.
    247 
    248 
    249 ### IV. Future Plans:
    250 
    251   - uSTL support?
    252 
    253