CMake

Android NDK supporta l'utilizzo di CMake per e compilare codice C e C++ per la tua applicazione. In questa pagina viene illustrato come utilizzare Crea con l'NDK tramite il ExternalNativeBuild del plug-in Android Gradle o quando richiamando direttamente CMake.

Il file della toolchain CMake

NDK supporta CMake tramite un file toolchain. I file Toolchain sono file CMake che personalizzano il comportamento della toolchain per la compilazione incrociata. La toolchain il file 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 sono forniti nel comando riga quando richiami cmake. Per un elenco degli argomenti supportati, consulta Sezione Argomenti della catena degli strumenti.

Il "nuovo" file toolchain

In precedenza, gli NDK hanno sperimentato una nuova implementazione del file toolchain, ovvero ridurrebbero le differenze di comportamento tra l'uso del file toolchain dell'NDK e usando il supporto integrato di CMake. Abbiamo richiesto una quantità significativa di di lavoro (che non è stato completato), ma che in realtà non ha migliorato il comportamento, quindi non lo abbiamo più in mente.

Il "nuovo" il file toolchain presenta regressioni del comportamento rispetto al file "legacy" Toolchain. Il comportamento predefinito è il flusso di lavoro consigliato. Se utilizzando -DANDROID_USE_LEGACY_TOOLCHAIN_FILE=OFF, consigliamo di rimuovere il flag dalla tua build. Il nuovo file Toolchain non ha mai raggiunto lo stesso livello della versione precedente del file di strumenti, quindi è probabile che si verifichino regressioni del comportamento.

Anche se sconsigliamo di utilizzare il nuovo file Toolchain, al momento non sono disponibili intende rimuoverli dall'NDK. Questo causerebbe l'interruzione delle build che si basano differenze di comportamento tra i file della serie di strumenti nuovi e legacy e purtroppo rinominando l'opzione per chiarire che "legacy" è in realtà consigliato interrompe l'utilizzo di questa opzione. Se stai utilizzando il modello nuovo file Toolchain di cui non è necessario eseguire la migrazione, ma sappi che eventuali bug segnalati il comportamento dei file di toolchain non verrà risolto, ma che dovrai migrare.

Utilizzo

Gradle

L'utilizzo del file toolchain CMake è automatico quando externalNativeBuild. Consulta la sezione di Android Studio Aggiungere il codice C e C++ ai progetto per ulteriori informazioni.

Riga di comando

Quando crei con CMake al di fuori di Gradle, il file Toolchain stesso e i suoi argomenti devono essere passati a CMake. Ad esempio:

$ cmake \
    -DCMAKE_TOOLCHAIN_FILE=$NDK/build/cmake/android.toolchain.cmake \
    -DANDROID_ABI=$ABI \
    -DANDROID_PLATFORM=android-$MINSDKVERSION \
    $OTHER_ARGS

Argomenti della Toolchain

I seguenti argomenti possono essere passati al file toolchain CMake. Se crei con Gradle, aggiungi argomenti android.defaultConfig.externalNativeBuild.cmake.arguments come descritto nei Documentazione su External NativeBuild. Se crei dalla riga di comando, passa argomenti Crea con -D. Ad esempio, per forzare armeabi-v7a a non creare con Neon assistenza, supera -DANDROID_ARM_NEON=FALSE.

ANDROID_ABI

L'ABI di destinazione. Per informazioni sulle ABI supportate, vedi ABI Android.

Gradle

Gradle fornisce questo argomento automaticamente. Non impostare esplicitamente questa opzione nel tuo file build.gradle. Per controllare le ABI scelte come target da Gradle, usa abiFilters come descritto in ABI Android.

Riga di comando

Crea build per un singolo target per ogni build. Per scegliere come target più di un Android Un'ABI deve essere creata una volta per ogni ABI. È consigliabile usare build diverse per ogni ABI al fine di evitare collisioni tra le build.

Valore Note
armeabi-v7a
armeabi-v7a with NEON Uguale a armeabi-v7a.
arm64-v8a
x86
x86_64

ANDROID_ARM_MODE

Specifica se generare istruzioni per il braccio o il pollice per armeabi-v7a. Non contiene effetto per altre ABI. Per maggiori informazioni, consulta le ABI Android documentazione.

Valore Note
un braccio
pollice Comportamento predefinito.

ANDROID_NATIVE_API_LEVEL

Alias per ANDROID_PLATFORM.

ANDROID_PLATFORM

Specifica il livello API minimo supportato dall'applicazione o dalla libreria. Questo corrisponde al valore minSdkVersion dell'applicazione.

Gradle

Quando utilizzi il plug-in Android Gradle, questo valore viene impostato automaticamente su corrisponde al valore minSdkVersion dell'applicazione e non deve essere impostato manualmente.

Riga di comando

Quando si richiama direttamente CMake, questo valore viene impostato sul livello API più basso per impostazione predefinita supportate dalla NDK in uso. Ad esempio, con NDK r20 questo valore viene impostato al livello API 16.

Sono accettati più formati per questo parametro:

  • android-$API_LEVEL
  • $API_LEVEL
  • android-$API_LETTER

Il formato $API_LETTER consente di specificare android-N senza dover determinare il numero associato a quell'uscita. Tieni presente che alcune release ha ricevuto un aumento dell'API senza un aumento letterale. Queste API possono essere specificate aggiungendo il suffisso -MR1. Ad esempio, il livello API 25 è android-N-MR1.

ANDROID_STL

Specifica l'STL da utilizzare per questa applicazione. Per ulteriori informazioni, vedi C++ il supporto dalle librerie. Per impostazione predefinita, verrà utilizzato c++_static.

Valore Note
c++_shared La variante della libreria condivisa di libc++.
c++_statico La variante della libreria statica di libc++.
nessuno Nessun supporto per la libreria standard C++.
di infotainment L'STL del sistema

