Cómo usar el NDK con otros sistemas de compilación

El NDK es oficialmente compatible con ndk-build y CMake. La mayoría de los usuarios deben consultar una de esas guías para compilar el código de la aplicación. El propósito de este documento es describir cómo se compila código existente que usa otros sistemas de compilación. Este suele ser el caso de las dependencias de terceros que no son específicas de Android, como OpenSSL y libbzip2.

En cambio, los encargados de mantener sistemas de compilación que buscan agregar compatibilidad nativa con el NDK a sus sistemas de compilación deberían leer la Guía para encargados de mantener sistemas de compilación.

Descripción general

El compilador Clang del NDK se puede usar con solo una configuración mínima necesaria para definir tu entorno de destino.

Para asegurarte de compilar la arquitectura correcta, pasa el destino adecuado con -target al invocar a Clang, o invoca a Clang con destino fijado previamente. Por ejemplo, si realizas una compilación para ARM de 64 bits de Android con un minSdkVersion de 21, funcionará cualquiera de las siguientes opciones (y podrás usar la que consideres más 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

En ambos casos, reemplaza $NDK con la ruta de acceso al NDK y $HOST_TAG para que coincida con el NDK que descargaste según la tabla que se incluye a continuación:

Variante del SO del NDK Etiqueta de host
macOS darwin-x86_64
Linux linux-x86_64
Windows de 64 bits windows-x86_64

En este caso, el formato del prefijo o argumento de destino es triple, con un sufijo que indica minSdkVersion. Este sufijo solo se usa con Clang o Clang++; las herramientas binutils (como ar y strip) no requieren sufijo porque minSdkVersion no las afecta. Los argumentos de destino triples de Android son los siguientes:

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

Las secuencias de comandos de compilación de muchos proyectos esperan compiladores cruzados del estilo GCC, en los que cada compilador se orienta solo a una combinación de SO y arquitectura, por lo que es posible que no controlen -target de manera correcta. En estos casos, por lo general, puedes incluir el argumento -target como parte de la definición del compilador (p. ej., CC="clang -target aarch64-linux-android21) o usar los objetos binarios de Clang con prefijo triple.

Autoconf

Los proyectos de Autoconf te permiten especificar la cadena de herramientas para usar con las variables de entorno. Por ejemplo, a continuación, se muestra cómo compilar libpng para Android x86-64 con una minSdkVersion de nivel de API 21 en Linux.

# 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

Las herramientas seleccionadas en este ejemplo son correctas para NDK r22 y versiones posteriores. Es posible que los NDK más antiguos necesiten herramientas diferentes.

Proyectos Make que no son de Autoconf

Algunos proyectos con archivos Make permiten compilación cruzada, ya que anulan las mismas variables que anularías en un proyecto de Autoconf. A continuación, se muestra cómo compilar libbzip2 para Android x86-64 con una 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/llvm-ar \
    RANLIB=$TOOLCHAIN/bin/llvm-ranlib \
    bzip2

Las herramientas seleccionadas en este ejemplo son correctas para NDK r22 y versiones posteriores. Es posible que los NDK más antiguos necesiten herramientas diferentes.