सीमेक

Android NDK, CMake का इस्तेमाल करके, इन कामों के लिए अपने ऐप्लिकेशन के लिए, C और C++ कोड कंपाइल करें. इस पेज पर बताया गया है कि Android Gradle प्लग इन के ExternalNativeBuild के ज़रिए या जब हम सीधे CMake का इस्तेमाल करना चाहते हैं.

CMake टूलचेन फ़ाइल

NDK, टूलचेन फ़ाइल के ज़रिए CMake के साथ काम करता है. टूलचेन फ़ाइलें, CMake फ़ाइलें होती हैं जो क्रॉस-कंपाइलिंग के लिए टूलचेन के व्यवहार को कस्टमाइज़ करती हैं. टूलचेन एनडीके के लिए इस्तेमाल की जाने वाली फ़ाइल एनडीके में इस पते पर मौजूद होती है: <NDK>/build/cmake/android.toolchain.cmake.

एबीआई, minSdkVersion जैसे बिल्ड पैरामीटर, निर्देश पर दिए जाते हैं cmake शुरू करते समय लाइन का इस्तेमाल करें. इस्तेमाल किए जा सकने वाले आर्ग्युमेंट की सूची देखने के लिए, यहां जाएं: टूलचेन आर्ग्युमेंट सेक्शन.

"नया" टूलचेन फ़ाइल

इससे पहले एनडीके ने टूलचेन फ़ाइल को लागू करने के लिए एक नया प्रयोग किया जो यह एनडीके की टूलचेन फ़ाइल और पहले से मौजूद CMake सहायता का इस्तेमाल कर रहे हैं. आखिर में, बहुत ज़्यादा पैसे खर्च करने पड़े काम का है (जो पूरा नहीं हुआ है), लेकिन व्यवहार में सुधार नहीं हुआ है, इसलिए, अब हम इस दिशा में काम नहीं कर रहे हैं.

"नया" टूलचेन फ़ाइल में "लेगसी" की तुलना में व्यवहार रिग्रेशन होता है टूलचेन फ़ाइल में सेव की जाती है. डिफ़ॉल्ट व्यवहार, सुझाया गया वर्कफ़्लो है. अगर आप: हमारा सुझाव है कि आप -DANDROID_USE_LEGACY_TOOLCHAIN_FILE=OFF का इस्तेमाल करके, उस फ़्लैग को हटा दें आपको कुछ कदम उठाने होंगे. नई टूलचेन फ़ाइल कभी भी पुराने वर्शन के बराबर नहीं थी टूलचेन फ़ाइल में एक्सपोर्ट किया जा सकता है, ताकि व्यवहार रिग्रेशन की संभावना हो.

हालांकि, हम नई टूलचेन फ़ाइल का इस्तेमाल न करने का सुझाव देते हैं, लेकिन फ़िलहाल ऐसी कोई को एनडीके से हटाने की योजना बना रहा है. ऐसा करने से वे बिल्ड टूट जाएंगे जो नई और लेगसी टूलचेन फ़ाइलों के व्यवहार में अंतर, और हमें अफ़सोस है कि विकल्प का नाम बदलकर यह साफ़ किया जा रहा है कि "लेगसी" असल में ऐसा है सुझाए गए इस विकल्प का इस्तेमाल करने वाले लोगों को भी नुकसान पहुंच सकता है. यदि आप खुशी से कोई नई टूलचेन फ़ाइल है जिसे आपको माइग्रेट करने की ज़रूरत नहीं है. हालांकि, यह जान लें कि किसी भी गड़बड़ी को के ख़िलाफ़ नई टूलचेन फ़ाइल के काम करने का तरीका तय नहीं किया जाएगा. इसके बजाय आपको माइग्रेट करना होगा.

इस्तेमाल

ग्रेडल

externalNativeBuild. अपने Android Studio के C और C++ कोड जोड़ें प्रोजेक्ट गाइड देखें.

आदेश पंक्ति

Gradle के बाहर CMake का इस्तेमाल करते समय, टूलचेन फ़ाइल और इसके तर्क CMake को पास किए जाने चाहिए. उदाहरण के लिए:

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

टूलचेन के तर्क

