Android NDK আপনার অ্যাপ্লিকেশনের জন্য C এবং C++ কোড কম্পাইল করতে CMake ব্যবহার করে সমর্থন করে। এই পৃষ্ঠাটি Android Gradle Plugin এর ExternalNativeBuild
এর মাধ্যমে NDK-এর সাথে CMake কীভাবে ব্যবহার করতে হয় বা সরাসরি CMake ব্যবহার করার সময় আলোচনা করে।
CMake টুলচেন ফাইল
NDK একটি টুলচেইন ফাইলের মাধ্যমে CMake সমর্থন করে। টুলচেন ফাইলগুলি হল CMake ফাইল যা ক্রস-কম্পাইলিংয়ের জন্য টুলচেনের আচরণকে কাস্টমাইজ করে। NDK-এর জন্য ব্যবহৃত টুলচেন ফাইলটি NDK-এ <NDK>/build/cmake/android.toolchain.cmake
এ অবস্থিত।
বিল্ড প্যারামিটার যেমন ABI, minSdkVersion
, ইত্যাদি কমান্ড লাইনে দেওয়া হয় cmake
চালু করার সময়। সমর্থিত আর্গুমেন্টের তালিকার জন্য, টুলচেইন আর্গুমেন্টস বিভাগটি দেখুন।
"নতুন" টুলচেন ফাইল
এর আগে NDKs টুলচেন ফাইলের একটি নতুন বাস্তবায়নের সাথে পরীক্ষা করেছিল যা NDK-এর টুলচেন ফাইল ব্যবহার করা এবং অন্তর্নির্মিত CMake সমর্থন ব্যবহার করার মধ্যে আচরণের পার্থক্য কমিয়ে দেবে। এটির জন্য একটি উল্লেখযোগ্য পরিমাণ কাজের প্রয়োজন (যা সম্পূর্ণ হয়নি), কিন্তু আসলে আচরণের উন্নতি হয়নি, তাই আমরা আর এটি অনুসরণ করছি না।
"নতুন" টুলচেন ফাইলে "লিগেসি" টুলচেন ফাইলের তুলনায় আচরণের রিগ্রেশন আছে। ডিফল্ট আচরণ হল প্রস্তাবিত কর্মপ্রবাহ। আপনি যদি -DANDROID_USE_LEGACY_TOOLCHAIN_FILE=OFF
ব্যবহার করেন, আমরা আপনার বিল্ড থেকে সেই পতাকাটি সরানোর পরামর্শ দিই। নতুন টুলচেন ফাইলটি কখনই লিগ্যাসি টুলচেন ফাইলের সাথে সমতা পায়নি, তাই সম্ভবত আচরণের রিগ্রেশন রয়েছে।
যদিও আমরা নতুন টুলচেন ফাইল ব্যবহার করার বিরুদ্ধে সুপারিশ করি, বর্তমানে NDK থেকে এটি সরানোর কোনো পরিকল্পনা নেই। এটি করা বিল্ডগুলিকে ভেঙে ফেলবে যা নতুন এবং লিগ্যাসি টুলচেইন ফাইলগুলির মধ্যে আচরণের পার্থক্যের উপর নির্ভর করে এবং দুর্ভাগ্যবশত বিকল্পটির নাম পরিবর্তন করে এটি পরিষ্কার করে যে "উত্তরাধিকার" আসলে প্রস্তাবিত সেই বিকল্পের ব্যবহারকারীদেরও ভেঙে দেবে। আপনি যদি আনন্দের সাথে নতুন টুলচেন ফাইলটি ব্যবহার করেন তবে আপনাকে মাইগ্রেট করার দরকার নেই, তবে জেনে রাখুন যে নতুন টুলচেন ফাইল আচরণের বিরুদ্ধে দায়ের করা কোনো বাগ সম্ভবত ঠিক করা হবে না এবং পরিবর্তে আপনাকে স্থানান্তর করতে হবে।
ব্যবহার
গ্রেডল
externalNativeBuild
ব্যবহার করার সময় CMake টুলচেন ফাইলের ব্যবহার স্বয়ংক্রিয়। আরও তথ্যের জন্য আপনার প্রজেক্ট গাইডে অ্যান্ড্রয়েড স্টুডিওর সি এবং সি++ কোড যুক্ত করুন দেখুন।
কমান্ড লাইন
Gradle-এর বাইরে CMake দিয়ে তৈরি করার সময়, টুলচেন ফাইল নিজেই এবং এর আর্গুমেন্টগুলি অবশ্যই CMake-এ পাস করতে হবে। যেমন:
$ cmake \
-DCMAKE_TOOLCHAIN_FILE=$NDK/build/cmake/android.toolchain.cmake \
-DANDROID_ABI=$ABI \
-DANDROID_PLATFORM=android-$MINSDKVERSION \
$OTHER_ARGS
টুলচেইন আর্গুমেন্ট
নিম্নলিখিত আর্গুমেন্ট CMake টুলচেইন ফাইলে পাস করা যেতে পারে। যদি Gradle দিয়ে তৈরি করা হয়, তাহলে ExternalNativeBuild ডক্সে বর্ণিত android.defaultConfig.externalNativeBuild.cmake.arguments
এ আর্গুমেন্ট যোগ করুন। যদি কমান্ড লাইন থেকে বিল্ডিং করা হয়, -D
এর সাথে CMake-এ আর্গুমেন্ট পাস করুন। উদাহরণ স্বরূপ, armeabi-v7a-কে নিয়ন সাপোর্ট দিয়ে তৈরি না করতে বাধ্য করতে, পাস করুন -DANDROID_ARM_NEON=FALSE
।
ANDROID_ABI
লক্ষ্য ABI. সমর্থিত ABI সম্পর্কে তথ্যের জন্য, Android ABIs দেখুন।
গ্রেডল
Gradle স্বয়ংক্রিয়ভাবে এই যুক্তি প্রদান করে। আপনার build.gradle
ফাইলে এই আর্গুমেন্টটি স্পষ্টভাবে সেট করবেন না। ABIs Gradle কি লক্ষ্য করে তা নিয়ন্ত্রণ করতে, Android ABIs- এ বর্ণিত abiFilters
ব্যবহার করুন।
কমান্ড লাইন
CMake বিল্ড প্রতি একটি একক লক্ষ্যের জন্য তৈরি করে। একাধিক Android ABI টার্গেট করতে, আপনাকে ABI প্রতি একবার তৈরি করতে হবে। বিল্ডগুলির মধ্যে সংঘর্ষ এড়াতে প্রতিটি ABI-এর জন্য বিভিন্ন বিল্ড ডিরেক্টরি ব্যবহার করার পরামর্শ দেওয়া হয়।
মান | নোট |
---|---|
armeabi-v7a | |
armeabi-v7a with NEON | armeabi-v7a মতই। |
arm64-v8a | |
x86 | |
x86_64 |
ANDROID_ARM_MODE
armeabi-v7a-এর জন্য বাহু বা থাম্ব নির্দেশনা তৈরি করতে হবে কিনা তা নির্দিষ্ট করে। অন্যান্য ABI-এর জন্য কোন প্রভাব নেই। আরও তথ্যের জন্য, Android ABIs ডকুমেন্টেশন দেখুন।
মান | নোট |
---|---|
বাহু | |
থাম্ব | ডিফল্ট আচরণ। |
ANDROID_NATIVE_API_LEVEL
ANDROID_PLATFORM এর উপনাম।
ANDROID_PLATFORM
অ্যাপ্লিকেশন বা লাইব্রেরি দ্বারা সমর্থিত ন্যূনতম API স্তর নির্দিষ্ট করে৷ এই মানটি অ্যাপ্লিকেশনের minSdkVersion
এর সাথে মিলে যায়।
গ্রেডল
অ্যান্ড্রয়েড গ্রেডল প্লাগইন ব্যবহার করার সময়, এই মানটি স্বয়ংক্রিয়ভাবে অ্যাপ্লিকেশনটির minSdkVersion
সাথে মেলে এবং ম্যানুয়ালি সেট করা উচিত নয়৷
কমান্ড লাইন
CMake সরাসরি আহ্বান করার সময়, এই মানটি ব্যবহার করা NDK দ্বারা সমর্থিত সর্বনিম্ন API স্তরে ডিফল্ট হয়। উদাহরণস্বরূপ, NDK r20 এর সাথে এই মানটি API স্তর 16-এ ডিফল্ট হয়।
এই প্যারামিটারের জন্য একাধিক বিন্যাস গ্রহণ করা হয়:
-
android-$API_LEVEL
-
$API_LEVEL
-
android-$API_LETTER
$API_LETTER
ফর্ম্যাট আপনাকে সেই রিলিজের সাথে যুক্ত নম্বর নির্ধারণ করার প্রয়োজন ছাড়াই android-N
নির্দিষ্ট করতে দেয়। নোট করুন যে কিছু রিলিজ একটি অক্ষর বৃদ্ধি ছাড়া একটি API বৃদ্ধি পেয়েছে। এই APIগুলিকে -MR1
প্রত্যয় যুক্ত করে নির্দিষ্ট করা যেতে পারে। উদাহরণস্বরূপ, API স্তর 25 হল android-N-MR1
।
ANDROID_STL
এই অ্যাপ্লিকেশনের জন্য কোন STL ব্যবহার করতে হবে তা নির্দিষ্ট করে। আরও তথ্যের জন্য, C++ লাইব্রেরি সমর্থন দেখুন। ডিফল্টরূপে, c++_static
ব্যবহার করা হবে।
মান | নোট |
---|---|
c++_শেয়ার করা হয়েছে | libc++ এর ভাগ করা লাইব্রেরি বৈকল্পিক। |
c++_static | libc++ এর স্ট্যাটিক লাইব্রেরি রূপ। |
কোনটি | কোন C++ স্ট্যান্ডার্ড লাইব্রেরি সমর্থন নেই। |
সিস্টেম | সিস্টেম STL |
কম্পাইলার পতাকা পরিচালনা করুন
আপনি যদি আপনার বিল্ডের জন্য কম্পাইলার বা লিঙ্কারে নির্দিষ্ট ফ্ল্যাগ পাঠাতে চান, তাহলে set_target_compile_options এবং বিকল্পগুলির সম্পর্কিত পরিবারের জন্য CMake ডকুমেন্টেশন দেখুন। সেই পৃষ্ঠার নীচে "এছাড়াও দেখুন" বিভাগে কিছু সহায়ক সূত্র রয়েছে৷
সাধারণভাবে, সর্বোত্তম অনুশীলন হল সংকীর্ণ উপলব্ধ সুযোগ হিসাবে কম্পাইলার ফ্ল্যাগগুলি প্রয়োগ করা। যে পতাকাগুলি আপনি আপনার সমস্ত লক্ষ্যগুলিতে প্রয়োগ করতে চান (যেমন -Werror
) প্রতি-মডিউল পুনরাবৃত্তি করতে অসুবিধাজনক, তবে এখনও বিশ্বব্যাপী খুব কমই প্রয়োগ করা উচিত ( CMAKE_CXX_FLAGS
), কারণ সেগুলি আপনার প্রকল্পে তৃতীয় পক্ষের নির্ভরতার উপর অনাকাঙ্ক্ষিত প্রভাব ফেলতে পারে . এই ধরনের ক্ষেত্রে, পতাকাগুলি ডিরেক্টরি-স্কোপে প্রয়োগ করা যেতে পারে ( add_compile_options
)।
কম্পাইলার ফ্ল্যাগগুলির একটি সংকীর্ণ উপসেটের জন্য, সেগুলি cppFlags
বা অনুরূপ বৈশিষ্ট্যগুলি ব্যবহার করে আপনার build.gradle ফাইলে সেট করা যেতে পারে। আপনার এটা করা উচিত নয়। Gradle থেকে CMake-এ পাস করা ফ্ল্যাগগুলিতে আশ্চর্যজনক অগ্রাধিকারের আচরণ থাকবে, কিছু ক্ষেত্রে অ্যান্ড্রয়েড কোড তৈরির জন্য প্রয়োজনীয় বাস্তবায়নের মাধ্যমে ফ্ল্যাগগুলিকে ওভাররাইড করা হয়। সর্বদা সরাসরি CMake-এ CMake আচরণ পরিচালনা করতে পছন্দ করুন। আপনি যদি প্রতি এজিপি buildType
কম্পাইলার ফ্ল্যাগ নিয়ন্ত্রণ করতে চান, দেখুন CMake-এ AGP বিল্ড টাইপের সাথে কাজ করুন ।
CMake এ AGP বিল্ড টাইপের সাথে কাজ করুন
আপনার যদি CMake আচরণকে একটি কাস্টম গ্রেডল buildType
এর সাথে মানানসই করতে হয়, তাহলে আপনার CMake বিল্ড স্ক্রিপ্টগুলি পড়তে পারে এমন একটি অতিরিক্ত CMake পতাকা (কোনও কম্পাইলার পতাকা নয়) পাস করতে সেই বিল্ড টাইপটি ব্যবহার করুন। উদাহরণস্বরূপ, যদি আপনার "ফ্রি" এবং "প্রিমিয়াম" বিল্ড ভেরিয়েন্ট থাকে যা আপনার build.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_
উপসর্গের সাথে কিছু এড়ান।
একটি উদাহরণের জন্য স্যানিটাইজার NDK নমুনা দেখুন।
CMake বিল্ড কমান্ড বুঝুন
CMake বিল্ড সমস্যাগুলি ডিবাগ করার সময়, Android এর জন্য ক্রস-কম্পাইল করার সময় Gradle যে নির্দিষ্ট বিল্ড আর্গুমেন্টগুলি ব্যবহার করে তা জানার জন্য এটি সহায়ক।
অ্যান্ড্রয়েড গ্রেডল প্লাগইন বিল্ড আর্গুমেন্টগুলি সংরক্ষণ করে যা এটি প্রতিটি ABI-এর জন্য একটি CMake বিল্ড কার্যকর করার জন্য ব্যবহার করে এবং build_command.txt
এ বিল্ড টাইপ জোড়া। এই ফাইলগুলি নিম্নলিখিত ডিরেক্টরিতে পাওয়া যায়:
<project-root>/<module-root>/.cxx/cmake/<build-type>/<ABI>/
নিচের স্নিপেটটি armeabi-v7a
আর্কিটেকচারকে লক্ষ্য করে hello-jni
নমুনার একটি ডিবাগযোগ্য রিলিজ তৈরি করতে CMake আর্গুমেন্টের একটি উদাহরণ দেখায়।
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
প্রি-বিল্ট লাইব্রেরি ব্যবহার করুন
যদি পূর্বনির্মাণ করা লাইব্রেরিটি আপনাকে আমদানি করতে হবে তা AAR হিসাবে বিতরণ করা হয়, সেগুলি আমদানি করতে এবং ব্যবহার করতে স্টুডিওর নির্ভরতা ডক্স অনুসরণ করুন৷ আপনি যদি AGP ব্যবহার না করেন তাহলে আপনি https://google.github.io/prefab/example-workflow.html অনুসরণ করতে পারেন, তবে সম্ভবত AGP-এ স্থানান্তর করা অনেক সহজ।
লাইব্রেরিগুলির জন্য যেগুলি AAR হিসাবে বিতরণ করা হয় না, CMake-এর সাথে প্রি-বিল্ট লাইব্রেরিগুলি ব্যবহার করার নির্দেশাবলী, CMake ম্যানুয়াল -এ IMPORTED
লক্ষ্য সংক্রান্ত add_library
ডকুমেন্টেশন দেখুন।
বিল্ডিং তৃতীয় পক্ষের কোড
আপনার CMake প্রকল্পের অংশ হিসাবে তৃতীয়-পক্ষের কোড তৈরি করার কয়েকটি উপায় রয়েছে এবং কোন বিকল্পটি সবচেয়ে ভাল কাজ করে তা আপনার পরিস্থিতির উপর নির্ভর করবে। সর্বোত্তম বিকল্পটি প্রায়শই এটি না করাই হবে। পরিবর্তে, লাইব্রেরির জন্য একটি AAR তৈরি করুন এবং আপনার অ্যাপ্লিকেশনে এটি ব্যবহার করুন। আপনার অগত্যা সেই AAR প্রকাশ করার দরকার নেই। এটি আপনার গ্রেডল প্রকল্পের অভ্যন্তরীণ হতে পারে।
যদি এটি একটি বিকল্প না হয়:
- বিক্রেতা (অর্থাৎ অনুলিপি) আপনার সংগ্রহস্থলে তৃতীয় পক্ষের উত্স এবং এটি তৈরি করতে add_subdirectory ব্যবহার করুন। এটি শুধুমাত্র তখনই কাজ করে যদি অন্য লাইব্রেরিটিও CMake দিয়ে তৈরি করা হয়।
- একটি বহিরাগত প্রকল্প সংজ্ঞায়িত করুন।
- আপনার প্রকল্প থেকে আলাদাভাবে লাইব্রেরি তৈরি করুন এবং এটিকে পূর্বনির্মাণ হিসাবে আমদানি করতে পূর্বনির্মাণ লাইব্রেরি ব্যবহার করুন অনুসরণ করুন।
CMake এ YASM সমর্থন
NDK x86 এবং x86-64 আর্কিটেকচারে চালানোর জন্য YASM- এ লিখিত সমাবেশ কোড নির্মাণের জন্য CMake সমর্থন প্রদান করে। YASM হল NASM অ্যাসেম্বলারের উপর ভিত্তি করে x86 এবং x86-64 আর্কিটেকচারের জন্য একটি ওপেন-সোর্স অ্যাসেম্বলার।
CMake এর সাথে সমাবেশ কোড তৈরি করতে, আপনার প্রকল্পের CMakeLists.txt
এ নিম্নলিখিত পরিবর্তনগুলি করুন:
-
ASM_NASM
তে সেট মান সহenable_language
কল করুন। - আপনি একটি শেয়ার্ড লাইব্রেরি বা এক্সিকিউটেবল বাইনারি তৈরি করছেন তার উপর নির্ভর করে,
add_library
বাadd_executable
কল করুন। আর্গুমেন্টে, YASM-এ এসেম্বলি প্রোগ্রামের জন্য.asm
ফাইল এবং সংশ্লিষ্ট C লাইব্রেরি বা ফাংশনের জন্য.c
ফাইল সমন্বিত সোর্স ফাইলগুলির একটি তালিকা পাস করুন।
নিচের স্নিপেটটি দেখায় কিভাবে আপনি একটি শেয়ার্ড লাইব্রেরি হিসাবে একটি YASM প্রোগ্রাম তৈরি করতে আপনার CMakeLists.txt
কনফিগার করতে পারেন।
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 প্রোগ্রাম কীভাবে তৈরি করা যায় তার উদাহরণের জন্য, NDK গিট সংগ্রহস্থলে ইয়াসম পরীক্ষা দেখুন।
সমস্যা রিপোর্ট করুন
আপনি যদি NDK বা এর CMake টুলচেন ফাইলের সাথে কোনো সমস্যায় পড়েন, GitHub-এ android-ndk/ndk ইস্যু ট্র্যাকারের মাধ্যমে রিপোর্ট করুন। Gradle বা Android Gradle Plugin সমস্যাগুলির জন্য, পরিবর্তে একটি স্টুডিও বাগ রিপোর্ট করুন ।