• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<html><body><pre>USING THE ANDROID TOOLCHAIN AS A STANDALONE COMPILER
2======================================================
3
4It is now possible to use the toolchains provided with the Android NDK as
5standalone compilers. This can be useful if you already have your own build
6system, and only need to ability to invoke the cross-compiler to add support
7to Android for it.
8
9A typical use case if invoking the 'configure' script of an open-source
10library that expects a cross-compiler in the CC environment variable.
11
12
13This document explains how to do that:
14
151/ Selecting your toolchain:
16----------------------------
17
18Before anything else, you need to decide whether your standalone toolchain
19is going to target ARM-based devices, x86-based, or MIPS-based one.
20Each 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
262/ Selecting your sysroot:
27--------------------------
28
29The second thing you need to know is which Android native API level you want
30to target. Each one of them provides a different various APIs, which are
31documented under doc/STABLE-APIS.html, and correspond to the sub-directories
32of $NDK/platforms.
33
34This allows you to define the path to your 'sysroot', a GCC term for a
35directory containing the system headers and libraries of your target.
36Usually, this will be something like:
37
38   SYSROOT=$NDK/platforms/android-&lt;level&gt;/arch-&lt;arch&gt;/
39
40Where &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
42targeting Android 2.2 (a.k.a. Froyo), you would use:
43
44   SYSROOT=$NDK/platforms/android-8/arch-arm
45
46IMPORTANT: Note that X86 and MIPS architectures are only supported at android-9 and later.
47
483/ Invoking the compiler (the hard way):
49----------------------------------------
50
51Invoke the compiler using the --sysroot option to indicate where the system
52files 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
57Where &lt;name&gt; is the toolchain's name, &lt;system&gt; is the host tag for your system,
58and &lt;prefix&gt; is a toolchain-specific prefix. For example, if you are on Linux
59using 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
63As you can see, this is rather verbose, but it works!
64
65IMPORTANT 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
724/ Invoking the compiler (the easy way):
73----------------------------------------
74
75The NDK allows you to create a "customized" toolchain installation to make
76life 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
80This will create a directory named /tmp/my-android-toolchain containing a
81copy of the android-5/arch-arm sysroot, and of the toolchain binaries.
82
83Note that by default, the 32-bit ARM-based GCC 4.6 toolchain will be selected by the script.
84Use the '--arch=x86' option to specify the x86 GCC 4.6, or add '--arch=mips' option
85to 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
92If you wish, add '--llvm-version=3.1' to also copy clang/llvm 3.1, or
93use --toolchain with '-clang3.1' suffix.  For example:
94
95  --toolchain=arm-linux-androideabi-clang3.1  # same as --arch=arm --llvm-version=3.1
96
97You may specify --system=linux-x86_64 on 64-bit Linux or --system=darwin-x86_64 on 64-bit
98MacOSX to make 64-bit host toolchain instead of the 32-bit one (default).
99See IV of NDK-BUILD.html
100
101You 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
107Note that without the --install-dir option, make-standalone-toolchain.sh will
108create a tarball in /tmp/ndk/&lt;toolchain-name&gt;.tar.bz2. This allows you to
109archive and redistribute the binaries easily.
110
111Another important benefit is that this standalone toolchain will contain a
112working copy of the GNU libstdc++, with working exceptions and RTTI support
113(as long as you link against libstdc++ or libsupc++)
114
115Use --help for more options and details.
116
117IMPORTANT: 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
121NOTE: You can still use the --sysroot option with the new toolchain, but it
122      is now simply optional!
123
124
1255/ About Clang
126---------------------
127
128Clang/clang++ uses the same assembler, linker, headers, libraries and GNU
129libstdc++ in the same standalone package.  Clang/clang++ are actually scripts
130with "-target" set to the specified architecture at creation.  For example, in
131ARM standalone package, clang is a one-liner:
132
133   `dirname $0`/clang31 -target armv5te-none-linux-androideabi "$@"
134
135clang++ is another:
136
137   `dirname $0`/clang++31 -target armv5te-none-linux-androideabi "$@"
138
139Note that for arm, clang will change target based on the presence of
140subsequent 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
146You may override with your own -target if you wish.
147
148Extra efforts have been made to make clang/clang++ easier drop-in
149replacements for gcc/g++ in Makefile.  When in doubt, use the following
150common 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
158See http://clang.llvm.org/, especially the GCC compatibility section.
159
160
1616/ ABI Compatibility:
162---------------------
163
164The machine code generated by the ARM toolchain should be compatible with
165the official Android 'armeabi' ABI (see docs/CPU-ARCH-ABIS.html) by default.
166
167It is recommended to use the -mthumb compiler flag to force the generation
168of 16-bit Thumb-1 instructions (the default being 32-bit ARM ones).
169
170If you want to target the 'armeabi-v7a' ABI, you will need ensure that the
171following flags are being used:
172
173  CFLAGS='-march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16'
174
175Note: 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
180If you want to use Neon instructions, you will need to change the -mfpu
181compiler flag:
182
183  CFLAGS='-march=armv7-a -mfloat-abi=softfp -mfpu=neon'
184
185Note that this forces the use of VFPv3-D32, as per the ARM specification.
186
187Also, make sure the following two flags are provided to linker:
188
189  LDFLAGS='-march=armv7-a -Wl,--fix-cortex-a8'
190
191Note: 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
195If none of the above makes sense to you, it's probably better not to use
196the standalone toolchain, and stick to the NDK build system instead, which
197will handle all the details for you.
198
199You don't have to use any specific compiler flag when targeting the x86 ABI
200or the MIPS ABI.
201
2027/ Warnings and Limitations:
203--------------------------
204
2057.1/ Windows support:
206- - - - - - - - - - -
207
208The Windows binaries do *not* depend on Cygwin. The good news is that they
209are thus faster, the bad news is that they do not understand the Cygwin
210path specification like /cygdrive/c/foo/bar (instead of C:/foo/bar).
211
212The NDK build system ensures that all paths passed to the compiler from Cygwin
213are automatically translated, and deals with other horrors for you. If you have
214a custom build system, you may need to deal with the problem yourself.
215
216NOTE: 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
2207.2/ wchar_t support:
221- - - - - - - - - - -
222
223As documented, the Android platform did not really support wchar_t until
224Android 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
234We recommend any developer to get rid of any dependencies on the wchar_t type
235and switch to better representations. The support provided in Android is only
236there to help you migrate existing code.
237
238
2397.3/ Exceptions, RTTI and STL:
240- - - - - - - - - - - - - - -
241
242The toolchain binaries *do* support C++ exceptions and RTTI by default.
243They are enabled by default, so use -fno-exceptions and -fno-rtti if you
244want to disable them when building sources with them (e.g. to generate
245smaller machine code).
246
247NOTE: 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
2537.4/ C++ STL support:
254- - - - - - - - - - -
255
256The standalone toolchain also comes with a copy of the GNU libstdc++
257library, which provides an implementation of the C++ Standard Template
258Library. 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
289The reason the shared version of GNU libstdc++ is not called libstdc++.so is
290because this would conflict at runtime with the system's own minimal C++
291runtime, which is /system/lib/libstdc++.so. This enforces a new name for the
292GNU ELF library. This is not a problem for the static library.
293
294</pre></body></html>
295