Utiliser le NDK avec d'autres systèmes de compilation

Le NDK est officiellement compatible avec ndk-build et CMake. La plupart des utilisateurs doivent se référer à l'un de ces guides pour créer le code d'application. L'objectif de ce document est de décrire comment compiler du code existant qui utilise d'autres systèmes de compilation. C'est souvent le cas des dépendances tierces qui ne sont pas spécifiques d'Android, comme OpenSSL et libbzip2.

Les personnes qui gèrent un système de compilation et souhaitent lui intégrer la compatibilité NDK native doivent plutôt consulter la page Build System Maintainers Guide.

Aperçu

Le compilateur Clang du NDK est utilisable avec la configuration minimale requise pour définir votre environnement cible.

Pour vous assurer que votre build repose sur la bonne architecture, transmettez les target avec -target lors de l'appel de Clang. Par exemple, pour compiler pour des charges de travail 64 bits, ARM sur Android avec un minSdkVersion de 21:

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

Il existe également des points d'entrée avec préfixe cible pour Clang. Il peut s'agir de Liens symboliques ou scripts redirigeant vers clang, en fonction de la version du NDK et l'OS hôte. Appeler Clang directement avec --target sera plus fiable, car qui est le workflow le plus testé, et il arrive que le transfert d'arguments les bugs dans les scripts. Sous Windows, le CreateProcess supplémentaire nécessaire pour transférer du script au véritable compilateur peut potentiellement avoir un problème peut avoir un impact négatif sur la vitesse de compilation.

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

Dans les deux cas, remplacez $NDK par le chemin d'accès au NDK et définissez $HOST_TAG pour qu'il corresponde au NDK que vous avez téléchargé, conformément au tableau suivant :

Variante d'OS du NDK Balise d'hôte
macOS darwin-x86_64
Linux linux-x86_64
Windows 64 bits windows-x86_64

Le format du préfixe ou de l'argument cible correspond ici au triplet cible avec un suffixe indiquant la minSdkVersion. Ce suffixe n'est utilisé qu'avec clang/clang++. Les outils binutils (tels que ar et strip) ne nécessitent pas de suffixe, car ils ne sont pas affectés par la minSdkVersion. Les triplets cibles compatibles avec Android sont les suivants :

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

Les scripts de compilation d'un grand nombre de projets prévoient des compilateurs croisés de type GCC, où chaque compilateur ne cible qu'une seule combinaison OS/architecture. Il est donc possible qu'ils ne gèrent pas correctement -target. Dans ce cas, vous pouvez généralement inclure le -target argument dans la définition du compilateur (par exemple, CC="clang -target aarch64-linux-android21). Dans les rares cas où le système de compilation que vous utilisez est ne pouvez pas utiliser ce formulaire, utilisez les binaires Clang avec le triplet en préfixe.

Autoconf

Les projets autoconf vous permettent de spécifier la chaîne d'outils à utiliser avec des variables d'environnement. L'exemple suivant montre comment compiler libpng pour Android x86-64 avec une minSdkVersion de niveau d'API 21, sous 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

Les outils sélectionnés dans cet exemple conviennent à NDK r22 ou version ultérieure. Les NDK plus anciens peuvent nécessiter des outils différents.

Projets make sans autoconf

Certains projets makefile autorisent la compilation croisée via le remplacement des mêmes variables que dans un projet autoconf. L'exemple suivant montre comment compiler libbzip2 pour Android x86-64 avec une 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

Les outils sélectionnés dans cet exemple conviennent à NDK r22 ou version ultérieure. Les NDK plus anciens peuvent nécessiter des outils différents.