The NDK contains official support for ndk-build and CMake. Most users should refer to one of those guides for building application code. The purpose of this document is to describe how to build existing code that uses other build systems. This is often the case with third-party dependencies that are not Android-specific, such as OpenSSL and libbzip2.
Build system maintainers looking to add native NDK support to their build systems should instead read the Build System Maintainers Guide.
As of NDK r19, the toolchains installed by default with the NDK may be used
make_standalone_toolchain.py script is no longer needed for
interfacing with arbitrary build systems.
To ensure that you build for the correct architecture, either pass the
appropriate target with
-target when invoking Clang, or invoke the
target-prefixed Clang. For example, to compile for 64-bit ARM Android with a
minSdkVersion of 21, either of the following will work and you may use
whichever you find most convenient:
$ $NDK/toolchains/llvm/prebuilt/$HOST_TAG/clang++ \ -target aarch64-linux-android21 foo.cpp
$ $NDK/toolchains/llvm/prebuilt/$HOST_TAG/aarch64-linux-android21-clang++ \ foo.cpp
In both cases, replace
$NDK with the path to the NDK and
$HOST_TAG to match
the NDK you downloaded according to the following table:
|NDK OS Variant||Host Tag|
The format of the prefix or target argument here is the target triple with a
suffix denoting the
minSdkVersion. This suffix is only used with
clang/clang++; the binutils tools (such as
strip) do not require a
suffix because they are unaffected by
minSdkVersion. Android's supported
target triples are as follows:
Many projects' build scripts will expect GCC-style cross compilers where each
compiler targets only one OS/architecture combination and so may not handle
-target cleanly. In these cases, it is better to use the triple-prefixed Clang
Autoconf projects allow you to specify the toolchain to use with environment
variables. For example, the following shows how to build
libpng for 64-bit
Android ARM with a
minSdkVersion of API level 21.
$ git clone https://github.com/glennrp/libpng $ cd libpng $ export TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/$HOST_TAG $ export AR=$TOOLCHAIN/bin/aarch64-linux-android-ar $ export AS=$TOOLCHAIN/bin/aarch64-linux-android-as $ export CC=$TOOLCHAIN/bin/aarch64-linux-android21-clang $ export CXX=$TOOLCHAIN/bin/aarch64-linux-android21-clang++ $ export LD=$TOOLCHAIN/bin/aarch64-linux-android-ld $ export RANLIB=$TOOLCHAIN/bin/aarch64-linux-android-ranlib $ export STRIP=$TOOLCHAIN/bin/aarch64-linux-android-strip $ ./configure --host aarch64-linux-android $ make
To target a different architecture or API level, use the appropriately prefixed tools.
Non-Autoconf make projects
Some makefile projects allow cross compilation by overriding the same variables
that you would with an autoconf project. As an example, the following shows how
libbzip2 for 32-bit Android ARM with a
minSdkVersion of 16.
$ git clone https://gitlab.com/bzip/bzip2.git $ cd bzip2 $ export TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/$HOST_TAG $ make \ CC=$TOOLCHAIN/bin/armv7a-linux-androideabi16-clang \ AR=$TOOLCHAIN/bin/arm-linux-androideabi-ar \ RANLIB=$TOOLCHAIN/bin/arm-linux-androideabi-ranlib \ bzip2
As with autoconf, to target a different architecture or API level, use the appropriately prefixed tools.