لتضمين مشروع المكتبة الأصلية كتبعية لإنشاء Gradle، ستحتاج إلى تزويد Gradle بالمسار إلى ملف النص البرمجي CMake أو ndk-build. عند إنشاء تطبيقك، تشغّل Gradle أداة CMake أو ndk-build، وتنشئ حِزمًا للمكتبات المشتركة مع تطبيقك. وتستخدم Gradle أيضًا النص البرمجي للإصدار لمعرفة الملفات التي سيتم نقلها إلى مشروع استوديو Android، كي تتمكّن من الوصول إليها من نافذة المشروع. إذا لم يكن لديك نص إصدار للمصادر المدمجة مع المحتوى، يجب إنشاء نص برمجي لإنشاء CMake قبل المتابعة.
يمكن ربط كل وحدة في مشروع Android بملف نص برمجي واحد فقط CMake أو ndk-build. على سبيل المثال، إذا كنت تريد إنشاء مخرجات وتجميعها من
مشاريع CMake المتعددة، عليك استخدام ملف CMakeLists.txt
واحد
كنص برمجي للإصدار CMake عالي المستوى (الذي تربط به بعد ذلك Gradle)
و
إضافة مشاريع CMake الأخرى كتبعيات لنص الإصدار هذا. وبالمثل، إذا كنت تستخدم ndk-build، يمكنك
تضمين ملفات Makefiles أخرى في ملف النص البرمجي
Android.mk
ذي المستوى الأعلى.
بعد ربط Gradle بمشروع أصلي، يعدّل "استوديو Android" لوحة المشروع لعرض ملفات المصدر والمكتبات الأصلية في مجموعة cpp والنصوص البرمجية للإصدارات الخارجية في مجموعة ملفات الإصدارات الخارجية.
ملاحظة: عند إجراء تغييرات على إعدادات Gradle، احرِص على تطبيق التغييرات من خلال النقر على مزامنة المشروع في شريط الأدوات. بالإضافة إلى ذلك، عند إجراء تغييرات على ملف النص البرمجي CMake أو ndk-build بعد ربطه مسبقًا بتطبيق Gradle، عليك مزامنة Android Studio مع التغييرات التي أجريتها من خلال اختيار إنشاء > إعادة تحميل مشاريع C++ المرتبطة من شريط القوائم.
استخدام واجهة مستخدم "استوديو Android"
يمكنك ربط Gradle بمشروع CMake أو ndk-build خارجي باستخدام واجهة مستخدم "استوديو Android":
- افتح لوحة المشروع من الجانب الأيمن من بيئة التطوير المتكاملة (IDE) واختَر عرض Android.
- انقر بزر الماوس الأيمن على الوحدة التي تريد ربطها بمكتبتك الأصلية، مثل وحدة التطبيق، واختَر ربط مشروع C++ بـ Gradle من القائمة. من المفترض أن يظهر مربّع حوار مشابه للمربّع الذي يظهر في الشكل 4.
- من القائمة المنسدلة، اختَر إما CMake أو ndk-build.
- إذا اخترت CMake (أو CMake)، استخدم الحقل بجانب Project Path (مسار المشروع) لتحديد ملف النص البرمجي
CMakeLists.txt
لمشروع CMake الخارجي. - إذا اخترت ndk-build، استخدِم الحقل بجانب مسار المشروع لتحديد ملف النص البرمجي
Android.mk
لمشروع إصدار ndk الخارجي. يتضمّن "استوديو Android" أيضًا ملفApplication.mk
إذا كان في الدليل نفسه الذي يتضمّن ملفAndroid.mk
.
- إذا اخترت CMake (أو CMake)، استخدم الحقل بجانب Project Path (مسار المشروع) لتحديد ملف النص البرمجي
- انقر على حسنًا.
إعداد Gradle يدويًا
لإعداد تطبيق Gradle يدويًا للربط بمكتبتك الأصلية، عليك إضافة
مجموعة
externalNativeBuild
إلى ملف
build.gradle
على مستوى الوحدة وضبطه باستخدام مجموعة
cmake
أو
ndkBuild
:
رائع
android { ... defaultConfig {...} buildTypes {...} // Encapsulates your external native build configurations. externalNativeBuild { // Encapsulates your CMake build configurations. cmake { // Provides a relative path to your CMake build script. path "CMakeLists.txt" } } }
Kotlin
android { ... defaultConfig {...} buildTypes {...} // Encapsulates your external native build configurations. externalNativeBuild { // Encapsulates your CMake build configurations. cmake { // Provides a relative path to your CMake build script. path = file("CMakeLists.txt") } } }
ملاحظة: إذا كنت تريد ربط Gradle بمشروع ndk-build حالي،
استخدِم المجموعة
ndkBuild
بدلاً من المجموعة
cmake
، وقدِّم مسارًا نسبيًا لملف Android.mk
. وتتضمّن أداة Gradle أيضًا
ملف Application.mk
إذا
كان في الدليل نفسه الذي يتضمّن ملف Android.mk
.
تحديد عمليات الضبط الاختيارية
يمكنك تحديد وسيطات وعلامات اختيارية لـ CMake أو ndk-build من خلال
ضبط وحدة
externalNativeBuild
أخرى داخل مجموعة
defaultConfig
من ملف build.gradle
على مستوى الوحدة. كما هي الحال مع السمات الأخرى في مجموعة
defaultConfig
، يمكنك إلغاء هذه السمات لكلّ
صيغة منتج في إعدادات تصميمك.
على سبيل المثال، إذا كان مشروع CMake أو ndk-build يحدد عدة مكتبات أصلية
وملفات تنفيذية، يمكنك استخدام السمة
targets
لإنشاء وتجميع مجموعة فرعية فقط من هذه العناصر
لصيغة منتج معيّنة. ويوضّح نموذج الرمز التالي بعض السمات التي يمكنك ضبطها:
رائع
android { ... defaultConfig { ... // This block is different from the one you use to link Gradle // to your CMake or ndk-build script. externalNativeBuild { // For ndk-build, instead use the ndkBuild block. cmake { // Passes optional arguments to CMake. arguments "-DANDROID_ARM_NEON=TRUE", "-DANDROID_TOOLCHAIN=clang" // Sets a flag to enable format macro constants for the C compiler. cFlags "-D__STDC_FORMAT_MACROS" // Sets optional flags for the C++ compiler. cppFlags "-fexceptions", "-frtti" } } } buildTypes {...} productFlavors { ... demo { ... externalNativeBuild { cmake { ... // Specifies which native libraries or executables to build and package // for this product flavor. The following tells Gradle to build only the // "native-lib-demo" and "my-executible-demo" outputs from the linked // CMake project. If you don't configure this property, Gradle builds all // executables and shared object libraries that you define in your CMake // (or ndk-build) project. However, by default, Gradle packages only the // shared libraries in your app. targets "native-lib-demo", // You need to specify this executable and its sources in your CMakeLists.txt // using the add_executable() command. However, building executables from your // native sources is optional, and building native libraries to package into // your app satisfies most project requirements. "my-executible-demo" } } } paid { ... externalNativeBuild { cmake { ... targets "native-lib-paid", "my-executible-paid" } } } } // Use this block to link Gradle to your CMake or ndk-build script. externalNativeBuild { cmake {...} // or ndkBuild {...} } }
Kotlin
android { ... defaultConfig { ... // This block is different from the one you use to link Gradle // to your CMake or ndk-build script. externalNativeBuild { // For ndk-build, instead use the ndkBuild block. cmake { // Passes optional arguments to CMake. arguments += listOf("-DANDROID_ARM_NEON=TRUE", "-DANDROID_TOOLCHAIN=clang") // Sets a flag to enable format macro constants for the C compiler. cFlags += listOf("-D__STDC_FORMAT_MACROS") // Sets optional flags for the C++ compiler. cppFlags += listOf("-fexceptions", "-frtti") } } } buildTypes {...} productFlavors { ... create("demo") { ... externalNativeBuild { cmake { ... // Specifies which native libraries or executables to build and package // for this product flavor. The following tells Gradle to build only the // "native-lib-demo" and "my-executible-demo" outputs from the linked // CMake project. If you don't configure this property, Gradle builds all // executables and shared object libraries that you define in your CMake // (or ndk-build) project. However, by default, Gradle packages only the // shared libraries in your app. targets += listOf("native-lib-demo", // You need to specify this executable and its sources in your CMakeLists.txt // using the add_executable() command. However, building executables from your // native sources is optional, and building native libraries to package into // your app satisfies most project requirements. "my-executible-demo") } } } create("paid") { ... externalNativeBuild { cmake { ... targets += listOf("native-lib-paid", "my-executible-paid") } } } } // Use this block to link Gradle to your CMake or ndk-build script. externalNativeBuild { cmake {...} // or ndkBuild {...} } }
للاطّلاع على مزيد من المعلومات حول ضبط نكهات المنتجات وخيارات التصميم، انتقِل إلى
ضبط خيارات الإصدار. للحصول على قائمة بالمتغيّرات التي يمكنك ضبطها لإنشاء CMake باستخدام السمة arguments
، راجِع المقالة استخدام متغيرات CMake.
تضمين المكتبات الأصلية المُنشأة مسبقًا
إذا كنت تريد من Gradle أن تجمع مكتبات أصلية مسبقة الإنشاء وغير مستخدَمة في أي إصدار خارجي، يمكنك إضافتها إلى دليل src/main/jniLibs/ABI
في وحدتك.
يلزم توفير إصدارات من مكوّن Android Gradle الإضافي قبل الإصدار 4.0، بما في ذلك أهداف
IMPORTED
في دليل jniLibs
لتضمينها في تطبيقك. في حال نقل البيانات من إصدار سابق من المكوّن الإضافي، قد
يواجهك خطأ، مثل الخطأ التالي:
* What went wrong:
Execution failed for task ':app:mergeDebugNativeLibs'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.Workers$ActionFacade
> More than one file was found with OS independent path 'lib/x86/libprebuilt.so'
إذا كنت تستخدم الإصدار 4.0 من Android Gradle Plugin.0، عليك نقل أيّ مكتبات يستخدمها
IMPORTED
CMake الأهداف خارج دليل jniLibs
لتجنُّب هذا الخطأ.
تحديد واجهات ABI
بشكل تلقائي، ينشئ Gradle مكتبتك الأصلية في ملفات .so
منفصلة للواجهات الثنائية للتطبيقات (ABIs) التي يتيحها NDK ويدمجها كلّها في تطبيقك. وإذا كنت تريد من
أداة Gradle إنشاء وتجميع بعض إعدادات واجهة التطبيق الثنائية (ABI) فقط لمكتباتك
الأصلية، يمكنك تحديدها باستخدام العلامة ndk.abiFilters
في ملف build.gradle
على مستوى الوحدة، كما هو موضّح أدناه:
رائع
android {
...
defaultConfig {
...
externalNativeBuild {
cmake {...}
// or ndkBuild {...}
}
// Similar to other properties in the defaultConfig
block,
// you can configure the ndk block for each product flavor
// in your build configuration.
ndk {
// Specifies the ABI configurations of your native
// libraries Gradle should build and package with your app.
abiFilters 'x86', 'x86_64', 'armeabi', 'armeabi-v7a',
'arm64-v8a'
}
}
buildTypes {...}
externalNativeBuild {...}
}
Kotlin
android {
...
defaultConfig {
...
externalNativeBuild {
cmake {...}
// or ndkBuild {...}
}
// Similar to other properties in the defaultConfig
block,
// you can configure the ndk block for each product flavor
// in your build configuration.
ndk {
// Specifies the ABI configurations of your native
// libraries Gradle should build and package with your app.
abiFilters += listOf("x86", "x86_64", "armeabi", "armeabi-v7a",
"arm64-v8a")
}
}
buildTypes {...}
externalNativeBuild {...}
}
وفي معظم الحالات، ما عليك سوى تحديد abiFilters
في مجموعة ndk
، على النحو الموضّح أعلاه، لأنّ ذلك يطلب من Gradle إنشاء وتجميع تلك النُسخ من مكتباتك الأصلية. مع ذلك، إذا كنت تريد
التحكّم في المحتوى الذي يجب أن تنشئه أداة Gradle، بغض النظر عمّا تريد
أن تضيفه إلى الحزمة في تطبيقك، يمكنك ضبط علامة abiFilters
أخرى في مجموعة
defaultConfig.externalNativeBuild.cmake
(أو مجموعة
defaultConfig.externalNativeBuild.ndkBuild
). تنشئ أداة Gradle
إعدادات واجهة التطبيق الثنائية (ABI) هذه، ولكنّها لا تقدّم سوى الإعدادات التي تحدّدها في مجموعة
defaultConfig.ndk
.
ننصح بالنشر باستخدام تنسيق "مجموعة حزمات تطبيق Android" لتقليل حجم تطبيقك بشكل أكبر، لأنّه لن يتم تلقّي سوى المكتبات الأصلية التي تطابق واجهة التطبيق الثنائية (ABI) لجهاز المستخدم مع عملية التنزيل.
بالنسبة إلى التطبيقات القديمة التي تنشر باستخدام حِزم APK (تم إنشاؤها قبل آب (أغسطس) 2021)، ننصحك
بضبط عدة حِزم APK استنادًا إلى واجهة التطبيق الثنائية (ABI). وبدلاً من إنشاء حزمة APK كبيرة واحدة باستخدام جميع
إصدارات مكتباتك الأصلية، تنشئ منصة Gradle حزمة APK منفصلة لكل واجهة تطبيق ABI
تريد دعمها، ولا توفِّر سوى الملفات التي تحتاج إليها كل واجهة التطبيق الثنائية (ABI). في حال ضبط عدة حِزم APK لكل واجهة ABI بدون تحديد العلامة abiFilters
كما هو موضّح في نموذج الرمز أعلاه، تنشئ أداة Gradle
جميع إصدارات واجهة التطبيق الثنائية (ABI) المتوافقة مع مكتباتك الأصلية، ولكنها تنشئ فقط الحزم التي
تحدِّدها في إعدادات حِزم APK المتعددة. لتجنُّب إنشاء إصدارات لا تريدها من مكتباتك الأصلية، يمكنك تقديم قائمة واجهات ABI نفسها لكل من العلامة abiFilters
وإعدادات APK المتعددة لكل واجهة برمجة تطبيقات (ABI).