| page.title=ABI Management |
| @jd:body |
| |
| <div id="qv-wrapper"> |
| <div id="qv"> |
| <h2>On this page</h2> |
| |
| <ol> |
| <li><a href="#sa">Supported ABIs</a></li> |
| <li><a href="#gc">Generating Code for a Specific ABI</a></li> |
| <li><a href="#am">ABI Management on the Android Platform</a></li> |
| </ol> |
| </div> |
| </div> |
| |
| <p>Different Android handsets use different CPUs, which in turn support different instruction sets. |
| Each combination of CPU and instruction sets has its own Application Binary Interface, or |
| <i>ABI</i>. The ABI defines, with great precision, how an application's machine code is supposed to |
| interact with the system at runtime. You must specify an ABI for each CPU architecture you want |
| your app to work with.</p> |
| |
| <p>A typical ABI includes the following information:</p> |
| |
| <ul> |
| <li>The CPU instruction set(s) that the machine code should use.</li> |
| <li>The endianness of memory stores and loads at runtime.</li> |
| <li>The format of executable binaries, such as programs and shared libraries, and |
| the types of content they support.</li> |
| <li>Various conventions for passing data between your code and the system. |
| These conventions include alignment constraints, as well as how the system uses the stack and |
| registers when it calls functions.</li> |
| <li>The list of function symbols available to your machine code at runtime, |
| generally from very specific sets of libraries.</li> |
| </ul> |
| |
| <p>This page enumerates the ABIs that the NDK supports, and provides information about how each ABI |
| works.</p> |
| |
| <h2 id="sa">Supported ABIs</h2> |
| |
| <p>Each ABI supports one or more instruction sets. Table 1 provides an at-a-glance overview of |
| the instruction sets each ABI supports.</p> |
| |
| <p class="table-caption" id="abi-table"> |
| <strong>Table 1.</strong> ABIs and supported instruction sets.</p> |
| |
| <table> |
| <tr> |
| <th>ABI</th> |
| <th>Supported Instruction Set(s)</th> |
| <th>Notes</th> |
| </tr> |
| |
| <tr> |
| <td><a href="#armeabi">{@code armeabi}</a> </td> |
| <td><li>ARMV5TE and later</li> |
| <li>Thumb-1</li></td> |
| <td>No hard float.</td> |
| </tr> |
| |
| <tr> |
| <td><a href="#v7a">{@code armeabi-v7a}</a></td> |
| <td> |
| <li>armeabi</li> |
| <li>Thumb-2</li> |
| <li>VFPv3-D16</li> |
| <li>Other, optional</li></td> |
| <td>Incompatible with ARMv5, v6 devices.</td> |
| </tr> |
| |
| <tr> |
| <td><a href="#arm64-v8a">{@code arm64-v8a}</a></td> |
| <td><li>AArch-64</li></td> |
| </tr> |
| |
| <tr> |
| <td> |
| <a href="#x86">{@code x86}</a></td> |
| <td><li>x86 (IA-32)</li> |
| <li>MMX</li> |
| <li>SSE/2/3</li> |
| <li>SSSE3</li></td> |
| <td>No support for MOVBE or SSE4.</td> |
| </tr> |
| |
| <tr> |
| <td><a href="#86-64">{@code x86_64}</a> </td> |
| <td> |
| <li>x86-64</li> |
| <li>MMX</li> |
| <li>SSE/2/3</li> |
| <li>SSSE3</li> |
| <li>SSE4.1, 4.2</li> |
| <li>POPCNT</li></td> |
| </tr> |
| |
| <tr> |
| <td><a href="#mips">{@code mips}</a></td> |
| <td><li>MIPS32r1 and later</li></td> |
| <td>Uses hard-float, and assumes a CPU:FPU clock ratio of 2:1 for maximum |
| compatibility. Provides neither micromips nor MIPS16.</td> |
| </tr> |
| |
| <tr> |
| <td><a href="#mips64">{@code mips64}</a></td> |
| <td><li>MIPS64r6</li></td><td> |
| </td> |
| </tr> |
| </table> |
| |
| <p>More detailed information about each ABI appears below.</p> |
| |
| <h3 id="armeabi">armeabi</h3> |
| <p>This ABI is for ARM-based CPUs that support at least |
| the ARMv5TE instruction set. Please refer to the following documentation for |
| more details:</p> |
| |
| <ul> |
| <li><a href="https://www.scss.tcd.ie/~waldroj/3d1/arm_arm.pdf">ARM Architecture |
| Reference Manual</a></li> |
| <li><a |
| href="http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042e/IHI0042E_aapcs.pdf"> |
| Procedure Call Standard for the ARM Architecture</a></li> |
| <li><a |
| href="http://infocenter.arm.com/help/topic/com.arm.doc.dui0101a/DUI0101A_Elf.pdf"> |
| ARM ELF File Format</a></li> |
| <li><a |
| href="http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.subset.swdev.abi/index.html">Application Binary Interface (ABI) for the ARM Architecture</a></li> |
| <li><a |
| href="http://infocenter.arm.com/help/topic/com.arm.doc.ihi0037c/IHI0037C_bpabi.pdf"> |
| Base Platform ABI for the ARM Architecture</a></li> |
| <li><a |
| href="http://infocenter.arm.com/help/topic/com.arm.doc.ihi0039c/IHI0039C_clibabi.pdf"> |
| C Library ABI for the ARM Architecture</a></li> |
| <li><a |
| href="http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ihi0041d/index.html"> |
| C++ ABI for the ARM Architecture</a></li> |
| <li><a |
| href="http://infocenter.arm.com/help/topic/com.arm.doc.ihi0043d/IHI0043D_rtabi.pdf"> |
| Run-time ABI for the ARM Architecture</a></li> |
| <li><a href="http://www.sco.com/developers/gabi/2001-04-24/contents.html">ELF |
| System V Application Binary Interface</a></li> |
| <li><a href="http://mentorembedded.github.com/cxx-abi/abi.html">Generic/Itanium C++ |
| ABI</a></li> |
| </ul> |
| |
| <p>The AAPCS standard defines EABI as a family of similar |
| but distinct ABIs. Also, Android follows the little-endian |
| <a href="http://sourcery.mentor.com/sgpp/lite/arm/portal/kbattach142/arm_gnu_linux_ abi.pdf"> |
| ARM GNU/Linux ABI</a>.</p> |
| |
| <p>This ABI does not support hardware-assisted floating point |
| computations. Instead, all floating-point operations use software helper |
| functions from the compiler's {@code libgcc.a} static library.</p> |
| |
| <p>The armeabi ABI supports ARM’s |
| <a href="http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0210c/CACBCAAE.html"> |
| Thumb (a.k.a. Thumb-1) instruction set</a>. The NDK generates Thumb |
| code by default unless you specify different behavior using the |
| <code>LOCAL_ARM_MODE</code> variable in your |
| <a href="{@docRoot}ndk/guides/android_mk.html">{@code Android.mk}</a> |
| file.</p> |
| |
| <h3 id="v7a">armeabi-v7a</h3> |
| <p>This ABI extends armeabi to include several |
| <a href="http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0406c/index.html"> |
| CPU instruction set extensions</a>. The instruction extensions that this Android-specific |
| ABI supports are:</p> |
| |
| <ul> |
| <li>The Thumb-2 instruction set extension, which provides performance comparable to 32-bit ARM |
| instructions with similar compactness to Thumb-1.</li> |
| <li>The VFP hardware-FPU instructions. More specifically, VFPv3-D16, which |
| includes 16 dedicated 64-bit floating point registers, in addition to another |
| 16 32-bit registers from the ARM core.</li> |
| </ul> |
| |
| <p>Other extensions that the v7-a ARM spec describes, including |
| <a href="http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0388f/Beijfcja.html"> |
| Advanced SIMD</a> (a.k.a. NEON), VFPv3-D32, and ThumbEE, are optional |
| to this ABI. Since their presence is not guaranteed, the system should check at runtime |
| whether the extensions are available. If they are not, you must use alternative code paths. This |
| check is similar to the one that the system typically performs to check or use |
| <a href="http://en.wikipedia.org/wiki/MMX_%28instruction_set%29">MMX</a>, |
| <a href="http://en.wikipedia.org/wiki/SSE2">SSE2</a>, and other specialized |
| instruction sets on x86 CPUs.</p> |
| |
| <p>For information about how to perform these runtime checks, refer to |
| <a href="{@docRoot}ndk/guides/cpu-features.html">The {@code cpufeatures} Library</a>. |
| Also, for information about the NDK's support for building |
| machine code for NEON, see |
| <a href="{@docRoot}ndk/guides/cpu-arm-neon.html">NEON Support</a>.</p> |
| |
| <p>The {@code armeabi-v7a} ABI uses the {@code -mfloat-abi=softfp} switch to |
| enforce the rule that the compiler must pass all double values in core register pairs during |
| function calls, instead of dedicated floating-point ones. The system can perform all internal |
| computations using the FP registers. Doing so speeds up the computations greatly.</p> |
| |
| <h3 id="arm64-v8a">arm64-v8a</h3> |
| <p>This ABI is for ARMv8-based CPUs that support AArch64. It also includes the NEON and |
| VFPv4 instruction sets.</p> |
| |
| <p>For more information, see the |
| <a href="http://www.arm.com/files/downloads/ARMv8_Architecture.pdf">ARMv8 |
| Technology Preview</a>, and contact ARM for further details.</p> |
| |
| <h3 id="x86">x86</h3> |
| <p>This ABI is for CPUs supporting the instruction set commonly |
| referred to as "x86" or "IA-32". Characteristics of this ABI include:</p> |
| |
| <ul> |
| <li>Instructions normally generated by GCC with compiler flags such as the following: |
| |
| <pre class="no-pretty-print"> |
| -march=i686 -mtune=intel -mssse3 -mfpmath=sse -m32 |
| </pre> |
| |
| <p>These flags target the the Pentium Pro instruction set, along with the |
| the <a href="http://en.wikipedia.org/wiki/MMX_%28instruction_set%29">MMX</a>, |
| <a href="http://en.wikipedia.org/wiki/Streaming_SIMD_Extensions">SSE</a>, |
| <a href="http://en.wikipedia.org/wiki/SSE2">SSE2</a>, |
| <a href="http://en.wikipedia.org/wiki/SSE3">SSE3</a>, and |
| <a href="http://en.wikipedia.org/wiki/SSSE3">SSSE3</a> instruction set extensions. |
| The generated code is an optimization balanced across the top Intel 32-bit |
| CPUs.</p> |
| <p> For more information on compiler flags, particularly related to performance optimization, |
| refer to <a href="http://software.intel.com/blogs/2012/09/26/gcc-x86-performance-hints">GCC |
| x86 performance hints</a>.</p> |
| </li> |
| <li>Use of the standard Linux x86 32-bit calling convention, as opposed to the one for SVR. For |
| more information, see section 6, "Register Usage", of |
| <a href="http://www.agner.org/optimize/calling_conventions.pdf">Calling conventions for different |
| C++ compilers and operating systems</a>.</li> |
| </ul> |
| |
| <p>The ABI does not include any other optional IA-32 instruction set |
| extensions, such as:</p> |
| <ul> |
| <li>MOVBE</li> |
| <li>Any variant of SSE4.</li> |
| </ul> |
| <p>You can still use these extensions, as long as you use runtime feature-probing to |
| enable them, and provide fallbacks for devices that do not support them.</p> |
| <p>The NDK toolchain assumes 16-byte stack alignment before a function call. The default tools and |
| options enforce this rule. If you are writing assembly code, you must make sure to maintain stack |
| alignment, and ensure that other compilers also obey this rule.</p> |
| |
| <p>Refer to the following documents for more details:</p> |
| <ul> |
| <li> |
| <a href="https://gcc.gnu.org/onlinedocs/gcc-4.9.2/gcc/i386-and-x86-64-Options.html"> |
| GCC online documentation: Intel 386 and AMD x86-64 Options</a></li> |
| <li><a href="http://www.agner.org/optimize/calling_conventions.pdf">Calling |
| conventions for different C++ compilers and operating systems</a></li> |
| <li><a |
| href="http://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf" |
| >Intel IA-32 Intel Architecture Software Developer's Manual, Volume 2: |
| Instruction Set Reference</a></li> |
| <li><a |
| href="http://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-system-programming-manual-325384.pdf">Intel |
| IA-32 Intel Architecture Software Developer's Manual, Volume 3: System |
| Programming Guide</a></li> |
| <li><a href="http://www.sco.com/developers/devspecs/abi386-4.pdf">System V Application Binary |
| Interface: Intel386 Processor Architecture Supplement</a></li> |
| </ul> |
| |
| <h3 id="86-64">x86_64</h3> |
| <p>This ABI is for CPUs supporting the instruction set commonly referred to as |
| "x86-64." It supports instructions that GCC typically generates with the following |
| compiler flags:</p> |
| <pre class="no-pretty-print"> |
| -march=x86-64 -msse4.2 -mpopcnt -m64 -mtune=intel |
| </pre> |
| |
| <p>These flags target the x86-64 instruction set, according to the GCC |
| documentation. along with the |
| <a href="http://en.wikipedia.org/wiki/MMX_%28instruction_set%29">MMX</a>, |
| <a href="http://en.wikipedia.org/wiki/Streaming_SIMD_Extensions">SSE</a>, |
| <a href="http://en.wikipedia.org/wiki/SSE2">SSE2</a>, |
| <a href="http://en.wikipedia.org/wiki/SSE3">SSE3</a>, |
| <a href="http://en.wikipedia.org/wiki/SSSE3">SSSE3</a>, |
| <a href="http://en.wikipedia.org/wiki/SSE4#SSE4.1">SSE4.1</a>, |
| <a href="http://en.wikipedia.org/wiki/SSE4#SSE4.2">SSE4.2</a>, and |
| <a href="https://software.intel.com/en-us/node/512035">POPCNT</a> |
| instruction-set extensions. The generated code is an optimization balanced |
| across the top Intel 64-bit CPUs.</p> |
| |
| <p> For more information on compiler flags, particularly related to performance optimization, |
| refer to <a href="http://software.intel.com/blogs/2012/09/26/gcc-x86-performance-hints">GCC |
| x86 Performance</a>.</p> |
| |
| <p>This ABI does not include any other optional x86-64 instruction set |
| extensions, such as:</p> |
| |
| <ul> |
| <li>MOVBE</li> |
| <li>SHA</li> |
| <li>AVX</li> |
| <li>AVX2</li> |
| </ul> |
| |
| <p>You can still use these extensions, as long as you use runtime feature probing to |
| enable them, and provide fallbacks for devices that do not support them.</p> |
| <p>Refer to the following documents for more details:</p> |
| |
| <ul> |
| <li><a href="http://www.agner.org/optimize/calling_conventions.pdf">Calling conventions for |
| different C++ compilers and operating systems</a></li> |
| <li> |
| <a href="http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html?iid=tech_vt_tech+64-32_manuals"> |
| Intel64 and IA-32 Architectures Software Developer's Manual, Volume 2: Instruction Set |
| Reference</a></li> |
| <li> |
| <a href="http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html?iid=tech_vt_tech+64-32_manuals"> |
| Intel64 and IA-32 Intel Architecture Software Developer's Manual Volume 3: System Programming</a> |
| </li> |
| </ul> |
| |
| <h3 id="mips">mips</h3> |
| <p>This ABI is for MIPS-based CPUs that support at least the MIPS32r1 instruction set. It includes |
| the following features:</p> |
| |
| <ul> |
| <li>MIPS32 revision 1 ISA</li> |
| <li>Little-endian</li> |
| <li>O32</li> |
| <li>Hard-float</li> |
| <li>No DSP application-specific extensions</li> |
| </ul> |
| |
| <p>For more information, please refer to the following documentation:</p> |
| |
| <ul> |
| <li>Architecture for Programmers ("MIPSARCH")</li> |
| <li><a href="https://refspecs.linuxbase.org/elf/gabi4+/contents.html">ELF |
| System V Application Binary Interface</a></li> |
| <li><a href="http://sourcery.mentor.com/public/cxx-abi/abi.html">Itanium/Generic C++ |
| ABI</a></li> |
| </ul> |
| |
| <p>For more specific details, see |
| <a href="http://www.imgtec.com/mips/architectures/mips32/">MIPS32 Architecture</a>. |
| Answers to common questions are in the |
| <a href="https://sourcery.mentor.com/sgpp/lite/mips/portal/target_arch?@action=faq&target_arch=MIPS">MIPS FAQ</a>. |
| </p> |
| </li> |
| </ul> |
| |
| <h3 id="mips64">mips64</h3> |
| <p>This ABI is for MIPS64 R6. For more information, see |
| <a href="http://www.imgtec.com/mips/architectures/mips64/">MIPS64 Architecture</a>.</p> |
| |
| <h2 id="gc">Generating Code for a Specific ABI</h2> |
| <p>By default, the NDK generates machine code for the armeabi ABI. You can |
| generate ARMv7-a-compatible machine code, instead, by adding the following line |
| to your <a href="{@docRoot}ndk/guides/application_mk.html">{@code Application.mk}</a> file.</p> |
| <pre class="no-pretty-print"> |
| APP_ABI := armeabi-v7a |
| </pre> |
| |
| <p>To build machine code for two or more distinct ABIs, using spaces as delimiters. For |
| example:</p> |
| |
| <pre class="no-pretty-print"> |
| APP_ABI := armeabi armeabi-v7a |
| </pre> |
| |
| <p>This setting tells the NDK to build two versions of your machine code: one |
| for each ABI listed on this line. For more information on the values you can specify for the |
| {@code APP_ABI} variable, see <a href="{@docRoot}ndk/guides/android_mk.html">Android.mk</a>. |
| </p> |
| |
| <p>When you build multiple machine-code versions, the build system copies the libraries to your |
| application project path, and ultimately packages them into your APK, so creating |
| a <a href="http://en.wikipedia.org/wiki/Fat_binary"><i>fat binary</i></a>. A fat binary |
| is larger than one containing only the machine code for a single system; the tradeoff is |
| gaining wider compatibility, but at the expense of a larger APK.</p> |
| |
| <p>At installation time, the package manager unpacks only the most appropriate |
| machine code for the target device. For details, see <a href="#aen">Automatic |
| extraction of native code at install time</a>.</p> |
| |
| |
| <h2 id="am">ABI Management on the Android Platform</h2> |
| <p>This section provides details about how the Android platform manages native |
| code in APKs.</p> |
| |
| <h3>Native code in app packages</h3> |
| <p>Both the Play Store and Package Manager expect to find NDK-generated |
| libraries on filepaths inside the APK matching the following pattern:</p> |
| |
| <pre class="no-pretty-print"> |
| /lib/<abi>/lib<name>.so |
| </pre> |
| |
| <p>Here, {@code <abi>} is one of the ABI names listed under <a href="#sa">Supported ABIs</a>, |
| and {@code <name>} is the name of the library as you defined it for the {@code LOCAL_MODULE} |
| variable in the <a href="{@docRoot}ndk/guides/android_mk.html">{@code Android.mk}</a> file. Since |
| APK files are just zip files, it is trivial to open them and confirm that the shared native |
| libraries are where they belong.</p> |
| |
| <p>If the system does not find the native shared libraries where it expects them, it cannot use |
| them. In such a case, the app itself has to copy the libraries over, and then |
| perform <code>dlopen()</code>.</p> |
| |
| <p>In a fat binary, each library resides under a directory whose name matches a corresponding ABI. |
| For example, a fat binary may contain:</p> |
| |
| <pre class="no-pretty-print"> |
| /lib/armeabi/libfoo.so |
| /lib/armeabi-v7a/libfoo.so |
| /lib/arm64-v8a/libfoo.so |
| /lib/x86/libfoo.so |
| /lib/x86_64/libfoo.so |
| /lib/mips/libfoo.so |
| /lib/mips64/libfoo.so |
| </pre> |
| |
| <p class="note"><strong>Note:</strong> ARMv7-based Android devices running 4.0.3 or earlier |
| install native libraries from the {@code armeabi} directory instead of the {@code armeabi-v7a} |
| directory if both directories exist. This is because {@code /lib/armeabi/} comes after |
| {@code /lib/armeabi-v7a/} in the APK. This issue is fixed from 4.0.4.</p> |
| |
| <h3>Android Platform ABI support</h3> |
| <p>The Android system knows at runtime which ABI(s) it supports, because build-specific system |
| properties indicate:</p> |
| |
| <ul> |
| <li>The primary ABI for the device, corresponding to the machine code used in |
| the system image itself.</li> |
| <li>An optional, secondary ABI, corresponding to another ABI that the system image also supports. |
| </li> |
| </ul> |
| |
| <p>This mechanism ensures that the system extracts the best machine code from |
| the package at installation time.</p> |
| |
| <p>For best performance, you should compile directly for the primary ABI. For example, a |
| typical ARMv5TE-based device would only define the primary ABI: {@code armeabi}. By contrast, a |
| typical, ARMv7-based device would define the primary ABI as {@code armeabi-v7a} and the secondary |
| one as {@code armeabi}, since it can run application native binaries generated for each of them.</p> |
| |
| <p>Many x86-based devices can also run {@code armeabi-v7a} and {@code armeabi} NDK binaries. For |
| such devices, the primary ABI would be {@code x86}, and the second one, {@code armeabi-v7a}.</p> |
| |
| <p>A typical MIPS-based device only defines a primary abi: {@code mips}.</p> |
| |
| <h3 id="aen">Automatic extraction of native code at install time</h3> |
| |
| <p>When installing an application, the package manager service scans the APK, and looks for any |
| shared libraries of the form:</p> |
| |
| <pre class="no-pretty-print"> |
| lib/<primary-abi>/lib<name>.so |
| </pre> |
| |
| <p>If none is found, and you have defined a secondary ABI, the service scans for shared libraries of |
| the form:</p> |
| |
| <pre class="no-pretty-print"> |
| lib/<secondary-abi>/lib<name>.so |
| </pre> |
| |
| <p>When it finds the libraries that it's looking for, the package manager |
| copies them to <code>/lib/lib<name>.so</code>, under the application's |
| {@code data} directory ({@code data/data/<package_name>/lib/}).</p> |
| |
| <p>If there is no shared-object file at all, the application builds and installs, but crashes at |
| runtime.</p> |