Como usar o NDK com outros sistemas de compilação

O NDK tem compatibilidade oficial para ndk-build e CMake. A maioria dos usuários precisa consultar um desses guias para criar o código do aplicativo. O objetivo deste documento é descrever como criar um código existente que usa outros sistemas de compilação. Isso geralmente ocorre com dependências de terceiros que não são específicas do Android, como OpenSSL e libbzip2.

Os administradores de sistema de compilação que queiram adicionar compatibilidade do NDK nativo com seus sistemas precisam ler o Build System Maintainers Guide (Guia de administradores de sistema de compilação).

Visão geral

A partir do NDK r19, os conjuntos de ferramentas instalados por padrão com o NDK podem ser usados no local. O script make_standalone_toolchain.py não é mais necessário para fazer a interface com sistemas de compilação arbitrários.

Para garantir que você crie a arquitetura correta, passe o destino apropriado com -target quando invocar o Clang ou invoque o Clang prefixado pelo destino. Por exemplo, para compilar para ARM Android de 64 bits com minSdkVersion de 21, qualquer um dos itens a seguir funcionará, e você poderá usar o que achar mais conveniente:

$ $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

Em ambos os casos, substitua $NDK pelo caminho do NDK e $HOST_TAG para corresponder ao NDK salvo, de acordo com a seguinte tabela:

Variante do SO do NDK Tag de host
macOS darwin-x86_64
Linux linux-x86_64
Windows de 32 bits windows
Windows de 64 bits windows-x86_64

O formato do prefixo ou do argumento de destino é o triplo do destino com um sufixo que indica o minSdkVersion. Esse sufixo é usado apenas com clang/clang++; as ferramentas binutils (como ar e strip) não exigem um sufixo porque elas não são afetadas por minSdkVersion. Os triplos do destino compatíveis com o Android são estes:

ABI Triplo
armeabi-v7a armv7a-linux-androideabi
arm64-v8a aarch64-linux-android
x86 i686-linux-android
x86-64 x86_64-linux-android

Os scripts de compilação de muitos projetos esperarão compiladores cruzados no estilo GCC, em que cada compilador é destinado apenas a uma combinação SO/arquitetura e, portanto, pode não manipular -target de maneira clara. Nesses casos, é melhor usar os binários Clang de triplo prefixo.

Autoconf

Os projetos do Autoconf permitem que você especifique o conjunto de ferramentas a ser usado com variáveis de ambiente. O exemplo a seguir mostra como criar libpng para Android x86-64 com minSdkVersion da API de nível 21, no Linux.

# Check out the source.
git clone https://github.com/glennrp/libpng
cd libpng
# Only choose one of these, depending on your build machine...
export TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/darwin-x86_64
export TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64
# Only choose one of these, depending on your device...
export TARGET=aarch64-linux-android
export TARGET=armv7a-linux-androideabi
export TARGET=i686-linux-android
export TARGET=x86_64-linux-android
# Set this to your minSdkVersion.
export API=21
# Configure and build.
export AR=$TOOLCHAIN/bin/$TARGET-ar
export AS=$TOOLCHAIN/bin/$TARGET-as
export CC=$TOOLCHAIN/bin/$TARGET$API-clang
export CXX=$TOOLCHAIN/bin/$TARGET$API-clang++
export LD=$TOOLCHAIN/bin/$TARGET-ld
export RANLIB=$TOOLCHAIN/bin/$TARGET-ranlib
export STRIP=$TOOLCHAIN/bin/$TARGET-strip
./configure --host $TARGET
make

Projetos que não são do Autoconf

Alguns projetos do makefile permitem compilação cruzada substituindo as mesmas variáveis que você faria com um projeto autoconf. Como exemplo, veja a seguir como criar libbzip2 para Android x86-64 com um minSdkVersion de 21.

# Check out the source.
git clone https://gitlab.com/bzip/bzip2.git
cd bzip2

# Only choose one of these, depending on your build machine...
export TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/darwin-x86_64
export TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64

# Only choose one of these, depending on your device...
export TARGET=aarch64-linux-android
export TARGET=armv7a-linux-androideabi
export TARGET=i686-linux-android
export TARGET=x86_64-linux-android

# Set this to your minSdkVersion.
export API=21

# Build.
make \
    CC=$TOOLCHAIN/bin/$TARGET$API-clang \
    AR=$TOOLCHAIN/bin/$TARGET-ar \
    RANLIB=$TOOLCHAIN/bin/$TARGET-ranlib \
    bzip2