সিমেক

অ্যান্ড্রয়েড এনডিকে আপনার অ্যাপ্লিকেশনের জন্য সি এবং সি++ কোড কম্পাইল করতে সিমেক (CMake) ব্যবহার সমর্থন করে। এই পৃষ্ঠায় আলোচনা করা হয়েছে কীভাবে অ্যান্ড্রয়েড গ্রেডল প্লাগইনের ExternalNativeBuild এর মাধ্যমে অথবা সরাসরি সিমেক কল করে এনডিকে-এর সাথে সিমেক ব্যবহার করা যায়।

CMake টুলচেইন ফাইল

NDK একটি টুলচেইন ফাইলের মাধ্যমে CMake সমর্থন করে। টুলচেইন ফাইল হলো এমন CMake ফাইল যা ক্রস-কম্পাইলিংয়ের জন্য টুলচেইনের আচরণকে কাস্টমাইজ করে। NDK-এর জন্য ব্যবহৃত টুলচেইন ফাইলটি NDK-এর মধ্যেই <NDK>/build/cmake/android.toolchain.cmake এই ঠিকানায় অবস্থিত।

Build parameters such as ABI, minSdkVersion , etc. are given on the command line when invoking cmake . For a list of supported arguments, see the Toolchain arguments section.

'নতুন' টুলচেইন ফাইল

পূর্ববর্তী এনডিকে-গুলোতে টুলচেইন ফাইলের একটি নতুন বাস্তবায়ন নিয়ে পরীক্ষা-নিরীক্ষা করা হয়েছিল, যার উদ্দেশ্য ছিল এনডিকে-র নিজস্ব টুলচেইন ফাইল এবং বিল্ট-ইন সিমেক (CMake) সাপোর্ট ব্যবহারের মধ্যকার আচরণগত পার্থক্য কমিয়ে আনা। এর জন্য উল্লেখযোগ্য পরিমাণ কাজের প্রয়োজন হয়েছিল (যা এখনও সম্পন্ন হয়নি), কিন্তু এটি আসলে আচরণের কোনো উন্নতি ঘটায়নি, তাই আমরা আর এই বিষয়টি নিয়ে এগোচ্ছি না।

"নতুন" টুলচেইন ফাইলটিতে "পুরানো" টুলচেইন ফাইলের তুলনায় আচরণগত অবনতি ঘটেছে। ডিফল্ট আচরণটিই প্রস্তাবিত কর্মপ্রবাহ। আপনি যদি -DANDROID_USE_LEGACY_TOOLCHAIN_FILE=OFF ব্যবহার করে থাকেন, তবে আমরা আপনার বিল্ড থেকে সেই ফ্ল্যাগটি সরিয়ে ফেলার পরামর্শ দিচ্ছি। নতুন টুলচেইন ফাইলটি কখনোই পুরানো টুলচেইন ফাইলের সাথে সমতা অর্জন করতে পারেনি, তাই এর আচরণগত অবনতি ঘটার সম্ভাবনা রয়েছে।

যদিও আমরা নতুন টুলচেইন ফাইলটি ব্যবহার না করার পরামর্শ দিই, বর্তমানে এটিকে NDK থেকে সরিয়ে ফেলার কোনো পরিকল্পনা নেই। এমনটা করলে সেইসব বিল্ড ভেঙে যাবে যেগুলো নতুন এবং পুরোনো টুলচেইন ফাইলের আচরণের পার্থক্যের উপর নির্ভর করে। দুর্ভাগ্যবশত, অপশনটির নাম পরিবর্তন করে এটা স্পষ্ট করে দিলেও যে "লেগ্যাসি" সংস্করণটিই আসলে ব্যবহার করার পরামর্শ দেওয়া হচ্ছে, তাতেও সেই অপশনটির ব্যবহারকারীরা সমস্যায় পড়বেন। আপনি যদি স্বাচ্ছন্দ্যে নতুন টুলচেইন ফাইলটি ব্যবহার করে থাকেন, তবে আপনার মাইগ্রেট করার প্রয়োজন নেই, কিন্তু জেনে রাখুন যে নতুন টুলচেইন ফাইলের আচরণ নিয়ে করা কোনো বাগ সম্ভবত ঠিক করা হবে না, এবং তার পরিবর্তে আপনাকে মাইগ্রেট করতে হবে।