CMake टूलचेन फ़ाइल में, ये आर्ग्युमेंट भेजे जा सकते हैं. अगर बना रहे हैं Gradle के साथ, तर्क जोड़ें android.defaultConfig.externalNativeBuild.cmake.arguments जैसा कि इसमें बताया गया है ExternalNativeBuild दस्तावेज़. अगर कमांड लाइन से बनाया जा रहा है, तो आर्ग्युमेंट को -D के साथ CMake करें. उदाहरण के लिए, Armeabi-v7a को नियॉन के साथ न बनाने के लिए बाध्य करना सहायता पाएं, -DANDROID_ARM_NEON=FALSE को पास करें.

ANDROID_ABI

टारगेट एबीआई. इस्तेमाल किए जा सकने वाले एबीआई के बारे में जानकारी के लिए, Android एबीआई देखें.

ग्रेडल

Gradle यह तर्क अपने-आप उपलब्ध कराता है. इसे स्पष्ट रूप से सेट न करें तर्क आपकी build.gradle फ़ाइल में मौजूद होना चाहिए. यह कंट्रोल करने के लिए कि एबीआई Gradle किन टारगेट को टारगेट करता है, abiFilters का इस्तेमाल करना होगा, जैसा कि Android एबीआई में बताया गया है.

आदेश पंक्ति

CMake की मदद से हर बिल्ड के लिए एक ही टारगेट का इस्तेमाल किया जा सकता है. एक से ज़्यादा Android को टारगेट करने के लिए एबीआई, आपको हर एबीआई के लिए एक बार बनाना होगा. हमारा सुझाव है कि आप अलग बिल्ड का इस्तेमाल करें डायरेक्ट्री, हर एबीआई के लिए बनाई गई हैं, ताकि बिल्ड के बीच टकराव से बचा जा सके.

वैल्यू नोट
armeabi-v7a
armeabi-v7a with NEON armeabi-v7a के बराबर किराया.
arm64-v8a
x86
x86_64

ANDROID_ARM_MODE

इस नीति से तय होता है कि Armeabi-v7a के लिए ग्रुप के निर्देश जनरेट करने हैं या थंब निर्देश. इसमें नहीं है का असर दूसरे एबीआई पर पड़ता है. ज़्यादा जानकारी के लिए, Android एबीआई देखें दस्तावेज़.

वैल्यू नोट
बांह
अंगूठा डिफ़ॉल्ट तरीका.

ANDROID_NATIVE_API_LEVEL

ANDROID_PLATFORM के लिए उपनाम.

ANDROID_PLATFORM

ऐप्लिकेशन या लाइब्रेरी के साथ काम करने वाला कम से कम एपीआई लेवल तय करता है. यह मान ऐप्लिकेशन के minSdkVersion से मेल खाता है.

ग्रेडल

'Android Gradle प्लग इन' का इस्तेमाल करते समय, यह वैल्यू अपने-आप ऐप्लिकेशन के minSdkVersion से मेल खाता है और इसे मैन्युअल रूप से सेट नहीं किया जाना चाहिए.

आदेश पंक्ति

सीधे CMake का इस्तेमाल करने पर, यह वैल्यू डिफ़ॉल्ट तौर पर एपीआई लेवल के सबसे निचले स्तर पर सेट हो जाती है NDK, जो इस्तेमाल में है. उदाहरण के लिए, NDK r20 के साथ यह वैल्यू डिफ़ॉल्ट होती है एपीआई लेवल 16 तक.

इस पैरामीटर के लिए कई फ़ॉर्मैट स्वीकार किए जाते हैं:

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

$API_LETTER फ़ॉर्मैट की मदद से, android-N को तय करने की ज़रूरत नहीं पड़ती उस रिलीज़ से जुड़ी संख्या का पता लगाएं. ध्यान रखें कि कुछ रिलीज़ बिना कोई अक्षर बढ़ाए एपीआई में बढ़ोतरी हुई है. इन एपीआई के बारे में बताया जा सकता है -MR1 सफ़िक्स जोड़ें. उदाहरण के लिए, एपीआई लेवल 25 android-N-MR1 है.

ANDROID_STL

बताता है कि इस ऐप्लिकेशन के लिए किस STL का इस्तेमाल करना है. ज़्यादा जानकारी के लिए, C++ लाइब्रेरी सहायता पर टैप करें. डिफ़ॉल्ट रूप से, c++_static का इस्तेमाल किया जाएगा.

वैल्यू नोट
सी++_शेयर किया गया libc++ का शेयर किया गया लाइब्रेरी वैरिएंट.
सी++_स्टैटिक libc++ का स्टैटिक लाइब्रेरी वैरिएंट.
कोई नहीं C++ स्टैंडर्ड लाइब्रेरी के साथ काम नहीं करता.
सिस्‍टम सिस्टम एसटीएल

