Das Android-NDK unterstützt die Verwendung von CMake, um C- und C++-Code für Ihre Anwendung zu kompilieren. Auf dieser Seite wird erläutert, wie Sie CMake mit dem NDK über ExternalNativeBuild
des Android-Gradle-Plug-ins verwenden oder wenn Sie CMake direkt aufrufen.
Die CMake-Toolchain-Datei
Der NDK unterstützt CMake über eine Toolchain-Datei. Toolchain-Dateien sind CMake-Dateien, mit denen das Verhalten der Toolchain für die Cross-Kompilierung angepasst wird. Die für den NDK verwendete Toolchain-Datei befindet sich im NDK unter <NDK>/build/cmake/android.toolchain.cmake
.
Build-Parameter wie ABI, minSdkVersion
usw. werden beim Aufrufen von cmake
in der Befehlszeile angegeben. Eine Liste der unterstützten Argumente finden Sie im Abschnitt Toolchain-Argumente.
Nutzung
Gradle
Bei Verwendung von externalNativeBuild
wird die CMake-Toolchain-Datei automatisch verwendet. Weitere Informationen finden Sie in der Android Studio-Anleitung zum Hinzufügen von C- und C++-Code in Ihr Projekt.
Befehlszeile
Wenn Sie mit CMake außerhalb von Gradle arbeiten, müssen die Toolchain-Datei selbst und ihre Argumente an CMake übergeben werden. Beispiele:
$ cmake \
-DCMAKE_TOOLCHAIN_FILE=$NDK/build/cmake/android.toolchain.cmake \
-DANDROID_ABI=$ABI \
-DANDROID_PLATFORM=android-$MINSDKVERSION \
$OTHER_ARGS
Toolchain-Argumente
Die folgenden Argumente können an die CMake-Toolchain-Datei übergeben werden. Wenn Sie Builds mit Gradle erstellen, fügen Sie android.defaultConfig.externalNativeBuild.cmake.arguments
Argumente hinzu, wie in der ExternalNativeBuild-Dokumentation beschrieben. Wenn Sie die Erstellung über die Befehlszeile ausführen, übergeben Sie Argumente mit -D
an CMake. Wenn Sie beispielsweise erzwingen möchten, dass armeabi-v7a nicht mit Neon unterstützt wird, übergeben Sie -DANDROID_ARM_NEON=FALSE
.
ANDROID_ABI
Das Ziel-ABIs. Informationen zu unterstützten ABIs finden Sie unter Android-ABIs.
Gradle
Gradle stellt dieses Argument automatisch bereit. Legen Sie dieses Argument in der Datei build.gradle
nicht explizit fest. Wenn Sie festlegen möchten, auf welche ABIs Gradle ausgerichtet ist, verwenden Sie abiFilters
, wie unter Android-ABIs beschrieben.
Befehlszeile
CMake-Builds für ein einzelnes Ziel pro Build. Wenn du ein Targeting auf mehr als ein Android-ABI vornehmen möchtest, musst du einmal pro ABI erstellen. Es wird empfohlen, für jedes ABI unterschiedliche Build-Verzeichnisse zu verwenden, um Kollisionen zwischen Builds zu vermeiden.
Antwort | Hinweise |
---|---|
armeabi-v7a |
|
armeabi-v7a with NEON |
Wie bei armeabi-v7a . |
arm64-v8a |
|
x86 |
|
x86_64 |
ANDROID_ARM_MODE
Gibt an, ob für armeabi-v7a Verzweigungs- oder Daumenanweisungen erstellt werden sollen. Hat keine Auswirkungen auf andere ABIs. Weitere Informationen findest du in der Dokumentation zu Android-ABIs.
Antwort | Hinweise |
---|---|
Arm | |
Daumen | Standardverhalten. |
ANDROID_ARM_NEON
Aktiviert oder deaktiviert NEON für armeabi-v7a. Hat keine Auswirkungen auf andere ABIs. Die Standardeinstellung ist „true“ für API-Level (minSdkVersion
oder ANDROID_PLATFORM
) 23 oder höher, andernfalls „false“. Weitere Informationen finden Sie in der Dokumentation zum Neon-Support.
Antwort | Hinweise |
---|---|
RICHTIG | Standardeinstellung für API-Level 23 oder höher. |
FALSCH | Standardeinstellung für API-Level 22 oder älter. |
ANDROID_LD
Wählt die Verknüpfung aus. lld wird derzeit für den NDK getestet und kann mit diesem Argument aktiviert werden.
Antwort | Hinweise |
---|---|
LDL | Aktiviert lld. |
Standard | Verwenden Sie die Standardverknüpfung für das angegebene ABI. |
ANDROID_NATIVE_API_LEVEL
Alias für ANDROID_PLATFORM.
ANDROID_PLATFORM
Gibt das von der Anwendung oder Bibliothek unterstützte minimale API-Level an. Dieser Wert entspricht dem minSdkVersion
der Anwendung.
Gradle
Wenn Sie das Android-Gradle-Plug-in verwenden, wird dieser Wert automatisch auf die minSdkVersion
der App festgelegt und sollte nicht manuell festgelegt werden.
Befehlszeile
Wenn CMake direkt aufgerufen wird, wird für diesen Wert standardmäßig die niedrigste API-Ebene verwendet, die von der verwendeten NDK unterstützt wird. Bei NDK r20 ist dieser Wert beispielsweise standardmäßig das API-Level 16.
Für diesen Parameter sind mehrere Formate zulässig:
android-$API_LEVEL
$API_LEVEL
android-$API_LETTER
Mit dem Format $API_LETTER
kannst du android-N
angeben, ohne die mit diesem Release verknüpfte Nummer ermitteln zu müssen. Beachten Sie, dass einige Releases eine API-Erhöhung ohne Buchstabenerhöhung erhalten haben. Diese APIs können durch Anfügen des Suffix -MR1
angegeben werden. API-Level 25 ist beispielsweise android-N-MR1
.
ANDROID_STL
Gibt an, welcher STL für diese Anwendung verwendet werden soll. Weitere Informationen finden Sie unter Unterstützung von C++-Bibliotheken. Standardmäßig wird c++_static
verwendet.
Antwort | Hinweise |
---|---|
c++_geteilt | Die gemeinsam genutzte Bibliotheksvariante von libc++. |
c++_statisch | Die statische Bibliotheksvariante von libc++. |
Keine | Die C++-Standardbibliothek wird nicht unterstützt. |
Infotainmentsystem | System-STL |
Informationen zum Befehl „CMake erstellen“
Beim Beheben von CMake-Build-Problemen ist es hilfreich, die spezifischen Build-Argumente zu kennen, die Gradle bei der Cross-Kompilierung für Android verwendet.
Das Android Gradle-Plug-in speichert die Build-Argumente, mit denen ein CMake-Build für jedes ABI- und Build-Typ-Paar ausgeführt wird, im build_command.txt
. Diese Dateien befinden sich im folgenden Verzeichnis:
<project-root>/<module-root>/.cxx/cmake/<build-type>/<ABI>/
Das folgende Snippet zeigt ein Beispiel für CMake-Argumente zum Erstellen eines debugfähigen Release des Beispiels hello-jni
, das auf die armeabi-v7a
-Architektur ausgerichtet ist.
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
Vordefinierte Bibliotheken verwenden
Wenn die vordefinierte Bibliothek, die Sie importieren müssen, als AAE bereitgestellt wird, folgen Sie den Abhängigkeitsdokumenten von Studio, um diese zu importieren und zu verwenden. Wenn Sie AGP nicht verwenden, können Sie dem Beispiel unter https://google.github.io/prefab/example-workflow.html folgen. Es ist jedoch wahrscheinlich einfacher, zu AGP zu migrieren.
Anleitungen zur Verwendung vordefinierter Bibliotheken mit CMake finden Sie in der add_library
-Dokumentation zu IMPORTED
-Zielen im CMake-Handbuch.
Drittanbietercode erstellen
Es gibt verschiedene Möglichkeiten, im Rahmen Ihres CMake-Projekts Drittanbietercode zu erstellen. Welche Option am besten funktioniert, hängt von Ihrer Situation ab. Oft ist es die beste Option, das überhaupt nicht zu tun. Erstellen Sie stattdessen ein AAE für die Bibliothek und nutzen Sie dieses in Ihrer Anwendung. Sie müssen solche automatisch angewendeten Empfehlungen nicht unbedingt veröffentlichen. Sie kann intern zu Ihrem Gradle-Projekt gehören.
Falls dies nicht möglich ist, gehen Sie so vor:
- Der Anbieter (kopiert) die Drittanbieterquelle in Ihr Repository und erstellt sie mit add_subdirectory. Dies funktioniert nur, wenn die andere Bibliothek ebenfalls mit CMake erstellt wurde.
- Definieren Sie ein ExternalProject.
- Erstellen Sie die Bibliothek getrennt von Ihrem Projekt und folgen Sie der Anleitung unter Vordefinierte Bibliotheken verwenden, um sie als vordefinierte zu importieren.
YASM-Unterstützung in CMake
Das NDK bietet CMake-Unterstützung für das Erstellen von Assembly-Code, der in YASM geschrieben wurde und auf x86- und x86-64-Architekturen ausgeführt wird. YASM ist ein Open-Source-Assembler für x86- und x86-64-Architekturen, die auf dem NASM-Assembr basieren.
Wenn Sie Assembly-Code mit CMake erstellen möchten, nehmen Sie die folgenden Änderungen an der Datei CMakeLists.txt
Ihres Projekts vor:
- Rufen Sie
enable_language
mit dem WertASM_NASM
auf. - Je nachdem, ob Sie eine gemeinsam genutzte Bibliothek oder eine ausführbare Binärdatei erstellen, rufen Sie
add_library
oderadd_executable
auf. Übergeben Sie in den Argumenten eine Liste der Quelldateien, die aus den.asm
-Dateien für das Assembly-Programm in YASM und den.c
-Dateien für die zugehörigen C-Bibliotheken oder -Funktionen besteht.
Das folgende Snippet zeigt, wie Sie CMakeLists.txt
konfigurieren können, um ein YASM-Programm als gemeinsam genutzte Bibliothek zu erstellen.
cmake_minimum_required(VERSION 3.6.0)
enable_language(ASM_NASM)
add_library(test-yasm SHARED jni/test-yasm.c jni/print_hello.asm)
Ein Beispiel zum Erstellen eines YASM-Programms als ausführbare Datei finden Sie im yasm-Test im NDK-Git-Repository.
Probleme melden
Wenn Probleme mit dem NDK oder der zugehörigen CMake-Toolchain-Datei auftreten, melden Sie diese über die android-ndk/ndk-Problemverfolgung auf GitHub. Bei Problemen mit Gradle oder Android Gradle-Plug-ins können Sie stattdessen einen Studio-Fehler melden.