כדי לכלול את הפרויקט של ספריית הנייטיב כתלות ב-build של Gradle, צריך כדי לספק ל-Gradle את הנתיב לקובץ הסקריפט CMake או ndk-build. מתי שאתם מפתחים את האפליקציה שלכם, Gradle מפעילה את CMake או ndk-build, וחבילות משותפות ספריות עם האפליקציה שלכם. Gradle משתמשת גם בסקריפט של build כדי לדעת אילו קבצים ניגשים לפרויקט Android Studio, כך שאפשר לגשת אליהם החלון Project. אם אין לכם סקריפט build ל-Native מקורות, צריך ליצור Cצור סקריפט build לפני שתמשיך.
כל מודול בפרויקט Android יכול לקשר ל-CMake או ל-ndk-build אחד בלבד
סקריפט. לדוגמה, אם אתם רוצים ליצור ולארוז פלטים
מספר פרויקטים של CMake, יש להשתמש בקובץ CMakeLists.txt
אחד
בתור סקריפט ה-build ברמה העליונה של CMake (שאליו מקשרים את Gradle)
הוספת פרויקטים אחרים של CMake בתור
יחסי התלות של סקריפט ה-build הזה. באותו האופן, אם משתמשים ב-ndk-build,
יכול לכלול קובצי מאכל אחרים ברמה העליונה
Android.mk
קובץ סקריפט.
אחרי שמקשרים את Gradle לפרויקט מקורי, Android Studio מעדכן את החלונית Project כדי להציג את קובצי המקור והספריות המקוריות בקבוצה cpp, ואת הסקריפטים החיצוניים של build קבוצה קובצי Build חיצוניים.
הערה: כשמשנים את ההגדרות של Gradle, חשוב להקפיד כדי להחיל את השינויים, לוחצים על סנכרון הפרויקט בסרגל הכלים. בנוסף, כשמבצעים שינויים ב-CMake או ב-ndk-build את קובץ הסקריפט אחרי שכבר קישרתם אותו ל-Gradle, עליכם לסנכרן אותו. ב-Android Studio עם השינויים שביצעת באמצעות בחירה באפשרות פיתוח > רענון C++ המקושר פרויקטים בסרגל התפריטים.
שימוש בממשק המשתמש של Android Studio
אפשר לקשר את Gradle לפרויקט CMake חיצוני או לפרויקט ndk-build באמצעות ממשק המשתמש של Android Studio:
- פותחים את החלונית Project (פרויקט) מהצד השמאלי של סביבת הפיתוח המשולבת (IDE), בוחרים בתצוגת Android.
- לוחצים לחיצה ימנית על המודול שרוצים לקשר לספריית הנייטיב, כמו המודול app, ובחר קישור C++ פרויקט עם Gradle מהתפריט. אמורה להופיע תיבת דו-שיח שדומה לזו אחת שמוצגת באיור 4.
- בתפריט הנפתח, בוחרים באפשרות CMake או
ndk-build.
- אם בוחרים באפשרות CMake, משתמשים בשדה שלצד
נתיב הפרויקט לציון הסקריפט
CMakeLists.txt
עבור פרויקט CMake החיצוני. - אם בוחרים באפשרות ndk-build, צריך להשתמש בשדה שליד
Project Path כדי לציין את קובץ הסקריפט
Android.mk
עבור את פרויקט ה-ndk-build החיצוני שלכם. Android Studio כולל גם אתApplication.mk
אם הוא נמצא באותה ספרייה שבה נמצא קובץAndroid.mk
.
- אם בוחרים באפשרות CMake, משתמשים בשדה שלצד
נתיב הפרויקט לציון הסקריפט
- לוחצים על אישור.
הגדרה ידנית של 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
, אפשר לשנות את המאפיינים האלה לכל אחד מהם
ולשפר את הטעם של המוצר בתצורת ה-build שלך.
לדוגמה, אם בפרויקט CMake או ndk-build מוגדרים כמה רכיבי Native
אפשר להשתמש בפקודה
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 {...} } }
לקבלת מידע נוסף על הגדרת טעמים של מוצרים ועל יצירת וריאציות, אפשר לעבור אל
הגדרת וריאציות ב-Build עבור
רשימה של משתנים שאפשר להגדיר ל-CMake באמצעות
arguments
, ראו שימוש במשתני CMake.
הכללה של ספריות מותאמות מוכנות מראש
אם רוצים ש-Gradle לארוז מראש ספריות מקוריות מוכנות מראש שלא נעשה בהן שימוש
build מקורי חיצוני, צריך להוסיף אותם אל src/main/jniLibs/ABI
של המודול.
נדרשות גרסאות של הפלאגין Android Gradle לפני 4.0, כולל CMake
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'
אם משתמשים ב-Android Gradle Plugin 4.0, צריך להעביר את כל הספריות שנמצאות בשימוש על ידי
IMPORTED
כדי להימנע מהשגיאה הזו, יש ליצור יעדים מתוך הספרייה jniLibs
.
ציון ממשקי ABI
כברירת מחדל, Gradle יוצרת את ספריית הנייטיב שלך לתוך .so
נפרדת
עבור Application Binary Interface
(ABI) ש-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
). גרדל
יוצר את הגדרות ה-ABI האלה אלא רק את החבילות שקבעתם
defaultConfig.ndk
.
מומלץ לפרסם באמצעות קובצי Android App Bundle כדי לצמצם עוד יותר את גודל האפליקציה שלך, כלומר רק ספריות מקוריות שתואמות לממשק ה-ABI של המשתמש המכשיר יסופק עם ההורדה.
לגבי אפליקציות מדור קודם שמפרסמים באמצעות חבילות APK (שנוצרו לפני אוגוסט 2021), כדאי לשקול את האפשרות
הגדרה
כמה חבילות APK על סמך ממשק ABI – במקום ליצור APK גדול אחד עם כל חבילות ה-APK
גרסאות של ספריות ה-ABI שלך, Gradle יוצרת APK נפרד לכל ABI
שרוצים לתמוך בהם ואריזתם רק את הקבצים שדרושים לכל ממשק ABI. אם
להגדיר כמה חבילות APK לכל ממשק ABI בלי לציין את הקוד
סימון abiFilters
כמו בדוגמת הקוד שלמעלה, Gradle
את כל גרסאות ה-ABI הנתמכות של הספריות המקוריות, אבל רק חבילות אותן
שציינת בתצורה המרובת של ה-APK. כדי להימנע מבניית גרסאות של
את הספריות המקוריות שלא רוצים ליצור, לספק את אותה רשימה של ממשקי ABI
גם הדגל abiFilters
וגם ה-APK המרוב לכל ABI
הגדרה אישית.