ব্যবহার

গ্রেডল

Use of the CMake toolchain file is automatic when using externalNativeBuild . See Android Studio's Add C and C++ code to your project guide for more information.

কমান্ড লাইন

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-কে Neon সাপোর্ট ছাড়া বিল্ড করতে বাধ্য করার জন্য, -DANDROID_ARM_NEON=FALSE পাস করুন।

ANDROID_ABI

লক্ষ্য ABI। সমর্থিত ABI-গুলো সম্পর্কে তথ্যের জন্য, Android ABIs দেখুন।

গ্রেডল

Gradle এই আর্গুমেন্টটি স্বয়ংক্রিয়ভাবে প্রদান করে। আপনার build.gradle ফাইলে এই আর্গুমেন্টটি স্পষ্টভাবে সেট করবেন না। Gradle কোন ABI-গুলোকে টার্গেট করবে তা নিয়ন্ত্রণ করতে, Android ABIs- এ বর্ণিত abiFilters ব্যবহার করুন।

কমান্ড লাইন

CMake প্রতি বিল্ডে একটিমাত্র টার্গেটের জন্য বিল্ড তৈরি করে। একাধিক অ্যান্ড্রয়েড ABI টার্গেট করতে হলে, আপনাকে প্রতিটি ABI-এর জন্য একবার করে বিল্ড করতে হবে। বিল্ডগুলোর মধ্যে সংঘর্ষ এড়ানোর জন্য প্রতিটি ABI-এর জন্য আলাদা বিল্ড ডিরেক্টরি ব্যবহার করার পরামর্শ দেওয়া হয়।

মূল্য নোট
armeabi-v7a
armeabi-v7a with NEON armeabi-v7a এর অনুরূপ।
arm64-v8a
x86
x86_64

ANDROID_ARM_MODE

armeabi-v7a-এর জন্য arm নাকি thumb নির্দেশাবলী তৈরি করা হবে তা নির্দিষ্ট করে। অন্যান্য ABI-এর ক্ষেত্রে এর কোনো প্রভাব নেই। আরও তথ্যের জন্য, Android ABIs ডকুমেন্টেশন দেখুন।

মূল্য নোট
বাহু
বুড়ো আঙুল ডিফল্ট আচরণ।

ANDROID_NATIVE_API_LEVEL

ANDROID_PLATFORM- এর বিকল্প নাম।

ANDROID_PLATFORM

অ্যাপ্লিকেশন বা লাইব্রেরি দ্বারা সমর্থিত সর্বনিম্ন API স্তর নির্দিষ্ট করে। এই মানটি অ্যাপ্লিকেশনটির minSdkVersion এর সাথে সঙ্গতিপূর্ণ।

গ্রেডল

অ্যান্ড্রয়েড গ্রেডল প্লাগইন ব্যবহার করার সময়, এই মানটি স্বয়ংক্রিয়ভাবে অ্যাপ্লিকেশনটির minSdkVersion সাথে মিলে যায় এবং এটি ম্যানুয়ালি সেট করা উচিত নয়।

কমান্ড লাইন

When invoking CMake directly, this value defaults to the lowest API level supported by the NDK in use. For example, with NDK r20 this value defaults to API level 16.

Multiple formats are accepted for this parameter:

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

$API_LETTER ফরম্যাটটি আপনাকে সেই রিলিজের সাথে যুক্ত নম্বরটি নির্ধারণ করার প্রয়োজন ছাড়াই android-N নির্দিষ্ট করার সুযোগ দেয়। উল্লেখ্য যে, কিছু রিলিজে লেটার বৃদ্ধি ছাড়াই API বৃদ্ধি পেয়েছে। এই API-গুলো -MR1 সাফিক্স যুক্ত করে নির্দিষ্ট করা যেতে পারে। উদাহরণস্বরূপ, API লেভেল 25 হলো android-N-MR1

ANDROID_STL

Specifies which STL to use for this application. For more information, see C++ library support . By default, c++_static will be used.

