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.  For example:
     21 
     22   * arm-linux-androideabi-4.6   => targeting ARM-based Android devices
     23   * x86-4.6                     => targeting x86-based Android devices
     24   * mipsel-linux-android-4.6    => targeting 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 X86 and MIPS architectures are only supported at android-9 and later.
     47 
     48 3/ Invoking the compiler (the hard way):
     49 ----------------------------------------
     50 
     51 Invoke the compiler using the --sysroot option to indicate where the system
     52 files for the platform you're targeting are located. For example, do:
     53 
     54     export CC="$NDK/toolchains/&lt;name&gt;/prebuilt/&lt;system&gt;/bin/&lt;prefix&gt;gcc --sysroot=$SYSROOT"
     55     $CC -o foo.o -c foo.c
     56 
     57 Where &lt;name&gt; is the toolchain's name, &lt;system&gt; is the host tag for your system,
     58 and &lt;prefix&gt; is a toolchain-specific prefix. For example, if you are on Linux
     59 using the NDK r5 toolchain, you would use:
     60 
     61     export CC="$NDK/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc --sysroot=$SYSROOT"
     62 
     63 As you can see, this is rather verbose, but it works!
     64 
     65 IMPORTANT NOTE:
     66 
     67     Using the NDK toolchain directly has a serious limitation:
     68     You won't be able to use any C++ STL (either STLport or
     69     the GNU libstdc++) with it. Also no exceptions and no RTTI.
     70 
     71 
     72 4/ Invoking the compiler (the easy way):
     73 ----------------------------------------
     74 
     75 The NDK allows you to create a "customized" toolchain installation to make
     76 life easier. For example, consider the following command:
     77 
     78   $NDK/build/tools/make-standalone-toolchain.sh --platform=android-5 --install-dir=/tmp/my-android-toolchain
     79 
     80 This will create a directory named /tmp/my-android-toolchain containing a
     81 copy of the android-5/arch-arm sysroot, and of the toolchain binaries.
     82 
     83 Note that by default, the 32-bit ARM-based GCC 4.6 toolchain will be selected by the script.
     84 Use the '--arch=x86' option to specify the x86 GCC 4.6, or add '--arch=mips' option
     85 to specify the MIPS GCC 4.6, or alternatively
     86 '--toolchain=&lt;name&gt;'.  For example:
     87 
     88   --toolchain=x86-4.4.3                  # select x86 GCC 4.4.3 compiler
     89   --toolchain=arm-linux-androideabi-4.7  # select ARM GCC 4.7 compiler
     90   --toolchain=mipsel-linux-android-4.6   # select MIPS GCC 4.6 compiler, same as --arch=mips
     91 
     92 If you wish, add '--llvm-version=3.1' to also copy clang/llvm 3.1, or
     93 use --toolchain with '-clang3.1' suffix.  For example:
     94 
     95   --toolchain=arm-linux-androideabi-clang3.1  # same as --arch=arm --llvm-version=3.1
     96 
     97 You may specify --system=linux-x86_64 on 64-bit Linux or --system=darwin-x86_64 on 64-bit
     98 MacOSX to make 64-bit host toolchain instead of the 32-bit one (default).
     99 See IV of NDK-BUILD.html
    100 
    101 You can later use it directly with something like:
    102 
    103    export PATH=/tmp/my-android-toolchain/bin:$PATH
    104    export CC=arm-linux-androideabi-gcc   # or export CC=clang
    105    export CXX=arm-linux-androideabi-g++  # or export CXX=clang++
    106 
    107 Note that without the --install-dir option, make-standalone-toolchain.sh will
    108 create a tarball in /tmp/ndk/&lt;toolchain-name&gt;.tar.bz2. This allows you to
    109 archive and redistribute the binaries easily.
    110 
    111 Another important benefit is that this standalone toolchain will contain a
    112 working copy of the GNU libstdc++, with working exceptions and RTTI support
    113 (as long as you link against libstdc++ or libsupc++)
    114 
    115 Use --help for more options and details.
    116 
    117 IMPORTANT: The toolchain binaries do not depend or contain host-specific paths,
    118            in other words, they can be installed in any location, or even
    119            moved if you need to.
    120 
    121 NOTE: You can still use the --sysroot option with the new toolchain, but it
    122       is now simply optional!
    123 
    124 
    125 5/ About Clang
    126 ---------------------
    127 
    128 Clang/clang++ uses the same assembler, linker, headers, libraries and GNU
    129 libstdc++ in the same standalone package.  Clang/clang++ are actually scripts
    130 with "-target" set to the specified architecture at creation.  For example, in
    131 ARM standalone package, clang is a one-liner:
    132 
    133    `dirname $0`/clang31 -target armv5te-none-linux-androideabi "$@"
    134 
    135 clang++ is another:
    136 
    137    `dirname $0`/clang++31 -target armv5te-none-linux-androideabi "$@"
    138 
    139 Note that for arm, clang will change target based on the presence of
    140 subsequent option "-march=armv7-a" and/or "-mthumb".  ie.
    141 
    142   1/ With "-march=armv7-a", -target becomes armv7-none-linux-androideabi
    143   2/ With "-mthumb", -target becomes thumb-none-linux-androideabi
    144   3/ With both, -target becomes thumbv7-none-linux-androideabi
    145 
    146 You may override with your own -target if you wish.
    147 
    148 Extra efforts have been made to make clang/clang++ easier drop-in
    149 replacements for gcc/g++ in Makefile.  When in doubt, use the following
    150 common techniques to check:
    151 
    152   1/ Add option "-v" to dump commands compiler driver issues
    153   2/ Add option "-###" to dump command line options, including those
    154      implicitly predefined.
    155   3/ Use "-x c /dev/null -dM -E" to dump predefined preprocessor definitions
    156   4/ Add option "-save-temps" and compare the preprocessed files *.i or *.ii
    157 
    158 See http://clang.llvm.org/, especially the GCC compatibility section.
    159 
    160 
    161 6/ ABI Compatibility:
    162 ---------------------
    163 
    164 The machine code generated by the ARM toolchain should be compatible with
    165 the official Android 'armeabi' ABI (see docs/CPU-ARCH-ABIS.html) by default.
    166 
    167 It is recommended to use the -mthumb compiler flag to force the generation
    168 of 16-bit Thumb-1 instructions (the default being 32-bit ARM ones).
    169 
    170 If you want to target the 'armeabi-v7a' ABI, you will need ensure that the
    171 following flags are being used:
    172 
    173   CFLAGS='-march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16'
    174 
    175 Note: The first flag enables Thumb-2 instructions, and the second one
    176       enables H/W FPU instructions while ensuring that floating-point
    177       parameters are passed in core registers, which is critical for
    178       ABI compatibility. Do *not* use these flags separately!
    179 
    180 If you want to use Neon instructions, you will need to change the -mfpu
    181 compiler flag:
    182 
    183   CFLAGS='-march=armv7-a -mfloat-abi=softfp -mfpu=neon'
    184 
    185 Note that this forces the use of VFPv3-D32, as per the ARM specification.
    186 
    187 Also, make sure the following two flags are provided to linker:
    188 
    189   LDFLAGS='-march=armv7-a -Wl,--fix-cortex-a8'
    190 
    191 Note: The first flag instructs linker to pick libgcc.a, libgcov.a and
    192       crt*.o tailored for armv7-a.  The 2nd flag is *required* to route
    193       around a CPU bug in some Cortex-A8 implementations:
    194 
    195 If none of the above makes sense to you, it's probably better not to use
    196 the standalone toolchain, and stick to the NDK build system instead, which
    197 will handle all the details for you.
    198 
    199 You don't have to use any specific compiler flag when targeting the x86 ABI
    200 or the MIPS ABI.
    201 
    202 7/ Warnings and Limitations:
    203 --------------------------
    204 
    205 7.1/ Windows support:
    206 - - - - - - - - - - -
    207 
    208 The Windows binaries do *not* depend on Cygwin. The good news is that they
    209 are thus faster, the bad news is that they do not understand the Cygwin
    210 path specification like /cygdrive/c/foo/bar (instead of C:/foo/bar).
    211 
    212 The NDK build system ensures that all paths passed to the compiler from Cygwin
    213 are automatically translated, and deals with other horrors for you. If you have
    214 a custom build system, you may need to deal with the problem yourself.
    215 
    216 NOTE: There is no plan to support Cygwin / MSys at the moment, but
    217       contributions are welcome. Contact the android-ndk forum for details.
    218 
    219 
    220 7.2/ wchar_t support:
    221 - - - - - - - - - - -
    222 
    223 As documented, the Android platform did not really support wchar_t until
    224 Android 2.3. What this means in practical terms is that:
    225 
    226   - If you target platform android-9 or higher, the size of wchar_t is
    227     4 bytes, and most wide-char functions are available in the C library
    228     (with the exception of multi-byte encoding/decoding functions and
    229      wsprintf/wsscanf).
    230 
    231   - If you target any prior API level, the size of wchar_t will be 1 byte
    232     and none of the wide-char functions will work anyway.
    233 
    234 We recommend any developer to get rid of any dependencies on the wchar_t type
    235 and switch to better representations. The support provided in Android is only
    236 there to help you migrate existing code.
    237 
    238 
    239 7.3/ Exceptions, RTTI and STL:
    240 - - - - - - - - - - - - - - -
    241 
    242 The toolchain binaries *do* support C++ exceptions and RTTI by default.
    243 They are enabled by default, so use -fno-exceptions and -fno-rtti if you
    244 want to disable them when building sources with them (e.g. to generate
    245 smaller machine code).
    246 
    247 NOTE: You will need to explicitly link with libsupc++ if you use these
    248       features. To do this, use -lsupc++ when linking binaries, as in:
    249 
    250     arm-linux-androideabi-g++ .... -lsupc++
    251 
    252 
    253 7.4/ C++ STL support:
    254 - - - - - - - - - - -
    255 
    256 The standalone toolchain also comes with a copy of the GNU libstdc++
    257 library, which provides an implementation of the C++ Standard Template
    258 Library. To use it, you however need to link with the proper library:
    259 
    260   * Use -lstdc++ to link against the _static_ library version. This ensures
    261     that all required C++ STL code is included into your final binary. This
    262     is ideal if you are only generating a single shared library or executable.
    263 
    264     This is the recommended way to do it.
    265 
    266   * Use -lgnustl_shared to link against the _shared_ library version. This
    267     is required if you have several related shared libraries or executables
    268     that need to run in the same address space at runtime (some global variables
    269     need to be defined uniquely, which is not possible if you link the static
    270     libstdc++ against each one of your executables).
    271 
    272     If you use this option, you need to ensure that libgnustl_shared.so is
    273     also copied to your device for your code to load properly. The file is
    274     at:
    275 
    276       $TOOLCHAIN/arm-linux-androideabi/lib/  for ARM toolchains.
    277       $TOOLCHAIN/i686-linux-android/lib/     for x86 ones.
    278       $TOOLCHAIN/mipsel-linux-android/lib/   for MIPS toolchains.
    279 
    280 
    281     IMPORTANT: The GNU libstdc++ is licensed under the GPLv3 with a
    282                linking exception. See the following URL for details:
    283 
    284           http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt01ch01s02.html
    285 
    286     If you cannot comply with its requirements, i.e. you cannot redistribute
    287     the shared library, do not use it in your project.
    288 
    289 The reason the shared version of GNU libstdc++ is not called libstdc++.so is
    290 because this would conflict at runtime with the system's own minimal C++
    291 runtime, which is /system/lib/libstdc++.so. This enforces a new name for the
    292 GNU ELF library. This is not a problem for the static library.
    293 
    294 </pre></body></html>
    295