कंपाइलर फ़्लैग मैनेज करें

अगर आपको अपने बिल्ड के लिए कंपाइलर या लिंकर को कुछ खास फ़्लैग पास करने हैं, set_target_compile_options के लिए CMake दस्तावेज़ देखें और विकल्पों की एक सूची है. "यह भी देखें" सेक्शन में सबसे नीचे मौजूद कुछ मददगार सुराग दे सकते हैं.

आम तौर पर, सबसे सही तरीका यह है कि कंपाइलर फ़्लैग को सबसे छोटे उपलब्ध दायरा. ऐसे फ़्लैग जिन्हें आपको अपने सभी टारगेट पर लागू करना है (जैसे कि -Werror) के लिए हर मॉड्यूल को आसानी से दोहराया नहीं जा सकता. हालांकि, ऐसा बहुत कम होता है ये बदलाव दुनिया भर में लागू होंगे (CMAKE_CXX_FLAGS). ऐसा इसलिए, क्योंकि इन बदलावों के अनचाहे असर हो सकते हैं तीसरे पक्ष की डिपेंडेंसी का इस्तेमाल किया जा सकता है. ऐसे मामलों में, फ़्लैग ये चीज़ें कर सकते हैं: डायरेक्ट्री-स्कोप (add_compile_options) पर लागू किया गया.

कंपाइलर फ़्लैग के छोटे सबसेट के लिए, उन्हें आपके Build.gradle में भी सेट किया जा सकता है cppFlags या मिलती-जुलती प्रॉपर्टी का इस्तेमाल करने वाली फ़ाइल. आपको ऐसा नहीं करना चाहिए. झंडों की थीम वाले इमोजी Gradle से CMake को पास किए जाने पर, एक खास प्राथमिकता के आधार पर व्यवहार किया जा सकेगा. मामलों में ओवरराइड का अनुरोध करने पर Android कोड बनाने के लिए ज़रूरी है. हमेशा CMake व्यवहार को पसंद करते हैं सीधे CMake में जाकर देखें. अगर आपको हर एजीपी buildType के हिसाब से कंपाइलर फ़्लैग कंट्रोल करने हैं, CMake में AGP बिल्ड टाइप के साथ काम करना देखें.

CMake में AGP बिल्ड टाइप के साथ काम करें

अगर आपको CMake व्यवहार को कस्टम Gradle buildType के हिसाब से बनाना है, तो उसका इस्तेमाल करें बिल्ड टाइप का इस्तेमाल करके, अतिरिक्त CMake फ़्लैग (कंपाइलर फ़्लैग नहीं) पास किया जा सकता है, जो CMake की बिल्ड स्क्रिप्ट पढ़ी जा सकती है. उदाहरण के लिए, अगर आपके पास "मुफ़्त" हो और "प्रीमियम" ऐसे बिल्ड वैरिएंट बनाएं जिन्हें आपके बिल्ड.gradle.kts के ज़रिए कंट्रोल किया जाता है और आपको वह डेटा CMake को:

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

इसके बाद, अपनी CMakeLists.txt में:

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

वैरिएबल का नाम तय करना आपका काम है, लेकिन पक्का करें कि टक्कर या भ्रम की स्थिति से बचने के लिए ANDROID_, APP_ या CMAKE_ प्रीफ़िक्स फ़्लैग कर दिया जाता है.

उदाहरण के लिए, Sanitizers NDK सैंपल देखें.

CMake बिल्ड कमांड को समझें

CMake बिल्ड की समस्याओं को डीबग करते समय, उसके खास बिल्ड के बारे में जानना मददगार होगा ऐसे आर्ग्युमेंट जिनका इस्तेमाल Gradle, Android के लिए क्रॉस-कंपाइलिंग करता है.

'Android Gradle प्लग इन', कोड को एक्ज़ीक्यूट करने के लिए इस्तेमाल किए जाने वाले बिल्ड आर्ग्युमेंट को सेव करता है हर एबीआई और बिल्ड टाइप के लिए CMake बिल्ड build_command.txt के साथ जोड़ें. ये फ़ाइलें यहां दी गई हैं डायरेक्ट्री:

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

नीचे दिया गया स्निपेट armeabi-v7a को टारगेट करने वाले hello-jni सैंपल की डीबग करने लायक रिलीज़ आर्किटेक्चर.

                    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

पहले से बनी लाइब्रेरी इस्तेमाल करना

