Home | History | Annotate | Download | only in docs
      1 <html><body><pre>USING THE ANDROID TOOLCHAIN AS A STANDALONE COMPILER
      2 ======================================================
      3 
      4 It is now possible to use the toolchains provided with the Android NDK as
      5 standalone compilers. This can be useful if you already have your own build
      6 system, and only need to ability to invoke the cross-compiler to add support
      7 to Android for it.
      8 
      9 A typical use case if invoking the 'configure' script of an open-source
     10 library that expects a cross-compiler in the CC environment variable.
     11 
     12 
     13 This document explains how to do that:
     14 
     15 1/ Selecting your toolchain:
     16 ----------------------------
     17 
     18 Before anything else, you need to decide whether your standalone toolchain
     19 is going to target ARM-based devices, x86-based, or MIPS-based one.
     20 Each architecture corresponds to a different toolchain name:
     21 
     22   * arm-linux-androideabi-4.4.3   => targetting ARM-based Android devices
     23   * x86-4.4.3                     => targetting x86-based Android devices
     24   * mipsel-linux-android-4.4.3    => targetting MIPS-based Android devices
     25 
     26 2/ Selecting your sysroot:
     27 --------------------------
     28 
     29 The second thing you need to know is which Android native API level you want
     30 to target. Each one of them provides a different various APIs, which are
     31 documented under doc/STABLE-APIS.html, and correspond to the sub-directories
     32 of $NDK/platforms.
     33 
     34 This allows you to define the path to your 'sysroot', a GCC term for a
     35 directory containing the system headers and libraries of your target.
     36 Usually, this will be something like:
     37 
     38    SYSROOT=$NDK/platforms/android-&lt;level&gt;/arch-&lt;arch&gt;/
     39 
     40 Where &lt;level&gt; is the API level number, and &lt;arch&gt; is the architecture
     41 ("arm", "x86", and "mips" are the supported values). For example, if you're
     42 targeting Android 2.2 (a.k.a. Froyo), you would use:
     43 
     44    SYSROOT=$NDK/platforms/android-8/arch-arm
     45 
     46 IMPORTANT: Note that only android-9 is supported for the x86 architecture.
     47 Note that android-9 and later are supported for the MIPS architecture.
     48 
     49 2/ Invoking the compiler (the hard way):
     50 ----------------------------------------
     51 
     52 Invoke the compiler using the --sysroot option to indicate where the system
     53 files for the platform you're targeting are located. For example, do:
     54 
     55     export CC="$NDK/toolchains/&lt;name&gt;/prebuilt/&lt;system&gt;/bin/&lt;prefix&gt;gcc --sysroot=$SYSROOT"
     56     $CC -o foo.o -c foo.c
     57 
     58 Where &lt;name&gt; is the toolchain's name, &lt;system&gt; is the host tag for your system,
     59 and &lt;prefix&gt; is a toolchain-specific prefix. For example, if you are on Linux
     60 using the NDK r5 toolchain, you would use:
     61 
     62     export CC="$NDK/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=$SYSROOT"
     63 
     64 As you can see, this is rather verbose, but it works!
     65 
     66 IMPORTANT NOTE:
     67 
     68     Using the NDK toolchain directly has a serious limitation:
     69     You won't be able to use any C++ STL (either STLport or
     70     the GNU libstdc++) with it. Also no exceptions and no RTTI.
     71 
     72 
     73 3/ Invoking the compiler (the easy way):
     74 ----------------------------------------
     75 
     76 The NDK allows you to create a "customized" toolchain installation to make
     77 life easier. For example, consider the following command:
     78 
     79   $NDK/build/tools/make-standalone-toolchain.sh --platform=android-5 --install-dir=/tmp/my-android-toolchain
     80 
     81 This will create a directory named /tmp/my-android-toolchain containing a
     82 copy of the android-5/arch-arm sysroot, and of the toolchain binaries.
     83 
     84 Note that by default, the ARM-based toolchain will be selected by the script.
     85 Use the '--arch=x86' option to specify the x86-based one,
     86 use the '--arch=mips' option to specify the MIPS-based one, or alternatively
     87 '--toolchain=&lt;name&gt;'.
     88 
     89 You can later use it directly with something like:
     90 
     91    export PATH=/tmp/my-android-toolchain/bin:$PATH
     92    export CC=arm-linux-androideabi-gcc
     93 
     94 Note that without the --install-dir option, make-standalone-toolchain.sh will
     95 create a tarball in /tmp/ndk/&lt;toolchain-name&gt;.tar.bz2. This allows you to
     96 archive and redistribute the binaries easily.
     97 
     98 Another important benefit is that this standalone toolchain will contain a
     99 working copy of the GNU libstdc++, with working exceptions and RTTI support
    100 (as long as you link against libstdc++ or libsupc++)
    101 
    102 Use --help for more options and details.
    103 
    104 IMPORTANT: The toolchain binaries do not depend or contain host-specific paths,
    105            in other words, they can be installed in any location, or even
    106            moved if you need to.
    107 
    108 NOTE: You can still use the --sysroot option with the new toolchain, but it
    109       is now simply optional!
    110 
    111 
    112 4/ ABI Compatibility:
    113 ---------------------
    114 
    115 The machine code generated by the ARM toolchain should be compatible with
    116 the official Android 'armeabi' ABI (see docs/CPU-ARCH-ABIS.html) by default.
    117 
    118 It is recommended to use the -mthumb compiler flag to force the generation
    119 of 16-bit Thumb-1 instructions (the default being 32-bit ARM ones).
    120 
    121 If you want to target the 'armeabi-v7a' ABI, you will need ensure that the
    122 following two flags are being used:
    123 
    124   CFLAGS='-march=armv7-a -mfloat-abi=softfp'
    125 
    126 Note: The first flag enables Thumb-2 instructions, and the second one
    127       enables H/W FPU instructions while ensuring that floating-point
    128       parameters are passed in core registers, which is critical for
    129       ABI compatibility. Do *not* use these flags separately!
    130 
    131 If you want to use Neon instructions, you will need one more compiler flag:
    132 
    133   CFLAGS='-march=armv7-a -mfloat-abi=softfp -mfpu=neon'
    134 
    135 Note that this forces the use of VFPv3-D32, as per the ARM specification.
    136 
    137 Also, make sure the following two flags are provided to linker:
    138 
    139   LDFLAGS='-march=armv7-a -Wl,--fix-cortex-a8'
    140 
    141 Note: The first flag instructs linker to pick libgcc.a, libgcov.a and
    142       crt*.o tailored for armv7.  The 2nd flag is *required* to routes
    143       around a CPU bug in some Cortex-A8 implementations:
    144 
    145 If none of the above makes sense to you, it's probably better not to use
    146 the standalone toolchain, and stick to the NDK build system instead, which
    147 will handle all the details for you.
    148 
    149 You don't have to use any specific compiler flag when targetting the x86 ABI
    150 or the MIPS ABI.
    151 
    152 5/ Warnings and Limitations:
    153 --------------------------
    154 
    155 5.1/ Windows support:
    156 - - - - - - - - - - -
    157 
    158 The Windows binaries do *not* depend on Cygwin. The good news is that they
    159 are thus faster, the bad news is that they do not understand the Cygwin
    160 path specification like /cygdrive/c/foo/bar (instead of C:/foo/bar).
    161 
    162 The NDK build system ensures that all paths passed to the compiler from Cygwin
    163 are automatically translated, and deals with other horrors for you. If you have
    164 a custom build system, you may need to deal with the problem yourself.
    165 
    166 NOTE: There is no plan to support Cygwin / MSys at the moment, but
    167       contributions are welcome. Contact the android-ndk forum for details.
    168 
    169 
    170 5.2/ wchar_t support:
    171 - - - - - - - - - - -
    172 
    173 As documented, the Android platform did not really support wchar_t until
    174 Android 2.3. What this means in practical terms is that:
    175 
    176   - If you target platform android-9 or higher, the size of wchar_t is
    177     4 bytes, and most wide-char functions are available in the C library
    178     (with the exception of multi-byte encoding/decoding functions and
    179      wsprintf/wsscanf).
    180 
    181   - If you target any prior API level, the size of wchar_t will be 1 byte
    182     and none of the wide-char functions will work anyway.
    183 
    184 We recommend any developer to get rid of any dependencies on the wchar_t type
    185 and switch to better representations. The support provided in Android is only
    186 there to help you migrate existing code.
    187 
    188 
    189 5.3/ Exceptions, RTTI and STL:
    190 - - - - - - - - - - - - - - -
    191 
    192 The toolchain binaries *do* support C++ exceptions and RTTI by default.
    193 They are enabled by default, so use -fno-exceptions and -fno-rtti if you
    194 want to disable them when building sources with them (e.g. to generate
    195 smaller machine code).
    196 
    197 NOTE: You will need to explicitly link with libsupc++ if you use these
    198       features. To do this, use -lsupc++ when linking binaries, as in:
    199 
    200     arm-linux-androideabi-g++ .... -lsupc++
    201 
    202 
    203 5.4/ C++ STL support:
    204 - - - - - - - - - - -
    205 
    206 The standalone toolchain also comes with a copy of the GNU libstdc++
    207 library, which provides an implementation of the C++ Standard Template
    208 Library. To use it, you however need to link with the proper library:
    209 
    210   * Use -lstdc++ to link against the _static_ library version. This ensures
    211     that all required C++ STL code is included into your final binary. This
    212     is ideal if you are only generating a single shared library or executable.
    213 
    214     This is the recommended way to do it.
    215 
    216   * Use -lgnustl_shared to link against the _shared_ library version. This
    217     is required if you have several related shared libraries or executables
    218     that need to run in the same address space at runtime (some global variables
    219     need to be defined uniquely, which is not possible if you link the static
    220     libstdc++ against each one of your executables).
    221 
    222     If you use this option, you need to ensure that libgnustl_shared.so is
    223     also copied to your device for your code to load properly. The file is
    224     at:
    225 
    226       $TOOLCHAIN/arm-linux-androideabi/lib/  for ARM toolchains.
    227       $TOOLCHAIN/i686-linux-android/lib/     for x86 ones.
    228       $TOOLCHAIN/mipsel-linux-android/lib/   for MIPS toolchains.
    229 
    230 
    231     IMPORTANT: The GNU libstdc++ is licensed under the GPLv3 with a
    232                linking exception. See the following URL for details:
    233 
    234           http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt01ch01s02.html
    235 
    236     If you cannot comply with its requirements, i.e. you cannot redistribute
    237     the shared library, do not use it in your project.
    238 
    239 The reason the shared version of GNU libstdc++ is not called libstdc++.so is
    240 because this would conflict at runtime with the system's own minimal C++
    241 runtime, which is /system/lib/libstdc++.so. This enforces a new name for the
    242 GNU ELF library. This is not a problem for the static library.
    243 
    244 </pre></body></html>
    245