CMake

Android NDK, uygulamanız için C ve C++ kodunu derlemek için CMake'i kullanmayı destekler. Bu sayfada, Android Gradle Plugin ExternalNativeBuild aracılığıyla veya doğrudan CMake çağrılırken CMake'in NDK ile nasıl kullanılacağı açıklanmaktadır.

CMake araç zinciri dosyası

NDK, bir araç zinciri dosyası aracılığıyla CMake'i destekler. Araç zinciri dosyaları, çapraz derleme için araç zincirinin davranışını özelleştiren CMake dosyalarıdır. NDK için kullanılan araç zinciri dosyası <NDK>/build/cmake/android.toolchain.cmake adresindeki NDK'da bulunur.

cmake çağrılırken ABI, minSdkVersion vb. derleme parametreleri komut satırında verilir. Desteklenen bağımsız değişkenlerin listesi için Araç zinciri bağımsız değişkenleri bölümüne bakın.

Kullanım

Grad

externalNativeBuild kullanılırken CMake araç zinciri dosyasının kullanımı otomatiktir. Daha fazla bilgi için Android Studio'nun Projenize C ve C++ kodu ekleme kılavuzuna bakın.

Komut Satırı

CMake ile Gradle dışında derleme yaparken araç zinciri dosyasının ve bağımsız değişkenlerinin CMake'e iletilmesi gerekir. Örneğin:

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

Araç zinciri bağımsız değişkenleri

Aşağıdaki bağımsız değişkenler, CMake araç zinciri dosyasına aktarılabilir. Gradle ile derleme yapıyorsanız android.defaultConfig.externalNativeBuild.cmake.arguments bağımsız değişkenlerini ExternalNativeBuild dokümanlarında açıklandığı şekilde ekleyin. Komut satırından derleme yapıyorsanız bağımsız değişkenleri CMake ile -D öğesine iletin. Örneğin, armeabi-v7a'yı her zaman Neon desteğiyle derlemeye zorlamak için -DANDROID_ARM_NEON=TRUE değerini geçirin.

ANDROID_ABI

Hedef ABI. Desteklenen ABI'lar hakkında bilgi edinmek için Android ABI'lar bölümüne bakın.

Grad

Gradle bu bağımsız değişkeni otomatik olarak sağlar. Bu bağımsız değişkeni build.gradle dosyanızda açıkça ayarlamayın. ABI Gradle'ın hangi hedefleri hedeflediğini kontrol etmek için Android ABI'ler bölümünde açıklandığı gibi abiFilters kullanın.

Komut Satırı

C derleme başına tek bir hedef için derlemeler oluşturun. Birden fazla Android ABI'yı hedeflemek için her ABI için bir kez derleme yapmanız gerekir. Derlemeler arasında çakışma olmasını önlemek amacıyla her ABI için farklı derleme dizinleri kullanmanız önerilir.

Değer Notlar
armeabi-v7a
armeabi-v7a with NEON -DANDROID_ABI=armeabi-v7a -DANDROID_ARM_NEON=ON ile aynıdır.
arm64-v8a
x86
x86_64

ANDROID_ARM_MODE

armeabi-v7a için kol veya başparmak talimatlarının oluşturulup oluşturulmayacağını belirtir. Diğer ABI'lara etkisi yoktur. Daha fazla bilgi için Android ABI dokümanlarına bakın.

Değer Notlar
etkinleştir
parmak Varsayılan davranış.

ANDROID_ARM_NEON

armeabi-v7a için NEON'u etkinleştirir veya devre dışı bırakır. Diğer ABI'lar üzerinde etkisi yoktur. Varsayılan olarak API düzeyi (minSdkVersion veya ANDROID_PLATFORM) 23 veya daha yeni için yanlış değerine ayarlanır, aksi takdirde yanlış değerini alır. Daha fazla bilgi için Neon destek dokümanlarına bakın.

Değer Notlar
DOĞRU API düzeyi 23 veya sonraki sürümler için varsayılan ayardır.
YANLIŞ API düzeyi 22 veya öncesi için varsayılan ayardır.

ANDROID_LD

Kullanılacak bağlayıcıyı seçer. lld, şu anda NDK için deneyseldir ve bu bağımsız değişkenle etkinleştirilebilir.

Değer Notlar
l LL'yi etkinleştirir.
varsayılan Belirtilen ABI için varsayılan bağlayıcıyı kullanın.

ANDROID_NATIVE_API_LEVEL

ANDROID_PLATFORM için takma ad.

ANDROID_PLATFORM

Uygulama veya kitaplık tarafından desteklenen minimum API düzeyini belirtir. Bu değer, uygulamanın minSdkVersion özelliğine karşılık gelir.

Grad

Android Gradle eklentisi kullanılırken bu değer, uygulamanın minSdkVersion ile eşleşecek şekilde otomatik olarak ayarlanır ve manuel olarak ayarlanmamalıdır.

Komut Satırı

CMake doğrudan çağrılırken, bu değer varsayılan olarak NDK tarafından kullanılan en düşük API düzeyini kullanır. Örneğin, NDK r20 kullanıldığında bu değer varsayılan olarak API düzeyi 16'ya ayarlanır.

