L'NDK di Android supporta l'uso di CMake per compilare il codice C e C++ per l'applicazione. In questa pagina viene spiegato come utilizzare CMake con l'NDK tramite ExternalNativeBuild
del plug-in Android per Gradle o quando si richiama direttamente CMake.
Il file toolchain CMake
L'NDK supporta CMake tramite un file Toolchain. I file Toolchain sono file CMake
che personalizzano il comportamento della toolchain per il cross-compiling. Il file della toolchain utilizzato per l'NDK si trova nell'NDK all'indirizzo <NDK>/build/cmake/android.toolchain.cmake
.
I parametri di build come ABI, minSdkVersion
e così via vengono forniti nella riga di comando quando chiami cmake
. Per un elenco degli argomenti supportati, consulta la sezione Argomenti della Toolbar.
Utilizzo
Gradle
L'utilizzo del file toolchain CMake è automatico quando utilizzi
externalNativeBuild
. Per ulteriori informazioni, consulta la guida di Android Studio Aggiungere codice C e C++ al progetto.
Riga di comando
Quando crei con CMake al di fuori di Gradle, il file della toolchain stesso e i relativi argomenti devono essere passati a CMake. Ecco alcuni esempi:
$ cmake \
-DCMAKE_TOOLCHAIN_FILE=$NDK/build/cmake/android.toolchain.cmake \
-DANDROID_ABI=$ABI \
-DANDROID_PLATFORM=android-$MINSDKVERSION \
$OTHER_ARGS
Argomenti Toolchain
I seguenti argomenti possono essere passati al file toolchain CMake. Se crei
con Gradle, aggiungi argomenti a
android.defaultConfig.externalNativeBuild.cmake.arguments
come descritto nella
documentazione di External NativeBuild. Se crei dalla riga di comando, passa gli argomenti a
CMake con -D
. Ad esempio, per costringere armeabi-v7a a non creare con il supporto Neon, passa -DANDROID_ARM_NEON=FALSE
.
ANDROID_ABI
L'ABI target. Per informazioni sulle ABI supportate, consulta la pagina relativa alle ABI Android.
Gradle
Gradle fornisce questo argomento automaticamente. Non impostare esplicitamente questo argomento nel file build.gradle
. Per controllare quali ABI vengono scelte come target da Gradle,
utilizza abiFilters
come descritto in ABI Android.
Riga di comando
Crea build per un singolo target per build. Per scegliere come target più di un'ABI Android, devi creare una volta per ABI. È consigliabile utilizzare directory di build diverse per ogni ABI in modo da evitare conflitti tra le build.
Valore | Notes |
---|---|
armeabi-v7a |
|
armeabi-v7a with NEON |
Uguale a armeabi-v7a . |
arm64-v8a |
|
x86 |
|
x86_64 |
ANDROID_ARM_MODE
Specifica se generare istruzioni per le braccia o per il pollice per armeabi-v7a. Non ha alcun effetto per altre ABI. Per ulteriori informazioni, consulta la documentazione sulle ABI Android.
Valore | Notes |
---|---|
un braccio | |
pollice | Comportamento predefinito. |
ANDROID_ARM_NEON
Abilita o disabilita NEON per armeabi-v7a. Non ha effetto per altre ABI. Il valore predefinito è true per il livello API (minSdkVersion
o ANDROID_PLATFORM
) 23 o successivo, false in caso contrario. Per ulteriori informazioni, consulta la documentazione relativa all'assistenza Neon.
Valore | Notes |
---|---|
VERO | Valore predefinito per il livello API 23 o versioni successive. |
FALSO | Valore predefinito per il livello API 22 o versioni precedenti. |
ANDROID_LD
Consente di selezionare il linker da utilizzare. lld è attualmente sperimentale per l'NDK e può essere abilitato con questo argomento.
Valore | Notes |
---|---|
lld | Attiva lld. |
predefinita | Utilizza il linker predefinito per l'ABI specificata. |
ANDROID_NATIVE_API_LEVEL
Alias per ANDROID_PLATFORM.
ANDROID_PLATFORM
Specifica il livello API minimo supportato dall'applicazione o dalla libreria. Questo
valore corrisponde al valore minSdkVersion
dell'applicazione.
Gradle
Quando utilizzi il plug-in Android per Gradle, questo valore viene impostato automaticamente per
corrispondere al valore minSdkVersion
dell'applicazione e non deve essere impostato manualmente.
Riga di comando
Quando si richiama direttamente CMake, questo valore viene impostato in modo predefinito sul livello API più basso supportato dall'NDK in uso. Ad esempio, con NDK r20 questo valore viene impostato al livello API 16 per impostazione predefinita.
Per questo parametro sono accettati più formati:
android-$API_LEVEL
$API_LEVEL
android-$API_LETTER
Il formato $API_LETTER
consente di specificare android-N
senza dover determinare il numero associato a quella release. Tieni presente che alcune release hanno ricevuto un aumento dell'API senza un aumento delle lettere. Queste API possono essere specificate
aggiungendo il suffisso -MR1
. Ad esempio, il livello API 25 è android-N-MR1
.
ANDROID_STL
Specifica il codice STL da utilizzare per questa applicazione. Per maggiori informazioni, consulta l'assistenza per la libreria C++. Per impostazione predefinita, viene utilizzato il criterio c++_static
.
Valore | Notes |
---|---|
c++_condiviso | La variante della libreria condivisa di libc++. |
c++_statica | La variante della libreria statica di libc++. |
Nessuna selezione | Nessuna libreria standard C++ supportata. |
di infotainment | Il sistema STL |
Informazioni sul comando di build CMake
Durante il debug dei problemi di build di CMake, è utile conoscere gli argomenti specifici di build che Gradle utilizza per la creazione di cross-compilazione per Android.
Il plug-in Android per Gradle salva gli argomenti della build utilizzati per l'esecuzione di una build
CMake per ogni coppia ABI e tipo di build
nell'build_command.txt
. Questi file si trovano nella seguente directory:
<project-root>/<module-root>/.cxx/cmake/<build-type>/<ABI>/
Lo snippet seguente mostra un esempio di argomenti CMake per creare una release di cui è possibile eseguire il debug dell'esempio hello-jni
che ha come target l'architettura armeabi-v7a
.
Executable : ${HOME}/Android/Sdk/cmake/3.10.2.4988404/bin/cmake
arguments :
-H${HOME}/Dev/github-projects/googlesamples/ndk-samples/hello-jni/app/src/main/cpp
-DCMAKE_FIND_ROOT_PATH=${HOME}/Dev/github-projects/googlesamples/ndk-samples/hello-jni/app/.cxx/cmake/universalDebug/prefab/armeabi-v7a/prefab
-DCMAKE_BUILD_TYPE=Debug
-DCMAKE_TOOLCHAIN_FILE=${HOME}/Android/Sdk/ndk/22.1.7171670/build/cmake/android.toolchain.cmake
-DANDROID_ABI=armeabi-v7a
-DANDROID_NDK=${HOME}/Android/Sdk/ndk/22.1.7171670
-DANDROID_PLATFORM=android-23
-DCMAKE_ANDROID_ARCH_ABI=armeabi-v7a
-DCMAKE_ANDROID_NDK=${HOME}/Android/Sdk/ndk/22.1.7171670
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON
-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=${HOME}/Dev/github-projects/googlesamples/ndk-samples/hello-jni/app/build/intermediates/cmake/universalDebug/obj/armeabi-v7a
-DCMAKE_RUNTIME_OUTPUT_DIRECTORY=${HOME}/Dev/github-projects/googlesamples/ndk-samples/hello-jni/app/build/intermediates/cmake/universalDebug/obj/armeabi-v7a
-DCMAKE_MAKE_PROGRAM=${HOME}/Android/Sdk/cmake/3.10.2.4988404/bin/ninja
-DCMAKE_SYSTEM_NAME=Android
-DCMAKE_SYSTEM_VERSION=23
-B${HOME}/Dev/github-projects/googlesamples/ndk-samples/hello-jni/app/.cxx/cmake/universalDebug/armeabi-v7a
-GNinja
jvmArgs :
Build command args: []
Version: 1
Utilizzare le librerie predefinite
Se la libreria predefinita che devi importare è distribuita come AAR, segui i documenti sulle dipendenze di Studio per importarli e utilizzarli. Se non utilizzi AGP, puoi seguire https://google.github.io/prefab/example-workflow.html, ma probabilmente sarà molto più facile eseguire la migrazione ad AGP.
Per le librerie che non sono distribuite come AAR, le istruzioni sull'utilizzo di librerie
predefinite con CMake, consulta la documentazione add_library
relativa ai target IMPORTED
nel manuale di CMake.
Creazione di codice di terze parti
Esistono diversi modi per creare codice di terze parti nell'ambito del progetto CMake e qual è l'opzione più adatta a seconda della situazione. Spesso la soluzione migliore è non farlo affatto. Puoi invece creare un AAR per la libreria e utilizzarlo nella tua applicazione. Non è necessario pubblicare questo AAR. Può essere interno al tuo progetto Gradle.
Se non è possibile:
- Fornitore (ovvero copia) il codice sorgente di terze parti nel tuo repository e utilizza add_subdirectory per crearlo. Funziona solo se anche l'altra libreria è stata creata con CMake.
- Definisci un ExternalProject.
- Crea la libreria separatamente dal tuo progetto e segui la procedura descritta in Usa librerie predefinite per importarla come predefinita.
Supporto di YASM in CMake
NDK fornisce il supporto CMake per la creazione di codice di assemblaggio scritto in YASM per l'esecuzione su architetture x86 e x86-64. YASM è un assemblatore open source per architetture x86 e x86-64, basato sull'assemblatore NASM.
Per creare il codice dell'assemblaggio con CMake, apporta le seguenti modifiche nel
CMakeLists.txt
del progetto:
- Chiama
enable_language
con il valore impostato suASM_NASM
. - A seconda che tu stia creando una libreria condivisa o un file binario eseguibile, chiama
add_library
oadd_executable
. Negli argomenti, passa un elenco di file di origine costituiti dai file.asm
per il programma di assemblaggio in YASM e dai file.c
per le librerie C o le funzioni associate.
Lo snippet seguente mostra come configurare CMakeLists.txt
per creare un programma YASM come libreria condivisa.
cmake_minimum_required(VERSION 3.6.0)
enable_language(ASM_NASM)
add_library(test-yasm SHARED jni/test-yasm.c jni/print_hello.asm)
Per un esempio di come creare un programma YASM come eseguibile, consulta yasm test nel repository Git NDK.
Segnalare i problemi
Se riscontri problemi con l'NDK o il relativo file toolchain CMake, segnalali tramite l'Issue Tracker android-ndk/ndk su GitHub. In caso di problemi con il plug-in Gradle o Android Gradle, segnala un bug di Studio.