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 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/bin/clang++ \
    -target aarch64-linux-android21 foo.cpp
$ $NDK/toolchains/llvm/prebuilt/$HOST_TAG/bin/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, no Linux, para Android x86-64 com minSdkVersion da API de nível 21.

# Check out the source.
git clone https://github.com/glennrp/libpng -b v1.6.37
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/llvm-ar
export CC=$TOOLCHAIN/bin/$TARGET$API-clang
export AS=$CC
export CXX=$TOOLCHAIN/bin/$TARGET$API-clang++
export LD=$TOOLCHAIN/bin/ld
export RANLIB=$TOOLCHAIN/bin/llvm-ranlib
export STRIP=$TOOLCHAIN/bin/llvm-strip
./configure --host $TARGET
make

As ferramentas selecionadas nesse exemplo estão corretas para o NDK r22 e versões mais recentes. NDKs mais antigos podem exigir ferramentas diferentes.

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 uma minSdkVersion 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/llvm-ar \
    RANLIB=$TOOLCHAIN/bin/llvm-ranlib \
    bzip2

As ferramentas selecionadas nesse exemplo estão corretas para o NDK r22 e versões mais recentes. NDKs mais antigos podem exigir ferramentas diferentes.