Usar o NDK com outros sistemas de build

O NDK tem suporte oficial ao 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 compilar um código 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 build que queiram adicionar suporte para NDK nativo nos próprios sistemas precisam ler o Guia de administradores de sistema de build.

Visão geral

O compilador Clang no NDK pode ser usado com apenas a configuração mínima necessária para definir seu ambiente de destino.

Para garantir que você crie para a arquitetura correta, transmita o destino com -target ao invocar o Clang. Por exemplo, para compilar para 64 bits, ARM Android com uma minSdkVersion de 21, faça o seguinte:

$ $NDK/toolchains/llvm/prebuilt/$HOST_TAG/bin/clang++ \
    --target aarch64-linux-android21 foo.cpp

Como alternativa, há pontos de entrada com prefixo no alvo para o Clang. Eles podem ser links simbólicos ou scripts que encaminham para o Clang, dependendo da versão do NDK e o SO do host. Invocar o Clang diretamente com --target é mais confiável. Esse é o fluxo de trabalho mais testado. Às vezes, há encaminhamento de argumentos bugs nos scripts. No Windows, os CreateProcess extras necessários para encaminhar do script para o compilador real podem ter um impacto um impacto negativo na velocidade de build.

$ $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 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, normalmente é possível incluir o -target. como parte da definição do compilador (por exemplo, CC="clang -target aarch64-linux-android21). Nos casos raros em que o sistema de build que você usa é não conseguir usar esse formulário, use os binários Clang de triplo prefixo.

Autoconf

Os projetos 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/clang --target=$TARGET$API"
export AS=$CC
export CXX="$TOOLCHAIN/bin/clang++ --target=$TARGET$API"
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/clang --target=$TARGET$API" \
    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.