Bu parametre için birden fazla biçim kabul edilir:

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

$API_LETTER biçimi, sürümle ilişkili sayıyı belirlemenize gerek kalmadan android-N öğesini belirtmenize olanak tanır. Bazı sürümlerin harf artışı olmadan API artışı aldığını unutmayın. Bu API'ler, -MR1 son ekini ekleyerek belirtilebilir. Örneğin, API düzeyi 25 android-N-MR1.

ANDROID_STL

Bu uygulama için hangi STL'nin kullanılacağını belirtir. Daha fazla bilgi için C++ Kitaplığı desteği bölümünü inceleyin. Varsayılan olarak c++_static kullanılır.

Değer Notlar
++paylaşıldı libc++ öğesinin paylaşılan kitaplık varyantı.
c++_statik libc++ öğesinin statik kitaplık varyantı.
yok C++ standart kitaplık desteği yok.
sistem Sistem STL'si

CMake derleme komutunu anlama

CMake derleme sorunlarını ayıklarken Gradle'ın Android için çapraz derleme yaparken kullandığı belirli derleme bağımsız değişkenlerini bilmek yararlıdır.

Android Gradle eklentisi, her ABI için Make derleme ve derleme türü çifti yürütme işlemi için kullandığı derleme bağımsız değişkenlerini build_command.txt öğesine kaydeder. Bu dosyalar aşağıdaki dizinde bulunur:

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

Aşağıdaki snippet'te, armeabi-v7a mimarisini hedefleyen hello-jni örneğinin hata ayıklaması yapılabilir bir sürümünü oluşturmak için CMake bağımsız değişkenlerinin bir örneği gösterilmektedir.

                    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

Önceden oluşturulmuş kitaplıkları kullanma

İçe aktarmanız gereken önceden oluşturulmuş kitaplık AAR olarak dağıtılmışsa bu dosyaları içe aktarmak ve kullanmak için Studio'nun bağımlı dokümanlarını uygulayın. AGP kullanmıyorsanız https://google.github.io/prefab/example-workflow.html sayfasını takip edebilirsiniz. Ancak AGP'ye geçiş yapmak muhtemelen çok daha kolay olacaktır.

AAR olarak dağıtılmamış kitaplıklar için CMake ile önceden oluşturulmuş kitaplıkları kullanma talimatları için CMake kılavuzundaki IMPORTED hedefleriyle ilgili add_library dokümanlarına bakın.

Üçüncü taraf kodu oluşturma

CMake projeniz kapsamında üçüncü taraf kodu oluşturmanın çeşitli yolları vardır ve durumunuza en uygun seçenek hangileridir? Genellikle en iyi seçenek, bunu hiç yapmamaktır. Bunun yerine, kitaplık için bir AAR oluşturun ve bunu uygulamanızda kullanın. Bu AAR'yi yayınlamanız gerekmez. Bu işlem Gradle projenizin içinde olabilir.

Bu seçenek sunulmuyorsa:

  • Deponuza üçüncü taraf kaynağı yükleyin (ör. kopyalayın) ve derlemek için add_subdirectory'i kullanın. Bu özellik, yalnızca diğer kitaplık CMake ile oluşturulmuşsa çalışır.
  • Bir ExternalProject tanımlayın.
  • Kitaplığı, projenizden ayrı olarak derleyin ve önceden oluşturulmuş olarak içe aktarmak için Önceden oluşturulmuş kitaplıkları kullan'ı uygulayın.

CMake'de YASM desteği

NDK, x86 ve x86-64 mimarilerinde çalıştırmak için YASM'de yazılmış montaj kodunun oluşturulması için CMake desteği sağlar. YASM, NASM derleyici uygulamasını temel alan x86 ve x86-64 mimarileri için açık kaynaklı bir derleyicidir.

CMake ile montaj kodu oluşturmak için projenizin CMakeLists.txt bölümünde aşağıdaki değişiklikleri yapın:

  1. enable_language için değeri ASM_NASM olarak ayarlayın.
  2. Paylaşılan kitaplık veya yürütülebilir ikili dosya oluşturmanıza bağlı olarak add_library veya add_executable numaralı telefonu arayın. Bağımsız değişkenlerde, YASM'deki derleme programı için .asm dosyaları ve ilişkili C kitaplıkları veya işlevleri için .c dosyalarından oluşan bir kaynak dosya listesi iletin.

Aşağıdaki snippet, CMakeLists.txt uygulamasını paylaşılan kitaplık olarak bir YASM programı oluşturmak için nasıl yapılandırabileceğinizi gösterir.

cmake_minimum_required(VERSION 3.6.0)

enable_language(ASM_NASM)

add_library(test-yasm SHARED jni/test-yasm.c jni/print_hello.asm)

YASM programının yürütülebilir olarak nasıl oluşturulacağına dair örnek için NDK git deposundaki yasm testine göz atın.

Sorun bildirme

NDK veya CMake araç zinciri dosyasıyla ilgili herhangi bir sorunla karşılaşırsanız sorunları GitHub'daki android-ndk/ndk sorun izleyici yoluyla bildirin. Gradle veya Android Gradle Plugin sorunları için Studio hatasını bildirin.