মূল্য নোট
সি++_শেয়ার্ড libc++ এর শেয়ার্ড লাইব্রেরি সংস্করণ।
সি++_স্ট্যাটিক libc++ এর স্ট্যাটিক লাইব্রেরি সংস্করণ।
কোনোটিই না C++ স্ট্যান্ডার্ড লাইব্রেরির কোনো সমর্থন নেই।
সিস্টেম সিস্টেম STL

কম্পাইলার ফ্ল্যাগ পরিচালনা করুন

আপনার বিল্ডের জন্য যদি কম্পাইলার বা লিঙ্কারে নির্দিষ্ট ফ্ল্যাগ পাস করার প্রয়োজন হয়, তাহলে set_target_compile_options এবং এর সাথে সম্পর্কিত অপশনগুলোর জন্য CMake ডকুমেন্টেশন দেখুন। সেই পৃষ্ঠার একেবারে নিচের "see also" অংশে কিছু সহায়ক সূত্র রয়েছে।

সাধারণত, কম্পাইলার ফ্ল্যাগগুলোকে সবচেয়ে সংকীর্ণ পরিসরে প্রয়োগ করাই সর্বোত্তম পন্থা। যে ফ্ল্যাগগুলো আপনি আপনার সমস্ত টার্গেটে প্রয়োগ করতে চান (যেমন -Werror ), সেগুলো প্রতি-মডিউলে পুনরাবৃত্তি করা অসুবিধাজনক, কিন্তু তবুও সেগুলো কদাচিৎ গ্লোবালি ( CMAKE_CXX_FLAGS ) প্রয়োগ করা উচিত, কারণ সেগুলো আপনার প্রোজেক্টের থার্ড-পার্টি ডিপেন্ডেন্সিগুলোর উপর অনাকাঙ্ক্ষিত প্রভাব ফেলতে পারে। এই ধরনের ক্ষেত্রে, ফ্ল্যাগগুলো ডিরেক্টরি-স্কোপে ( add_compile_options ) প্রয়োগ করা যেতে পারে।

কম্পাইলার ফ্ল্যাগের একটি ক্ষুদ্র অংশের জন্য, সেগুলি আপনার build.gradle ফাইলে cppFlags বা অনুরূপ প্রোপার্টি ব্যবহার করেও সেট করা যেতে পারে। আপনার এটি করা উচিত নয়। Gradle থেকে CMake-এ পাঠানো ফ্ল্যাগগুলির অগ্রাধিকারের আচরণ আশ্চর্যজনক হতে পারে, কিছু ক্ষেত্রে এটি ইমপ্লিমেন্টেশন দ্বারা পরোক্ষভাবে পাঠানো ফ্ল্যাগগুলিকে ওভাররাইড করে দেয়, যা অ্যান্ড্রয়েড কোড বিল্ড করার জন্য প্রয়োজনীয়। সর্বদা CMake-এর আচরণ সরাসরি CMake-এর মধ্যেই পরিচালনা করাকে অগ্রাধিকার দিন। যদি আপনার প্রতি AGP buildType কম্পাইলার ফ্ল্যাগ নিয়ন্ত্রণ করার প্রয়োজন হয়, তাহলে Work with AGP build types in CMake দেখুন।

CMake-এ AGP বিল্ড টাইপগুলির সাথে কাজ করুন

যদি আপনাকে একটি কাস্টম গ্রেডল buildType সাথে CMake-এর আচরণকে মানিয়ে নিতে হয়, তাহলে সেই বিল্ড টাইপটি ব্যবহার করে একটি অতিরিক্ত CMake ফ্ল্যাগ (কম্পাইলার ফ্ল্যাগ নয়) পাস করুন, যা আপনার CMake বিল্ড স্ক্রিপ্টগুলো পড়তে পারে। উদাহরণস্বরূপ, যদি আপনার "free" এবং "premium" বিল্ড ভ্যারিয়েন্ট থাকে যা আপনার 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()

The name of the variable is up to you, but make sure you avoid anything with an ANDROID_ , APP_ , or CMAKE_ prefix to avoid collision or confusion with existing flags.

