diff options
Diffstat (limited to 'docs/html/ndk/guides/standalone_toolchain.jd')
-rw-r--r-- | docs/html/ndk/guides/standalone_toolchain.jd | 605 |
1 files changed, 605 insertions, 0 deletions
diff --git a/docs/html/ndk/guides/standalone_toolchain.jd b/docs/html/ndk/guides/standalone_toolchain.jd new file mode 100644 index 0000000..3b6f7f1 --- /dev/null +++ b/docs/html/ndk/guides/standalone_toolchain.jd @@ -0,0 +1,605 @@ +page.title=Standalone Toolchain +@jd:body + +<div id="qv-wrapper"> + <div id="qv"> + <h2>On this page</h2> + + <ol> + <li><a href="#syt">Selecting Your Toolchain</a></li> + <li><a href="#sys">Selecting Your Sysroot</a></li> + <li><a href="#itc">Invoking the Compiler</a></li> + <li><a href="#wwc">Working with Clang</a></li> + <li><a href="#abi">ABI Compatibility</a></li> + <li><a href="#war">Warnings and Limitations</a></li> + </ol> + </div> + </div> + +<p>You can use the toolchains provided with the Android NDK independently, or as plug-ins +with an existing IDE, such as Eclipse. This flexibility +can be useful if you already have your own build system, and only need the ability to invoke the +cross-compiler in order to add support to Android for it.</p> + +<p>A typical use case is invoking the configure script of an open-source library that expects a +cross-compiler in the {@code CC} environment variable.</p> + +<p class="note"><strong>Note:</strong> This page assumes significant understanding of +compiling, linking, and low-level architecture. In addition, the techniques it describes are +unnecessary for most use cases. In most cases, we recommend that you forego using a standalone +toolchain, and instead stick to the NDK build system.</p> + +<h2 id="syt">Selecting Your Toolchain</h2> +<p>Before anything else, you need to decide which processing architecture your standalone toolchain +is going to target. Each architecture corresponds to a different toolchain name, as Table 1 +shows.</p> + +<p class="table-caption" id="table1"> + <strong>Table 1.</strong> {@code APP_ABI} settings for different instruction sets.</p> +<table> + <tr> + <th scope="col">Architecture</th> + <th scope="col">Toolchain name</th> + </tr> + <tr> + <td>ARM-based</td> + <td>{@code arm-linux-androideabi-<gcc-version>}</td> + </tr> + <tr> + <td>x86-based</td> + <td>{@code x86-<gcc-version>}</td> + </tr> + <tr> + <td>MIPS-based</td> + <td>{@code mipsel-linux-android-<gcc-version>}</td> + </tr> + <tr> + <td>ARM64-based</td> + <td>{@code aarch64-linux-android-<gcc-version>}</td> + </tr> + <tr> + <td>X86-64-based</td> + <td>{@code x86_64-<gcc-version>}</td> + </tr> + <tr> + <td>MIPS64-based</td> + <td>{@code mips64el-linux-android--<gcc-version>}</td> + </tr> +</table> + + + +<h2 id="sys">Selecting Your Sysroot</h2> +<p>The next thing you need to do is define your <i>sysroot</i> (A sysroot is a directory containing +the system headers and libraries for your target). To define the sysroot, you must must know the +Android API level you want to target for native support; available native APIs vary by Android API +level.</p> + +<p>Native APIs for the respective <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html"> +Android API levels</a> reside under {@code $NDK/platforms/}; each API-level +directory, in turn, contains subdirectories for the various CPUs and architectures. The +following example shows how to define a <em>sysroot</em> for a build targeting Android 5.0 +(API level 21), for ARM architecture:</p> + +<pre class="no-pretty-print"> +SYSROOT=$NDK/platforms/android-21/arch-arm +</pre> + +For more detail about the Android API levels and the respective native APIs they support, see +<a href={@docRoot}ndk/guides/stable_apis.html>Android NDK Native APIs</a>. + +<h2 id="itc">Invoking the Compiler</h2> + +<p>There are two ways to invoke the compiler. One method is simple, and leaves most of the lifting +to the build system. The other is more advanced, but provides more flexibility.</p> + +<h3 id="sm">Simple method</h3> +<p>The simplest way to build is by invoking the appropriate compiler directly from the command +line, using the {@code --sysroot} option to indicate the location of the system files for the +platform you're targeting. For example:</p> + +<pre class="no-pretty-print"> +export CC="$NDK/toolchains/arm-linux-androideabi-4.8/prebuilt/ \ +linux-x86/bin/arm-linux-androideabi-gcc-4.8 --sysroot=$SYSROOT" +$CC -o foo.o -c foo.c +</pre> + +<p>While this method is simple, it lacks in flexibility: It does not allow you to use any C++ STL +(STLport, libc++, or the GNU libstdc++) with it. It also does not support exceptions or RTTI.</p> + +<p>For Clang, you need to perform an additional two steps:</p> +<ul> +<ol type="1"> +<li>Add the appropriate {@code -target} for the target architecture, as Table 2 shows.</li> + +<p class="table-caption" id="table2"> + <strong>Table 2.</strong> Architectures and corresponding values for {@code -target}.</p> + <table> + <tr> + <th scope="col">Architecture</th> + <th scope="col">Value</th> + </tr> + <tr> + <td>armeabi</td> + <td>{@code -target armv5te-none-linux-androideabi}</td> + </tr> + <tr> + <td>armeabi-v7a</td> + <td>{@code -target armv7-none-linux-androideabi}</td> + </tr> + <tr> + <td>arm64-v8a</td> + <td>{@code -target aarch64-none-linux-android}</td> + </tr> + <tr> + <td>x86</td> + <td>{@code -target i686-none-linux-android}</td> + </tr> + <tr> + <td>x86_64</td> + <td>{@code -target x86_64-none-linux-android}</td> + </tr> + <tr> + <td>mips</td> + <td>{@code -target mipsel-none-linux-android}</td> + </tr> +</table> + +<li>Add assembler and linker support by adding the {@code -gcc-toolchain} option, as in the +following example:</li> +<pre class="no-pretty-print"> +-gcc-toolchain $NDK/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64 +</pre> +</ol> + +Ultimately, a command to compile using Clang might look like this: + +<pre class="no-pretty-print"> +export CC="$NDK/toolchains/arm-linux-androideabi-4.8/prebuilt/ \ +linux-x86/bin/arm-linux-androideabi-gcc-4.8 --sysroot=$SYSROOT" -target \ +armv7-none-linux-androideabi \ +-gcc-toolchain $NDK/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64" +$CC -o foo.o -c foo.c +</pre> +</ul> + +<h3>Advanced method</h3> +<p>The NDK provides the {@code make-standalone-toolchain.sh} shell script to allow you to perform a +customized toolchain installation from the command line. This approach affords you more flexibility +than the procedure described in <a href="#sm">Simple method</a>.</p> + +<p>The script is located in the {@code $NDK/build/tools/} directory, where {@code $NDK} is the +installation root for the NDK. An example of the use of this script appears below:</p> + +<pre class="no-pretty-print"> +$NDK/build/tools/make-standalone-toolchain.sh \ +--arch=arm --platform=android-21 --install-dir=/tmp/my-android-toolchain +</pre> + +<p>This command creates a directory named {@code /tmp/my-android-toolchain/}, containing a copy of +the {@code android-21/arch-arm} sysroot, and of the toolchain binaries for a 32-bit ARM +architecture.</p> + +<p>Note that the toolchain binaries do not depend on or contain host-specific paths, in other words, +you can install them in any location, or even move them if you need to.</p> + +<p>By default, the build system uses the 32-bit, ARM-based GCC 4.8 toolchain. You can specify a +different value, however, by specifying {@code --arch=<toolchain>} as an option. +Table 3 shows the values to use for other toolchains: + +<p class="table-caption" id="table3"> + <strong>Table 3.</strong> Toolchains and corresponding values, using {@code --arch}.</p> + <table> + <tr> + <th scope="col">Toolchain</th> + <th scope="col">Value</th> + </tr> + <tr> + <td>mips64 compiler</td> + <td>{@code --arch=mips64}</td> + </tr> + <tr> + <td>mips GCC 4.8 compiler</td> + <td>{@code --arch=mips}</td> + </tr> + <tr> + <td>x86 GCC 4.8 compiler</td> + <td>{@code --arch=x86}</td> + </tr> + <tr> + <td>x86_64 GCC 4.8 compiler</td> + <td>{@code --arch=x86_64}</td> + </tr> + <tr> + <td>mips GCC 4.8 compiler</td> + <td>{@code --arch=mips}</td> + </tr> +</table> + +<p>Alternatively, you can use the {@code --toolchain=<toolchain>} option. Table 4 shows the +values you can specify for {@code <toolchain>}:</p> + +<p class="table-caption" id="table4"> + <strong>Table 4.</strong> Toolchains and corresponding values, using {@code --toolchain}.</p> + <table> + <tr> + <th scope="col">Toolchain</th> + <th scope="col">Value</th> + </tr> + + <tr> + <td>arm</td> + <td> + <li>{@code --toolchain=arm-linux-androideabi-4.8}</li> + <li>{@code --toolchain=arm-linux-androideabi-4.9}</li> + <li>{@code --toolchain=arm-linux-android-clang3.5}</li> + <li>{@code --toolchain=arm-linux-android-clang3.6}</li> + </td> + </tr> + <tr> + <td>x86</td> + <td> + <li>{@code --toolchain=x86-linux-android-4.8}</li> + <li>{@code --toolchain=x86-linux-android-4.9}</li> + <li>{@code --toolchain=x86-linux-android-clang3.5}</li> + <li>{@code --toolchain=x86-linux-android-clang3.6}</li> + </td> + </tr> + <tr> + <td>mips</td> + <td> + <li>{@code --toolchain=mips-linux-android-4.8}</li> + <li>{@code --toolchain=mips-linux-android-4.9}</li> + <li>{@code --toolchain=mips-linux-android-clang3.5}</li> + <li>{@code --toolchain=mips-linux-android-clang3.6}</li> + </td> + </tr> + + <tr> + <td>arm64</td> + <td> + <li>{@code --toolchain=aarch64-linux-android-4.9}</li> + <li>{@code --toolchain=aarch64-linux-android-clang3.5}</li> + <li>{@code --toolchain=aarch64-linux-android-clang3.6}</li> + </td> + </tr> + <tr> + <td>x86_64</td> + <td> + <li>{@code --toolchain=x86_64-linux-android-4.9}</li> + <li>{@code --toolchain=x86_64-linux-android-clang3.5}</li> + <li>{@code --toolchain=x86_64-linux-android-clang3.6}</li> + </td> + </tr> + <tr> + <td>mips64</td> + <td> + <li>{@code --toolchain=mips64el-linux-android-4.9}</li> + <li>{@code --toolchain=mips64el-linux-android-clang3.5}</li> + <li>{@code --toolchain=mips64el-linux-android-clang3.6}</li> + </td> + </tr> +</table> + +<p class="note"><strong>Note: </strong> Table 4 is not an exhaustive list. Other combinations may +also be valid, but are unverified.</p> + +<p>You can also copy Clang/LLVM 3.6, using one of two methods: You can append {@code -clang3.6} to +the {@code --toolchain} option, so that the {@code --toolchain} option looks like the following +example: + +<pre class="no-pretty-print"> +--toolchain=arm-linux-androideabi-clang3.6 +</pre> + +<p>You can also add {@code -llvm-version=3.6} as a separate option on the command +line.</p> + +<p class="note"><strong>Note: </strong>Instead of specifying a specific version, you can also +use {@code <version>}, which defaults +to the highest available version of Clang.</p> + +<p>By default, the build system builds for a 32-bit host toolchain. You can specify a 64-bit +host toolchain instead. Table 5 shows the value to use with {@code -system} for different +platforms.</p> + +<p class="table-caption" id="table5"> + <strong>Table 5.</strong> Host toolchains and corresponding values, using {@code -system}.</p> + <table> + <tr> + <th scope="col">Host toolchain</th> + <th scope="col">Value</th> + </tr> + <tr> + <td>64-bit Linux</td> + <td>{@code -system=linux-x86_64}</td> + </tr> + <tr> + <td>64-bit MacOSX</td> + <td>{@code -system=darwin-x86_64}</td> + </tr> + <tr> + <td>64-bit Windows</td> + <td>{@code -system=windows-x86_64}</td> + </tr> +</table> + +For more information on specifying a 64- or 32-bit instruction host toolchain, see +<a href="{@docRoot}ndk/guides/ndk-build.html#6432">64-Bit and 32-Bit Toolchains</a>. + +<p>You may specify {@code --stl=stlport} to copy {@code libstlport} instead of the default +{@code libgnustl}. If you do so, and you wish to link against the shared library, you must +explicitly use {@code -lstlport_shared}. This requirement is similar to having to use +{@code -lgnustl_shared} for GNU {@code libstdc++}.</p> + +<p>Similarly, you can specify {@code --stl=libc++} to copy the LLVM libc++ headers and libraries. +To link against the shared library, you must explicitly use -lc++_shared.</p> + +<p>You can make these settings directly, as in the following example:</p> + +<pre class="no-pretty-print"> +export PATH=/tmp/my-android-toolchain/bin:$PATH +export CC=arm-linux-androideabi-gcc # or export CC=clang +export CXX=arm-linux-androideabi-g++ # or export CXX=clang++ +</pre> + +<p>Note that if you omit the {@code -install-dir} option, the {@code make-standalone-toolchain.sh} +shell script creates a tarball in {@code tmp/ndk/<toolchain-name>.tar.bz2}. This tarball makes +it easy to archive, as well as to redistribute the binaries.</p> + +<p>This standalone toolchain provides an additional benefit, as well, in that it contains a working +copy of a C++ STL library, with working exceptions and RTTI support.</p> + +<p>For more options and details, use {@code --help}.</p> + +<h2 id="wwc">Working with Clang</h2> +<p>You can install Clang binaries in the standalone installation by using the +{@code --llvm-version=<version>} option. {@code <version>} is a LLVM/Clang version +number, such as {@code 3.5} or {@code 3.6}. For example: + +<pre class="no-pretty-print"> +build/tools/make-standalone-toolchain.sh \ +--install-dir=/tmp/mydir \ +--toolchain=arm-linux-androideabi-4.8 \ +--llvm-version=3.6 +</pre> + +<p>Note that Clang binaries are copied along with the GCC ones, because they rely on the same +assembler, linker, headers, libraries, and C++ STL implementation.</p> + +<p>This operation also installs two scripts, named {@code clang} and {@code clang++}, under +{@code <install-dir>/bin/@}. These scripts invoke the real {@code clang} binary with default +target architecture flags. In other words, they should work without any modification, and you should +be able to use them in your own builds by just setting the {@code CC} and {@code CXX} environment +variables to point to them.</p> + +<h4>Invoking Clang</h4> +<p>In an ARM standalone installation built with {@code llvm-version=3.6}, invoking +<a href="http://clang.llvm.org/">Clang</a> on a Unix system takes the form of a single line. For +instance:</p> + +<pre class="no-pretty-print"> +`dirname $0`/clang36 -target armv5te-none-linux-androideabi "$@" +</pre> + +<p><code>clang++</code> invokes <code>clang++31</code> in the same way.</p> + +<h4>Clang targets with ARM</h4> + +<p>When building for ARM, Clang changes the target based on the presence of the +{@code -march=armv7-a} and/or {@code -mthumb} options:</p> + +<p class="table-caption" id="table5"> + <strong>Table 5.</strong> Specifiable {@code -march} values and their resulting targets.</p> + <table> + <tr> + <th scope="col">{@code -march} value</th> + <th scope="col">Resulting target</th> + </tr> + <tr> + <td>{@code -march=armv7-a}</td> + <td>{@code armv7-none-linux-androideabi}</td> + </tr> + <tr> + <td>{@code -mthumb}</td> + <td>{@code thumb-none-linux-androideabi}</td> + </tr> + <tr> + <td>Both {@code -march=armv7-a} and {@code -mthumb}</td> + <td>{@code thumbv7-none-linux-androideabi}</td> + </tr> +</table> + +<p>You may also override with your own {@code -target} if you wish.</p> + +<p>The {@code -gcc-toolchain} option is unnecessary because, in a standalone package, +Clang locates {@code as} and {@code ld} in a predefined relative location. <p> + +<p>{@code clang} and {@code clang++} should be easy drop-in replacements for {@code gcc} and +{@code g++} in a makefile. When in doubt, add the following options to verify that they are +working properly:</p> + +<ul> +<li>{@code -v} to dump commands associated with compiler driver issues</li> +<li>{@code -###} to dump command line options, including implicitly predefined ones.</li> +<li>{@code -x c < /dev/null -dM -E} to dump predefined preprocessor definitions</li> +<li>{@code -save-temps} to compare {@code *.i} or {@code *.ii} preprocessed files.</li> +</ul> + +<p>For more information about Clang, see +<a href="http://clang.llvm.org/">http://clang.llvm.org/</a>, especially the GCC compatibility +section.</p> + + +<h2 id="abi">ABI Compatibility</h2> +<p>The machine code that the ARM toolchain generates should be compatible with the official Android +{@code armeabi} <a href="{@docRoot}ndk/guides/abis.html">ABI</a> by default.</p> + +<p>We recommend use of the {@code -mthumb} compiler flag to force the generation of 16-bit Thumb-1 +instructions (the default being 32-bit ARM instructions).</p> + +<p>If you want to target the armeabi-v7a ABI, you must set the following flags: </p> + +<pre class="no-pretty-print"> +CFLAGS= -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 +</pre> + +<p>The first flag enables Thumb-2 instructions. The second flag enables hardware-FPU instructions +while ensuring that the system passes floating-point parameters in core registers, which is critical +for ABI compatibility.</p> + +<p class="note"><strong>Note: </strong>In versions of the NDK prior to r9b, do not use these flags +separately. You must set all or none of them. Otherwise, unpredictable behavior and crashes may +result.</p> + +<p>To use NEON instructions, you must change the {@code -mfpu} compiler flag:</p> + +<pre class="no-pretty-print"> +CFLAGS= -march=armv7-a -mfloat-abi=softfp -mfpu=neon +</pre> + +<p>Note that this setting forces the use of {@code VFPv3-D32}, per the ARM specification.</p> + +<p>Also, make sure to provide the following two flags to the linker:</p> + +<pre class="no-pretty-print"> +LDFLAGS= -march=armv7-a -Wl,--fix-cortex-a8 +</pre> + +<p>The first flag instructs the linker to pick {@code libgcc.a}, {@code libgcov.a}, and +{@code crt*.o}, which are tailored for armv7-a. The 2nd flag is required as a workaround for a CPU +bug in some Cortex-A8 implementations.</p> + +<p>Since NDK version r9b, all Android native APIs taking or returning double or float values have +{@code attribute((pcs("aapcs")))} for ARM. This makes it possible to compile user code in +{@code -mhard-float} (which implies {@code -mfloat-abi=hard}), and still link with the Android +native APIs that comply with the softfp ABI. For more information on this, see the comments in +{@code $NDK/tests/device/hard-float/jni/Android.mk}.</p> + +<p>If you want to use NEON intrinsics on x86, the build system can translate them to the native x86 +SSE intrinsics using a special C/C++ language header with the same name, {@code arm_neon.h}, as the +standard ARM NEON intrinsics header.</p> + +<p>By default, the x86 ABI supports SIMD up to SSSE3, and the header covers ~93% of (1869 of 2009) +NEON functions.</p> + +<p>You don't have to use any specific compiler flag when targeting the MIPS ABI.</p> + +<p>To learn more about ABI support, see <a href="{@docRoot}ndk/guides/x86.html">x86 Support</a>.</p> + +<h2 id="war">Warnings and Limitations</h2> +<h3>Windows support</h3> +<p>The Windows binaries do not depend on Cygwin. This lack of dependency makes them faster. The +cost, however, is that they do not understand Cygwin path specifications like +{@code cygdrive/c/foo/bar}, as opposed to {@code C:/foo/bar}.</p> + +<p>The NDK build system ensures that all paths passed to the compiler from Cygwin are automatically +translated, and manages other complexities, as well. If you have a custom build system, +you may need to resolve these complexities yourself.</p> + +<p>For information on contributing to support for Cygwin/MSys, visit the android-ndk +<a href="https://groups.google.com/forum/#!forum/android-ndk">forum</a>.</p> + +<h3>wchar_t support</h3> + +<p>The Android platform did not really support {@code wchar_t} until Android 2.3 (API level 9). This +fact has several ramifications:</p> +<ul> +<li>If you target platform Android 2.3 or higher, the size of {@code wchar_t} is 4 bytes, and most +{@code wide-char} functions are available in the C library (with the exception of multi-byte +encoding/decoding functions and {@code wsprintf}/{@code wsscanf}).</li> + +<li>If you target any lower API level, the size of {@code wchar_t} is 1 byte, and none of the +wide-char functions works.</li> +</ul> + +<p>We recommend that you get rid of any dependencies on the {@code wchar_t} type, and switch to +better representations. The support provided in Android is only there to help you migrate existing +code.</p> + +<h3>Exceptions, RTTI, and STL</h3> +<p>The toolchain binaries support C++ exceptions and RTTI by default. To disable C++ exceptions +and RTTI when building sources (to generate lighter-weight machine code, for example), use +{@code -fno-exceptions} and {@code -fno-rtti}.</p> + +<p>To use these features in conjunction with GNU libstdc++, you must explicitly link with libsupc++. +To do so, use {@code -lsupc++} when linking binaries. For example:</p> + +<pre class="no-pretty-print"> +arm-linux-androideabi-g++ .... -lsupc++ +</pre> + +<p>You do not need to do this when using the STLport or libc++ library.</p> + +<h3>C++ STL support</h3> +<p>The standalone toolchain includes a copy of a C++ Standard Template Library implementation. This +implementation is either for GNU libstdc++, STLport, or libc++, depending on what you specify for the +{@code --stl=<name>} option described previously. To use this implementation of STL, you need +to link your project with the proper library:</p> + +<ul> +<li> +Use {@code -lstdc++} to link against the static library version of any implementation. Doing so +ensures that all required C++ STL code is included into your final binary. This method is ideal if +you are only generating a single shared library or executable.</p> + +<p>This is the method that we recommend.</p> +</li> + +<li>Alternatively, use {@code -lgnustl_shared} to link against the shared library version of GNU +{@code libstdc++}. If you use this option, you must also make sure to copy +{@code libgnustl_shared.so} to your device in order for your code to load properly. Table 6 shows +where this file is for each toolchain type. +</li> + +<p class="note"><strong>Note: </strong>GNU libstdc++ is licensed under the GPLv3 license, with a +linking exception. If you cannot comply with its requirements, you cannot redistribute the +shared library in your project.</p> + + +<li>Use {@code -lstlport_shared} to link against the shared library version of STLport. When you do +so, you need to make sure that you also copy {@code libstlport_shared.so} to your device in order +for your code to load properly. Table 6 shows where this file is for each toolchain:</li> + +<p class="table-caption" id="table6"> + <strong>Table 6.</strong> Specifiable {@code -march} values and their resulting targets.</p> + <table> + <tr> + <th scope="col">Toolchain</th> + <th scope="col">Location</th> + </tr> + <tr> + <td>arm</td> + <td>{@code $TOOLCHAIN/arm-linux-androideabi/lib/}</td> + </tr> + <tr> + <td>arm64</td> + <td>{@code $TOOLCHAIN/aarch64-linux-android/lib/}</td> + </tr> + <tr> + <td>x86</td> + <td>{@code $TOOLCHAIN/i686-linux-android/lib/}</td> + </tr> + <tr> + <td>x86_64</td> + <td>{@code $TOOLCHAIN/x86_64-linux-android/lib/}</td> + </tr> + <tr> + <td>mips</td> + <td>{@code $TOOLCHAIN/mipsel-linux-android/lib/}</td> + </tr> + <tr> + <td>mips64</td> + <td>{@code $TOOLCHAIN/mips64el-linux-android/lib/}</td> + </tr> +</table> + +<p class="note"><strong>Note: </strong>If your project contains multiple shared libraries or +executables, you must link against a shared-library STL implementation. Otherwise, the build +system does not define certain global uniquely, which can result in unpredictable runtime behavior. +This behavior may include crashes and failure to properly catch exceptions.</p> + +<p>The reason the shared version of the libraries is not simply called {@code libstdc++.so} is that +this name would conflict at runtime with the system's own minimal C++ runtime. For this reason, +the build system enforces a new name for the GNU ELF library. The static library does not have +this problem.</p> |