CMarka

Android NDK, uygulamanız için C ve C++ kodunu derlemek amacıyla CMake'ın kullanılmasını destekler. Bu sayfada, Android Gradle Eklentisi'nin ExternalNativeBuild aracılığıyla veya CMake'i doğrudan çağırırken NDK ile CMake'in nasıl kullanılacağı anlatılmaktadır.

CMake toolchain dosyası

NDK, CMake'i bir araç zinciri dosyası aracılığıyla 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'da <NDK>/build/cmake/android.toolchain.cmake konumunda bulunur.

cmake çağrılırken komut satırında ABI, minSdkVersion gibi derleme parametreleri 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

Gradle

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

Komut Satırı

Gradle dışında CMake ile derleme yaparken araç zinciri dosyasının kendisi ve bağımsız değişkenleri CMake'e iletilmelidir. Örnek:

$ 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 derliyorsanız ExternalNativeBuild belgelerinde açıklandığı gibi android.defaultConfig.externalNativeBuild.cmake.arguments öğesine bağımsız değişkenler ekleyin. Komut satırından derliyorsanız -D ile CMake'e bağımsız değişkenler iletin. Örneğin, armeabi-v7a'yı Neon desteğiyle derlememeye zorlamak için -DANDROID_ARM_NEON=FALSE kodunu iletin.

ANDROID_ABI

Hedef ABI. Desteklenen ABI'ler hakkında bilgi edinmek için Android ABI'leri konusuna bakın.

Gradle

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 belirtmeyin. ABI'ler Gradle'ın neleri hedeflediğini kontrol etmek için Android ABI'leri bölümünde açıklandığı gibi abiFilters işlevini kullanın.

Komut Satırı

CMake derleme başına tek bir hedef için derleme yapar. Birden fazla Android ABI'yı hedeflemek için ABI başına bir kez derlemeniz gerekir. Derlemeler arasında çakışmaları önlemek amacıyla her ABI için farklı derleme dizinleri kullanmanız önerilir.

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

ANDROID_ARM_MODE

armeabi-v7a için kol talimatları veya baş parmak talimatları oluşturulup oluşturulmayacağını belirtir. Diğer ABI'ler üzerinde bir etkisi yoktur. Daha fazla bilgi için Android ABI'leri belgelerine bakın.

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

ANDROID_ARM_NEON

armeabi-v7a için NEON'u etkinleştirir veya devre dışı bırakır. Diğer ABI'ler için bir etkisi yoktur. API düzeyi (minSdkVersion veya ANDROID_PLATFORM) 23 veya daha yeni sürümleri için varsayılan olarak true (doğru), aksi durumda false (yanlış) değerine ayarlanı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ılandır.
YANLIŞ API düzeyi 22 veya önceki sürümler için varsayılan olarak ayarlanır.

ANDROID_LD

Hangi bağlayıcının kullanılacağını seçer. lld, şu anda NDK için deneyseldir ve bu bağımsız değişkenle etkinleştirilebilir.

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

ANDROID_NATIVE_API_LEVEL

ANDROID_PLATFORM takma adı.

ANDROID_PLATFORM

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

Gradle

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

Komut Satırı

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

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

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

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

ANDROID_STL

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

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

CMake derleme komutunu anlama

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

Android Gradle Eklentisi, build_command.txt ile her ABI ve derleme türü çifti için CMake derlemesi yürütmek üzere kullandığı derleme bağımsız değişkenlerini 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ü derlemek 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 bunları içe aktarmak ve kullanmak için Studio'nun bağımlılık belgelerini izleyin. AGP kullanmıyorsanız https://google.github.io/prefab/example-workflow.html adresindeki sayfaya bakabilirsiniz. Ancak AGP'ye geçmek muhtemelen çok daha kolaydır.

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

Üçüncü taraf kodu oluşturma

CMake projenizin bir parçası olarak üçüncü taraf kodu derlemenin çeşitli yolları vardır ve hangi seçeneğin en iyi sonucu vereceği, durumunuza bağlı olarak değişir. Çoğu zaman en iyi seçenek, bunu hiç yapmamaktır. Bunun yerine, kitaplık için bir AAR oluşturun ve uygulamanızda kullanın. Bu AAR'yi yayınlamanız gerekmez. Bu, Gradle projenizin içinde olabilir.

Bu seçenek mümkün değilse:

  • Üçüncü taraf kaynağı kod deponuza gönderin (ör. kopyalayın) ve kaynak oluşturmak için add_subdirectory kullanın. Bu işlem yalnızca diğer kitaplık da CMake ile oluşturulduğunda işe yarar.
  • ExternalProject tanımlayın.
  • Kitaplığı projenizden ayrı olarak oluşturun ve önceden oluşturulmuş olarak içe aktarmak için Önceden oluşturulmuş kitaplıkları kullanma talimatlarını uygulayın.

CMake'de YASM desteği

NDK, x86 ve x86-64 mimarilerinde çalışmak üzere YASM'de yazılmış derleme kodu derlemek için CMake desteği sağlar. YASM, NASM derleyicisine dayalı, x86 ve x86-64 mimarileri için açık kaynaklı bir derleyicidir.

CMake ile derleme kodu oluşturmak için projenizin CMakeLists.txt kodunda aşağıdaki değişiklikleri yapın:

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

Aşağıdaki snippet, bir YASM programını paylaşılan kitaplık olarak oluşturmak için CMakeLists.txt öğenizi 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)

Bir YASM programının yürütülebilir olarak nasıl derleneceğine dair bir örnek için NDK git deposundaki yasm testi bölümüne bakın.

Sorun bildirme

NDK veya CMake araç zinciri dosyasıyla ilgili herhangi bir sorunla karşılaşırsanız GitHub'daki android-ndk/ndk sorun izleyicisini kullanarak bildirin. Gradle veya Android Gradle Eklentisi ile ilgili sorunlar için bunun yerine Studio hatası bildirin.