Gestisci flag del compilatore

Se devi passare flag specifici al compilatore o al linker per la tua build, consulta la documentazione di CMake per set_target_compile_options e una famiglia di opzioni correlata. L'opzione "vedi anche" sezione in fondo alla pagina ha alcuni indizi utili.

In generale, la best practice prevede l'applicazione dei flag del compilatore nell'ambito disponibile. Le segnalazioni da applicare a tutti i target (ad esempio -Werror) è scomodo ripeterlo per modulo, ma raramente dovrebbe esserlo applicati a livello globale (CMAKE_CXX_FLAGS), in quanto potrebbero avere effetti indesiderati con dipendenze di terze parti nel progetto. In questi casi, i flag possono essere applicata a livello di directory (add_compile_options).

Per un sottoinsieme limitato di flag del compilatore, puoi impostarli anche nel file build.gradle utilizzando cppFlags o proprietà simili. Sconsigliamo di farlo. Flag passati a CMake da Gradle avranno comportamenti di precedenza sorprendenti, in alcuni che eseguono l'override di flag passati implicitamente dall'implementazione e che sono necessaria per creare il codice Android. Preferisco sempre gestire il comportamento CMake direttamente in CMake. Se devi controllare i flag del compilatore per buildType AGP, consulta Utilizzare i tipi di build AGP in CMake.

Utilizzare i tipi di build AGP in CMake

Se hai bisogno di personalizzare il comportamento CMake per un buildType Gradle personalizzato, usalo per passare un flag CMake aggiuntivo (non un flag del compilatore) Gli script di build CMake sono in grado di leggere. Ad esempio, se hai "senza costi" e "premium" creare varianti controllate dal tuo file build.gradle.kts e devi superare a CMake:

android {
    buildTypes {
        free {
            externalNativeBuild {
                cmake {
                    arguments.add("-DPRODUCT_VARIANT_PREMIUM=OFF")
                }
            }
        }
        premium {
            externalNativeBuild {
                cmake {
                    arguments.add("-DPRODUCT_VARIANT_PREMIUM=ON")
                }
            }
        }
    }
}

Quindi, nel file CMakeLists.txt:

if (DPRODUCT_VARIANT_PREMIUM)
  # Do stuff for the premium build.
else()
  # Do stuff for the free build.
endif()

Sei tu a decidere il nome della variabile, ma assicurati di evitare qualsiasi cosa con un Prefisso ANDROID_, APP_ o CMAKE_ per evitare collisioni o confusione con i flag esistenti.

Per un esempio, consulta l'esempio di igienizzanti NDK.

Informazioni sul comando di build CMake

Quando esegui il debug dei problemi di build di CMake, è utile conoscere la build specifica argomenti utilizzati da Gradle durante la compilazione incrociata per Android.

Il plug-in Android Gradle salva gli argomenti di build che utilizza per l'esecuzione di Crea build per ogni ABI e tipo di build accoppia il dispositivo a build_command.txt. Questi file si trovano nel seguente directory:

<project-root>/<module-root>/.cxx/cmake/<build-type>/<ABI>/

Il seguente snippet mostra un esempio degli argomenti CMake per creare release di cui è possibile eseguire il debug dell'esempio hello-jni che ha come target armeabi-v7a dell'architettura.

                    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

Usa le librerie predefinite

Se la libreria predefinita che devi importare è distribuita come AAR, segui Documentazione sulle dipendenze di Studio per importarli e utilizzarli. Se non utilizzi AGP, puoi seguire https://google.github.io/prefab/example-workflow.html, ma probabilmente è molto la migrazione ad AGP.

Per le librerie che non sono distribuite come AAR, le istruzioni sull'utilizzo librerie con CMake, consulta la documentazione di add_library relativa a IMPORTED target nel CMake manuale.

Creazione di codice di terze parti

Esistono diversi modi per generare codice di terze parti nell'ambito di CMake progetto e quale opzione funziona meglio dipenderà dalla tua situazione. Il meglio l'opzione di non farlo affatto. Puoi invece creare un AAR per il libreria e utilizzarlo nella tua applicazione. Non è necessario che tu pubblicare il file AAR. Può essere interno al tuo progetto Gradle.

Se non è possibile:

  • Il fornitore (ovvero copia) l'origine di terze parti nel tuo repository e utilizza add_subdirectory per crearlo. Funziona solo se anche l'altra libreria creato con CMake.
  • Definisci un ExternalProject.
  • Crea la libreria separatamente dal tuo progetto e segui Utilizza le librerie predefinite per importarlo come predefinito.

Supporto YASM in CMake

NDK fornisce il supporto CMake per la creazione di codice di assemblaggio scritto in YASM per l'esecuzione su x86 e x86-64 diverse architetture. YASM è un assemblatore open source per x86 e x86-64 di archiviazione, basate sull'assemblatore NASM.

Per creare codice Assembly con CMake, apporta le seguenti modifiche nella riga CMakeLists.txt:

  1. Chiama enable_language con il valore impostato su ASM_NASM.
  2. A seconda che tu stia creando una libreria condivisa o un eseguibile binario, richiama add_library o add_executable. Nella gli argomenti, passa in un elenco di file di origine composti da .asm file per il programma di assemblaggio in YASM e i file .c per il file C associato librerie o funzioni.

Il seguente snippet mostra come potresti 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 il documento yasm test nel repository Git NDK.

Segnalare i problemi

Se riscontri problemi con l'NDK o con il relativo file toolchain CMake, segnalali tramite lo strumento di monitoraggio dei problemi android-ndk/ndk su GitHub. Per Gradle o Problemi del plug-in Android Gradle. Segnala un bug di Studio.