صناعة

يدعم NDK في Android استخدام CMake لتجميع رموز C وC++ لتطبيقك. تناقش هذه الصفحة كيفية استخدام CMake with NDK عبر مكوّن ExternalNativeBuild الإضافي لنظام Gradle المتوافق مع Android أو عند استدعاء CMake مباشرةً.

ملف سلسلة أدوات CMake

يدعم NDK أداة CMake عبر ملف toolchain. ملفات سلسلة الأدوات هي ملفات CMake التي تخصص سلوك سلسلة الأدوات للتجميع المتبادل. يوجد ملف سلسلة الأدوات المستخدم لـ NDK في NDK على <NDK>/build/cmake/android.toolchain.cmake.

يتم عرض معلمات الإصدار، مثل ABI وminSdkVersion وغيرها في سطر الأوامر عند استدعاء cmake. للحصول على قائمة بالوسيطات المتوافقة، راجِع القسم وسيطات سلسلة الأدوات.

الاستخدام

مبرّد

يتم استخدام ملف CMake toolchain تلقائيًا عند استخدام externalNativeBuild. للحصول على مزيد من المعلومات، يمكنك الاطّلاع على دليل إضافة كود C وC++ إلى المشروع في "استوديو Android".

سطر الأوامر

عند الإنشاء باستخدام CMake خارج Gradle، يجب تمرير ملف سلسلة الأدوات نفسه ووسيطاته إلى CMake. على سبيل المثال:

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

وسيطات سلسلة الأدوات

يمكن تمرير الوسيطات التالية إلى ملف CMake toolchain. في حال الإنشاء باستخدام Gradle، أضِف الوسيطات إلى android.defaultConfig.externalNativeBuild.cmake.arguments كما هو موضَّح في مستندات ExternalNativeBuild. في حال الإنشاء من سطر الأوامر، مرِّر الوسيطات إلى CMake باستخدام -D. على سبيل المثال، لفرض عدم تنفيذ armeabi-v7a على دعم Neon، عليك تمرير الخطأ -DANDROID_ARM_NEON=FALSE.

ANDROID_ABI

واجهة التطبيق الثنائية (ABI) المستهدَفة للحصول على معلومات عن واجهات التطبيق الثنائية (ABI) المتوافقة، يُرجى الاطّلاع على واجهات التطبيق الثنائية (ABI) في Android.

مبرّد

توفِّر Gradle هذه الوسيطة تلقائيًا. لا تضبط هذه الوسيطة بشكل صريح في ملف build.gradle. للتحكّم في ما تستهدفه واجهات التطبيق الثنائية (ABI) في Gradle، استخدِم abiFilters كما هو موضّح في واجهات برمجة التطبيقات لنظام التشغيل Android.

سطر الأوامر

أنشئ تصميمات لهدف واحد لكل إصدار. لاستهداف أكثر من واجهة تطبيق ثنائية (ABI) واحدة في Android، عليك إنشاء واجهة تطبيق واحدة مرة واحدة لكل واجهة تطبيق ثنائية (ABI). يُوصى باستخدام دلائل إصدار مختلفة لكل واجهة تطبيق ثنائية (ABI) لتجنب الاصطدامات بين الإصدارات.

القيمة Notes
armeabi-v7a
armeabi-v7a with NEON الأسعار نفسها في فندق armeabi-v7a.
arm64-v8a
x86
x86_64

ANDROID_ARM_MODE

تحدِّد هذه السياسة ما إذا كان سيتم إنشاء تعليمات بشأن الذراع أو الإبهام للإصدار armeabi-v7a. ليس له أي تأثير على واجهات التطبيق الثنائية (ABI) الأخرى لمزيد من المعلومات، يمكنك الاطّلاع على مستندات واجهات ABI في Android.

القيمة Notes
ذراع
إبهام اليد السلوك التلقائي.

ANDROID_ARM_NEON

تتيح هذه السياسة تفعيل NEON لـ armeabi-v7a أو إيقافه. ولن يؤثر ذلك في واجهات التطبيق الثنائية (ABI) الأخرى. يتم ضبط الإعدادات التلقائية على "صحيح" لمستوى واجهة برمجة التطبيقات (minSdkVersion أو ANDROID_PLATFORM) 23 أو أحدث، أو على "خطأ" في حال عدم حدوث أي تغيير. لمزيد من المعلومات، يمكنك الاطّلاع على مستندات دعم Neon.

القيمة Notes
TRUE الإعداد التلقائي للمستوى 23 من واجهة برمجة التطبيقات أو الإصدارات الأحدث.
خطأ الإعداد التلقائي للمستوى 22 من واجهة برمجة التطبيقات أو المستويات الأعلى.

ANDROID_LD

