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 que compiles para la arquitectura correcta, pasa las destino con -target cuando se invoca a Clang. Por ejemplo, para compilar para 64 bits ARM Android con un minSdkVersion de 21, haz lo siguiente:

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

Como alternativa, existen puntos de entrada con prefijo de destino para Clang. Pueden ser enlaces simbólicos o secuencias de comandos que reenvían a Clang, según la versión del NDK y el SO host. Invocar Clang directamente con --target será más confiable, ya que que es el flujo de trabajo más probado y, a veces, se reenvían argumentos errores en las secuencias de comandos. En Windows, el CreateProcess adicional necesitaba reenviar de la secuencia de comandos al compilador real podrían tener un impacto tiene un impacto negativo en la velocidad de compilación.

$ $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 -target como parte de la definición del compilador (p.ej., CC="clang -target aarch64-linux-android21). En casos excepcionales en los que el sistema de compilación que utilizas sea que no puedas usar ese formulario, debes usar los 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/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

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/clang --target=$TARGET$API" \
    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.