Use the NDK with other build systems
Stay organized with collections
Save and categorize content based on your preferences.
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.
Overview
The Clang compiler in the NDK is useable with only minimal configuration required to define your target environment.
To ensure that you build for the correct architecture, pass the appropriate
target with -target when invoking Clang. For example, to compile for 64-bit
ARM Android with a minSdkVersion of 21, do the following:
$$NDK/toolchains/llvm/prebuilt/$HOST_TAG/bin/clang++\
--target=aarch64-linux-android21foo.cpp
Alternatively, there are target-prefixed entry-points for Clang. These may be
either symlinks or scripts that forward to clang, depending on the NDK release
and host OS. Invoking Clang directly with --target will be more reliable, as
that is the most tested workflow, and there are occasionally argument forwarding
bugs in the scripts. On Windows, the extra CreateProcess needed to forward
from the script to the real compiler could potentially have a noticeable
negative impact on build speed.
$$NDK/toolchains/llvm/prebuilt/$HOST_TAG/bin/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 |
|---|---|
| macOS | darwin-x86_64 |
| Linux | linux-x86_64 |
| 64-bit Windows | windows-x86_64 |
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 ar and strip) do not require a
suffix because they are unaffected by minSdkVersion. Android's supported
target triples are as follows:
| ABI | Triple |
|---|---|
| armeabi-v7a | armv7a-linux-androideabi |
| arm64-v8a | aarch64-linux-android |
| x86 | i686-linux-android |
| x86-64 | x86_64-linux-android |
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, you can typically include the -target
argument as part of the compiler definition (e.g. CC="clang -target
aarch64-linux-android21). In rare cases where the build system you're using is
not able to use that form, use the triple-prefixed Clang binaries.
Autoconf
Autoconf projects allow you to specify the toolchain to use with environment
variables. For example, the following shows how to build libpng for Android
x86-64 with a minSdkVersion of API level 21, on Linux.
# Check out the source. gitclonehttps://github.com/glennrp/libpng-bv1.6.37 cdlibpng# Only choose one of these, depending on your build machine... exportTOOLCHAIN=$NDK/toolchains/llvm/prebuilt/darwin-x86_64 exportTOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64# Only choose one of these, depending on your device... exportTARGET=aarch64-linux-android exportTARGET=armv7a-linux-androideabi exportTARGET=i686-linux-android exportTARGET=x86_64-linux-android# Set this to your minSdkVersion. exportAPI=21# Configure and build. exportAR=$TOOLCHAIN/bin/llvm-ar exportCC="$TOOLCHAIN/bin/clang --target=$TARGET$API" exportAS=$CC exportCXX="$TOOLCHAIN/bin/clang++ --target=$TARGET$API" exportLD=$TOOLCHAIN/bin/ld exportRANLIB=$TOOLCHAIN/bin/llvm-ranlib exportSTRIP=$TOOLCHAIN/bin/llvm-strip ./configure--host$TARGET make
The tools selected in this sample are correct for NDK r22 and newer. Older NDKs may require different 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
to build libbzip2 for Android x86-64 with a minSdkVersion of 21.
# Check out the source.
gitclonehttps://gitlab.com/bzip/bzip2.git
cdbzip2
# Only choose one of these, depending on your build machine...
exportTOOLCHAIN=$NDK/toolchains/llvm/prebuilt/darwin-x86_64
exportTOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64
# Only choose one of these, depending on your device...
exportTARGET=aarch64-linux-android
exportTARGET=armv7a-linux-androideabi
exportTARGET=i686-linux-android
exportTARGET=x86_64-linux-android
# Set this to your minSdkVersion.
exportAPI=21
# Build.
make\
CC="$TOOLCHAIN/bin/clang --target=$TARGET$API"\
AR=$TOOLCHAIN/bin/llvm-ar\
RANLIB=$TOOLCHAIN/bin/llvm-ranlib\
bzip2
The tools selected in this sample are correct for NDK r22 and newer. Older NDKs may require different tools.