1 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-<level>/arch-<arch>/ 39 40 Where <level> is the API level number, and <arch> 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/<name>/prebuilt/<system>/bin/<prefix>gcc --sysroot=$SYSROOT" 55 $CC -o foo.o -c foo.c 56 57 Where <name> is the toolchain's name, <system> is the host tag for your system, 58 and <prefix> 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=<name>'. For example: 87 88 --toolchain=x86-4.8 # select x86 GCC 4.8 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.3' to also copy clang/llvm 3.3, or 93 use --toolchain with '-clang3.3' suffix. For example: 94 95 --toolchain=arm-linux-androideabi-clang3.3 # same as --arch=arm --llvm-version=3.3 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 may specify --stl=stlport to copy libstlport instead of libgnustl. Note that 102 to link against the shared library, you will have to explicitely use -lstlport_shared 103 in this case, just like you need to use -lgnustl_shared for the GNU libstdc++ case. 104 Static linking doesn't require anything special. 105 106 You can later use it directly with something like: 107 108 export PATH=/tmp/my-android-toolchain/bin:$PATH 109 export CC=arm-linux-androideabi-gcc # or export CC=clang 110 export CXX=arm-linux-androideabi-g++ # or export CXX=clang++ 111 112 Note that without the --install-dir option, make-standalone-toolchain.sh will 113 create a tarball in /tmp/ndk/<toolchain-name>.tar.bz2. This allows you to 114 archive and redistribute the binaries easily. 115 116 Another important benefit is that this standalone toolchain will contain a 117 working copy of a C++ STL library, with working exceptions and RTTI support. 118 119 Use --help for more options and details. 120 121 > IMPORTANT: The toolchain binaries do not depend or contain host-specific paths, 122 in other words, they can be installed in any location, or even 123 moved if you need to. 124 125 > NOTE: You can still use the --sysroot option with the new toolchain, but it 126 is now simply optional! 127 128 129 5/ About Clang 130 --------------------- 131 132 It is possible to also install Clang binaries in the standalone 133 installation by using the --llvm-version=<version> option, where 134 <version> is a LLVM/Clang version number (e.g. `3.2` or `3.3`). E.g.: 135 136 build/tools/make-standalone-toolchain.sh \ 137 --install-dir=/tmp/mydir \ 138 --toolchain=arm-linux-androideabi-4.7 \ 139 --llvm-version=3.3 140 141 Note that Clang binaries are copied in addition to the GCC ones, because 142 they rely on the same assembler, linker, headers, libraries and C++ 143 STL implementation. 144 145 This also installs two scripts under <install-dir>/bin/ named '`clang`' 146 and '`clang++`' which invoke the real clang binary with default 147 target architecture flags. In other words, they should "just work" and 148 you should be able to use them in your own builds by setting CC and CXX 149 environment variables to point to them. 150 151 The rest of this section gives more detail about how these work, in case 152 you encounter some unexpected problems. 153 154 For example, in an ARM standalone installation built with 155 `--llvm-version=3.3`, `clang` is a one-liner that looks like this on Unix: 156 157 `dirname $0`/clang31 -target armv5te-none-linux-androideabi "$@" 158 159 And `clang++` invokes `clang++31` in the same way. 160 161 Note that for ARM, `clang` will change target based on the presence of 162 subsequent option "`-march=armv7-a`" and/or "`-mthumb`". ie. 163 164 1. With "`-march=armv7-a`", -target becomes `armv7-none-linux-androideabi`. 165 2. With "`-mthumb`", -target becomes `thumb-none-linux-androideabi`. 166 3. With both, -target becomes `thumbv7-none-linux-androideabi`. 167 168 You may override with your own -target if you wish. 169 170 Extra efforts have been made to make clang/clang++ easier drop-in 171 replacements for gcc/g++ in Makefile. When in doubt, use the following 172 common techniques to check: 173 174 1. Add option "`-v`" to dump commands compiler driver issues 175 2. Add option "`-###`" to dump command line options, including those 176 implicitly predefined. 177 3. Use "`-x c` `/dev/null` `-dM` `-E`" to dump predefined preprocessor definitions 178 4. Add option "`-save-temps`" and compare the preprocessed files `*.i` or `*.ii` 179 180 See http://clang.llvm.org/ , especially the GCC compatibility section. 181 182 183 6/ ABI Compatibility: 184 --------------------- 185 186 The machine code generated by the ARM toolchain should be compatible with 187 the official Android 'armeabi' ABI (see docs/CPU-ARCH-ABIS.html) by default. 188 189 It is recommended to use the -mthumb compiler flag to force the generation 190 of 16-bit Thumb-1 instructions (the default being 32-bit ARM ones). 191 192 If you want to target the 'armeabi-v7a' ABI, you will need ensure that the 193 following flags are being used: 194 195 CFLAGS='-march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16' 196 197 Note: The first flag enables Thumb-2 instructions, and the second one 198 enables H/W FPU instructions while ensuring that floating-point 199 parameters are passed in core registers, which is critical for 200 ABI compatibility. Do *not* use these flags separately! 201 202 If you want to use Neon instructions, you will need to change the -mfpu 203 compiler flag: 204 205 CFLAGS='-march=armv7-a -mfloat-abi=softfp -mfpu=neon' 206 207 Note that this forces the use of VFPv3-D32, as per the ARM specification. 208 209 Also, make sure the following two flags are provided to linker: 210 211 LDFLAGS='-march=armv7-a -Wl,--fix-cortex-a8' 212 213 Note: The first flag instructs linker to pick libgcc.a, libgcov.a and 214 crt*.o tailored for armv7-a. The 2nd flag is *required* to route 215 around a CPU bug in some Cortex-A8 implementations: 216 217 If none of the above makes sense to you, it's probably better not to use 218 the standalone toolchain, and stick to the NDK build system instead, which 219 will handle all the details for you. 220 221 You don't have to use any specific compiler flag when targeting the x86 ABI 222 or the MIPS ABI. 223 224 7/ Warnings and Limitations: 225 -------------------------- 226 227 ### 7.1/ Windows support: 228 229 The Windows binaries do *not* depend on Cygwin. The good news is that they 230 are thus faster, the bad news is that they do not understand the Cygwin 231 path specification like `/cygdrive/c/foo/bar` (instead of `C:/foo/bar`). 232 233 The NDK build system ensures that all paths passed to the compiler from Cygwin 234 are automatically translated, and deals with other horrors for you. If you have 235 a custom build system, you may need to deal with the problem yourself. 236 237 NOTE: There is no plan to support Cygwin / MSys at the moment, but 238 contributions are welcome. Contact the android-ndk forum for details. 239 240 241 ### 7.2/ wchar_t support: 242 243 As documented, the Android platform did not really support wchar_t until 244 Android 2.3. What this means in practical terms is that: 245 246 - If you target platform android-9 or higher, the size of wchar_t is 247 4 bytes, and most wide-char functions are available in the C library 248 (with the exception of multi-byte encoding/decoding functions and 249 wsprintf/wsscanf). 250 251 - If you target any prior API level, the size of wchar_t will be 1 byte 252 and none of the wide-char functions will work anyway. 253 254 We recommend any developer to get rid of any dependencies on the wchar_t type 255 and switch to better representations. The support provided in Android is only 256 there to help you migrate existing code. 257 258 259 ### 7.3/ Exceptions, RTTI and STL: 260 261 The toolchain binaries *do* support C++ exceptions and RTTI by default. 262 They are enabled by default, so use -fno-exceptions and -fno-rtti if you 263 want to disable them when building sources with them (e.g. to generate 264 smaller machine code). 265 266 NOTE: If you use the GNU libstdc++, you will need to explicitly link with 267 libsupc++ if you use these features. To do this, use -lsupc++ when 268 linking binaries, as in: 269 270 arm-linux-androideabi-g++ .... -lsupc++ 271 272 This is not needed when using the STLport library. 273 274 275 ### 7.4/ C++ STL support: 276 277 The standalone toolchain includes a copy of a C++ Standard Template Library 278 implementation, either the GNU libstdc++, or STLport, determined by your 279 use of the --stl=<name> option described previously. To use this STL 280 implementation, you however need to link your project with the proper 281 library: 282 283 * Use -lstdc++ to link against the _static_ library version of any 284 implementation. This ensures that all required C++ STL code is 285 included into your final binary. This is ideal if you are only 286 generating a **single** shared library or executable. 287 288 This is the recommended way to do it. 289 290 * Use -lgnustl_shared to link against the _shared_ library version of 291 GNU libstdc++. If you use this option, you need to ensure that 292 `libgnustl_shared.so` is also copied to your device for your code to 293 load properly. The file is at: 294 295 $TOOLCHAIN/arm-linux-androideabi/lib/ for ARM toolchains. 296 $TOOLCHAIN/i686-linux-android/lib/ for x86 ones. 297 $TOOLCHAIN/mipsel-linux-android/lib/ for MIPS toolchains. 298 299 IMPORTANT: The GNU libstdc++ is licensed under the **GPLv3** with a 300 linking exception. See the following URL for details: 301 302 > http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt01ch01s02.html 303 304 > If you cannot comply with its requirements, i.e. you cannot redistribute 305 the shared library, do not use it in your project. 306 307 * Use -stlport_shared to link against the _shared_ library version of 308 STLport. If you use this option, you need to ensure that 309 `libstlport_shared.so` is also copied to your device for your code 310 to load properly. They are found at the same locations than those 311 for `gnustl_shared`. 312 313 **VERY** **IMPORTANT** **NOTE**: 314 If your project contains _multiple_ shared libraries or 315 executables, you **must** link against a shared library STL implementation. 316 Otherwise, some global variables won't be defined uniquely, which can 317 result in all kind of weird behaviour at runtime, like crashes, exceptions 318 not being caught properly, and more surprises. 319 320 The reason the shared version of the libraries is not simply called 321 `libstdc++.so` is not called libstdc++.so is because this would conflict 322 at runtime with the system's own minimal C++ runtime, which is 323 `/system/lib/libstdc++.so`. This enforces a new name for the GNU ELF 324 library. This is not a problem for the static library. 325