Posted on

Cross compiling C/C++ libraries for Android (updated)

There are a few forms a C/C++ library that you want to cross compile to Android might come in.

For instance:

  • An Autotools project
  • A CMake project

To get started let’s make a standalone Android toolchain (a toolchain being compilers, libraries and headers for cross compiling our source code to a specific target architecture and platform ABI) .

Making a standalone toolchain

Firstly you’ll need to download and install the Android NDK. The Android NDK comes bundled with a script that will generate a standalone toolchain for cross compilation (see here). By default, specifying –arch=arm will default clang to target the armeabi-v7a ABI.

NB. This recipe was tested against Android NDK r18, r19 has broken CMake’s Android support at the time of writing.

export ANDROID_NDK_HOME="/Users/benmorris/Downloads/android-ndk-r18b"

# make the toolchain
${ANDROID_NDK_HOME}/build/tools/ --arch=arm --platform=android-21 --install-dir=android-toolchain --stl=libc++

# add the toolchain to our path
export PATH="`pwd -P`/android-toolchain/bin:$PATH"

# set target architecture (used by ./configure)
export CHOST="arm-linux-androideabi"

Cross compiling an autotools based project to Android

Having made our standalone toolchain above, let’s compile zlib for Android using the toolchain (Zlib is precompiled and available in the standalone toolchain’s sysroot but lets recompile it here for demonstration purposes). In the same shell session that we used to create our toolchain we first need to set some variables (used by configure) to ensure our toolchain’s compiler (and supporting utilities) are detected:

export CC="arm-linux-androideabi-clang"
export CXX="arm-linux-androideabi-clang++"
export RANLIB="arm-linux-androideabi-ranlib"
export LD="arm-linux-androideabi-ld"
export AR="arm-linux-androideabi-ar"
export ARFLAGS="cr"
export CHOST="arm-linux-androideabi"

Now we are ready to go ahead and build the library.

# download and extract zlib
tar zxf zlib-1.2.11.tar.gz

# configure and make it
cd zlib-1.2.11

We can confirm that the generated library’s ELF file format is as expected by inspecting it using the toolchain supplied nm tool:

../android-toolchain/bin/arm-linux-androideabi-nm libz.a

You should be able to see the library’s data, symbols, exported and imported function names.



You should see mention of the ARM abi you compiled against: ELF 32-bit LSB pie executable ARM, EABI5 version 1 (SYSV), dynamically linked, BuildID[sha1]=ce2abedd344601985bf13860bcb2fbd86c1b8b23, with debug_info, not stripped

Cross compiling a CMake based project to Android

For a CMake based project we’ll need to tell CMake how to find the standalone toolchain we created above. We do this by providing cmake with the path to the toolchain we want to use through the variables CMAKE_SYSTEM_NAME, CMAKE_SYSTEM_VERSION and CMAKE_ANDROID_STANDALONE_TOOLCHAIN. For demonstration purposes let’s compile a CMake based project for Android using the toolchain we created above:

cd assimp-3.1.1

cmake ./ \
  -DCMAKE_ANDROID_STANDALONE_TOOLCHAIN=`pwd -P`/../android-toolchain \
  -DCMAKE_INSTALL_PREFIX=`pwd -P`/build \

cmake --build . --config Release