একটি উদাহরণের জন্য স্যানিটাইজার এনডিকে নমুনাটি দেখুন।

CMake বিল্ড কমান্ড বুঝুন

When debugging CMake build issues, it's helpful to know the specific build arguments that Gradle uses when cross-compiling for Android.

অ্যান্ড্রয়েড গ্র্যাডল প্লাগইন প্রতিটি 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 হিসেবে ডিস্ট্রিবিউট করা হয়ে থাকে, তবে সেগুলো ইম্পোর্ট ও ব্যবহার করার জন্য Studio-র ডিপেন্ডেন্সি ডক্স অনুসরণ করুন। আপনি যদি AGP ব্যবহার না করেন, তবে https://google.github.io/prefab/example-workflow.html অনুসরণ করতে পারেন, কিন্তু AGP-তে মাইগ্রেট করা সম্ভবত অনেক বেশি সহজ হবে।

For libraries that are not distributed as an AAR, instructions on using prebuilt libraries with CMake, see the add_library documentation regarding IMPORTED targets in the CMake manual .

তৃতীয় পক্ষের কোড তৈরি করা

আপনার CMake প্রোজেক্টের অংশ হিসেবে থার্ড-পার্টি কোড বিল্ড করার কয়েকটি উপায় আছে, এবং কোন বিকল্পটি সবচেয়ে ভালো কাজ করবে তা আপনার পরিস্থিতির উপর নির্ভর করবে। প্রায়শই সেরা বিকল্পটি হবে এটি একেবারেই না করা। এর পরিবর্তে, লাইব্রেরিটির জন্য একটি AAR বিল্ড করুন এবং আপনার অ্যাপ্লিকেশনে সেটি ব্যবহার করুন। আপনার সেই AAR-টি পাবলিশ করার কোনো প্রয়োজন নেই। এটি আপনার Gradle প্রোজেক্টের মধ্যেই থাকতে পারে।

যদি সেটা সম্ভব না হয়:

  • Vendor (ie copy) the third-party source into your repository and use add_subdirectory to build it. This only works if the other library is also built with CMake.
  • একটি ExternalProject সংজ্ঞায়িত করুন।
  • Build the library separately from your project and follow Use prebuilt libraries to import it as a prebuilt.

CMake-এ YASM সমর্থন

NDK, YASM- এ লেখা অ্যাসেম্বলি কোডকে x86 এবং x86-64 আর্কিটেকচারে চালানোর জন্য CMake সাপোর্ট প্রদান করে। YASM হলো NASM অ্যাসেম্বলারের উপর ভিত্তি করে তৈরি x86 এবং x86-64 আর্কিটেকচারের জন্য একটি ওপেন-সোর্স অ্যাসেম্বলার।

To build assembly code with CMake, make the following changes in your project's CMakeLists.txt :

  1. Call enable_language with the value set to ASM_NASM .
  2. আপনি একটি শেয়ার্ড লাইব্রেরি নাকি একটি এক্সিকিউটেবল বাইনারি তৈরি করছেন, তার উপর নির্ভর করে add_library বা add_executable কল করুন। আর্গুমেন্টগুলিতে, YASM-এ লেখা অ্যাসেম্বলি প্রোগ্রামের জন্য .asm ফাইল এবং সংশ্লিষ্ট C লাইব্রেরি বা ফাংশনগুলির জন্য .c ফাইল সম্বলিত সোর্স ফাইলগুলির একটি তালিকা পাস করুন।

The following snippet shows how you might configure your CMakeLists.txt to build a YASM program as a shared library.

cmake_minimum_required(VERSION 3.6.0)

enable_language(ASM_NASM)

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

For an example of how to build a YASM program as an executable, see the yasm test in the NDK git repository.

সমস্যা রিপোর্ট করুন

NDK বা এর CMake টুলচেইন ফাইল নিয়ে কোনো সমস্যা হলে, GitHub-এর android-ndk/ndk ইস্যু ট্র্যাকারে তা জানান। Gradle বা Android Gradle Plugin-এর সমস্যার ক্ষেত্রে, এর পরিবর্তে Studio-তে একটি বাগ রিপোর্ট করুন