تحدد الرابط الذي سيتم استخدامه. تُعد lld تجريبية في الوقت الحالي لـ NDK ويمكن تفعيلها باستخدام هذه الوسيطة.

القيمة Notes
lld يتم تفعيل lld.
تلقائي استخدِم الرابط التلقائي لواجهة التطبيق الثنائية (ABI) المحدّدة.

ANDROID_NATIVE_API_LEVEL

اسم مستعار لنظام التشغيل ANDROID_PLATFORM.

ANDROID_PLATFORM

تُحدِّد هذه السياسة الحد الأدنى لمستوى واجهة برمجة التطبيقات الذي يتوافق مع التطبيق أو المكتبة. تتجاوب هذه القيمة مع minSdkVersion للتطبيق.

مبرّد

عند استخدام المكوّن الإضافي لنظام Gradle المتوافق مع Android، يتم ضبط هذه القيمة تلقائيًا لتتطابق مع 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 تلقائيًا.

القيمة Notes
c++_shared نسخة المكتبة المشتركة من libc++.
C++_static نسخة المكتبة الثابتة من libc++.
ما من علاقة لا يوجد دعم للمكتبة القياسية لـ C++.
النظامية STL في النظام

فهم أمر إصدار CMake

عند تصحيح مشاكل إصدار CMake، من المفيد معرفة وسيطات الإصدار المحدّدة التي يستخدمها Gradle عند التجميع المتبادل لنظام التشغيل Android.

يحفظ المكوّن الإضافي لنظام Gradle المتوافق مع Android وسيطات التصميم التي يستخدمها لتنفيذ إصدار CMake لكل زوج من واجهة ABI ونوع الإنشاء في build_command.txt. يمكن العثور على هذه الملفات في الدليل التالي:

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

يعرض المقتطف التالي مثالاً على وسيطات CMake لإنشاء إصدار قابل لتصحيح الأخطاء من نموذج hello-jni الذي يستهدف بنية armeabi-v7a.

                    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، اتّبِع مستندات التبعية في "استوديو YouTube" لاستيرادها واستخدامها. وإذا كنت لا تستخدم AGP، يمكنك متابعة https://google.github.io/prefab/example-workflow.html، ولكن من الأسهل كثيرًا الانتقال إلى AGP.

بالنسبة إلى المكتبات غير الموزَّعة كـ AAR، وتعليمات استخدام المكتبات المُنشأة مسبقًا باستخدام CMake، راجِع مستندات add_library بشأن أهداف IMPORTED في دليل CMake.

إنشاء رمز برمجي تابع لجهة خارجية

هناك عدد من الطرق لإنشاء التعليمات البرمجية التابعة لجهة خارجية كجزء من مشروع CMake، وأي خيار يعمل بشكل أفضل سيعتمد على موقفك. غالبًا ما يكون الخيار الأفضل هو عدم القيام بذلك على الإطلاق. بدلاً من ذلك، أنشِئ قيمة AAR للمكتبة واستخدِمها في تطبيقك. ولا تحتاج بالضرورة إلى نشر ميزة "الاقتراحات المطبّقة تلقائيًا". ويمكن أن تكون داخلية في مشروع Gradle الخاص بك.

إذا لم يكن هذا الخيار متاحًا:

  • مورِّد (أي نسخ) المصدر التابع لجهة خارجية إلى مستودعك واستخدِم add_subdirectory لإنشائه. لا يعمل هذا إلا إذا تم إنشاء المكتبة الأخرى أيضًا باستخدام CMake.
  • عرِّف مشروعًا خارجيًا.
  • يمكنك إنشاء المكتبة بشكل منفصل عن مشروعك واتّباع التعليمات الواردة في المقالة استخدام المكتبات المُنشأة مسبقًا لاستيرادها كمكتبات منشأة مسبقًا.

دعم YASM في CMake

يوفر NDK دعم CMake لإنشاء رمز التجميع مكتوبًا بلغة YASM ليتم تشغيله على البِنى الأساسية من x86 وx86-64. YASM هو مجمع مفتوح المصدر للبُنى x86 وx86-64، استنادًا إلى مجمع NASM.

لإنشاء رمز التجميع باستخدام CMake، عليك إجراء التغييرات التالية في عنصر CMakeLists.txt الخاص بمشروعك:

  1. استدعِ enable_language مع ضبط القيمة على ASM_NASM.
  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 في مستودع NDK git.

الإبلاغ عن المشاكل

إذا واجهت أي مشاكل في NDK أو ملف سلسلة أدوات CMake الخاص به، يمكنك الإبلاغ عنها عبر أداة تتبع مشاكل android-ndk/ndk على GitHub. بالنسبة إلى مشاكل Gradle أو مكوّن Gradle الإضافي لـ Android، يمكنك الإبلاغ عن خطأ في "استوديو YouTube" بدلاً من ذلك.