अगर पहले से मौजूद जिस लाइब्रेरी को इंपोर्ट करना है उसे एएआर के तौर पर डिस्ट्रिब्यूट किया गया है, तो Studio के डिपेंडेंसी दस्तावेज़ करने के लिए इस टूल का इस्तेमाल किया जा सकता है. अगर आप AGP का इस्तेमाल नहीं कर रहे हैं, तो https://google.github.io/prefab/example-workflow.html पर जाएं, लेकिन यह इसे AGP में आसानी से माइग्रेट किया जा सकता है.

जिन लाइब्रेरी को एएआर के तौर पर डिस्ट्रिब्यूट नहीं किया गया है उनके लिए, पहले से बनी गई लाइब्रेरी का इस्तेमाल करने के बारे में निर्देश CMake की लाइब्रेरी के लिए, IMPORTED से संबंधित add_library दस् तावेज़ देखें CMake मैन्युअल में टारगेट दिए जा सकते हैं.

तीसरे पक्ष का कोड बनाया जा रहा है

CMake की सुविधा के हिस्से के तौर पर तीसरे पक्ष का कोड बनाने के कई तरीके हैं कौनसा विकल्प सबसे अच्छा काम करता है, यह आपकी स्थिति पर निर्भर करेगा. सबसे अच्छी विकल्प यह होगा कि आप ऐसा बिलकुल नहीं करेंगे. इसके बजाय, AAR बनाएं लाइब्रेरी में सेव किया जा सकता है और उसका इस्तेमाल अपने ऐप्लिकेशन में किया जा सकता है. आपको ऐसा करने की ज़रूरत नहीं है पब्लिश कर दें. यह आपके Gradle प्रोजेक्ट के लिए इंटरनल हो सकता है.

अगर यह विकल्प मौजूद नहीं है, तो:

  • वेंडर (यानी कॉपी करना) तीसरे पक्ष के सोर्स को अपने डेटा स्टोर करने की जगह में रखना और उसका इस्तेमाल करना add_subdirectory पर जाएं. यह तरीका सिर्फ़ तब काम करता है, जब दूसरी लाइब्रेरी CMake के साथ बनाया गया है.
  • ExternalProject तय करें.
  • लाइब्रेरी को अपने प्रोजेक्ट से अलग बनाएं और फ़ॉलो करें पहले से बनी लाइब्रेरी के तौर पर इंपोर्ट करने के लिए, पहले से बनी लाइब्रेरी का इस्तेमाल करें.

CMake में YASM सहायता

एनडीके, असेंबली कोड को बनाने के लिए CMake की सुविधा देता है YASM, x86 और x86-64 पर चलेगा डिज़ाइन किया गया है. YASM, x86 और x86-64 के लिए एक ओपन-सोर्स असेंबलर है में से एक है.

CMake की मदद से असेंबली कोड बनाने के लिए, अपने प्रोजेक्ट के प्रोजेक्ट में ये बदलाव करें CMakeLists.txt:

  1. ASM_NASM पर सेट मान के साथ enable_language को कॉल करें.
  2. इस बात पर निर्भर करते हुए कि आप शेयर की गई लाइब्रेरी बना रहे हैं या कोई एक्ज़ीक्यूटेबल बाइनरी है, तो add_library या add_executable पर कॉल करें. तय सीमा में आर्ग्युमेंट, सोर्स फ़ाइलों की सूची में पास करें, जिसमें .asm फ़ाइलें शामिल हों YASM में असेंबली प्रोग्राम और इससे जुड़े C के लिए .c फ़ाइलों के लिए लाइब्रेरी या फ़ंक्शन शामिल हैं.

नीचे दिया गया स्निपेट दिखाता है कि आप अपने CMakeLists.txt को कैसे कॉन्फ़िगर कर सकते हैं शेयर की गई लाइब्रेरी के तौर पर YASM प्रोग्राम बनाना होगा.

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 प्रोग्राम को एक्ज़ीक्यूटेबल के तौर पर बनाने का तरीका जानने के लिए, yasm देखें टेस्ट करना होगा.

समस्याओं की शिकायत करना

अगर आपको एनडीके या इसकी CMake टूलचेन फ़ाइल में कोई समस्या आती है, तो उसकी शिकायत करें GitHub पर android-ndk/ndk समस्या को ट्रैक करने वाले टूल के ज़रिए. Gradle या 'Android Gradle प्लग इन' से जुड़ी समस्याएं, इसके बजाय Studio की गड़बड़ी की शिकायत करें.