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 compilar 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 mantenedores do sistema que queiram adicionar compatibilidade do NDK nativo com seus sistemas de compilação precisam ler o Build System Maintainers Guide (link em inglês).

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ê compile 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. Este 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 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