אם אתם לא משתמשים ב-CMake או ב-ndk-build, אבל אתם רוצים אינטגרציה מלאה של הפלאגין Android Gradle (AGP) C/C++ build ו-Android Studio, תוכלו ליצור מערכת build מותאמת אישית של C/C++ על ידי יצירת סקריפט מעטפת שכותב נתוני build בפורמט קובץ ה-build של Ninja.
תמיכה ניסיונית במערכות build מותאמות אישית של C/C++ נוספה ל-Android Studio ול-AGP. התכונה הזו זמינה החל מ-Android Studio Dolphin | 2021.3.1 Canary 4.
סקירה כללית
דפוס נפוץ לפרויקטים של C/C++, במיוחד כאלה שמטרגטים מספר פלטפורמות, הוא ליצור פרויקטים לכל אחת מהפלטפורמות האלה מייצוג בסיסי כלשהו.
דוגמה בולטת לדפוס הזה היא CMake. באמצעות CMake אפשר ליצור פרויקטים ל-Android, ל-iOS ולפלטפורמות אחרות מייצוג בסיסי אחד, שנשמר בקובץ CMakeLists.txt
.
ב-AGP יש תמיכה ישירה ב-CMake, אבל יש מחוללי פרויקטים אחרים שאין בהם תמיכה ישירה:
מחוללי פרויקטים מהסוג הזה תומכים בייצוג עורפי של נינג'ה כייצוג בקצה העורפי של גרסת ה-build של C/C++ או שאפשר להתאים אותם כדי ליצור נינג'ה כייצוג בקצה העורפי.
אם מוגדר כראוי פרויקט AGP עם מחולל מערכות פרויקטים משולב מסוג C/C++ מאפשר למשתמשים:
פיתוח משורת הפקודה ומ-Android Studio.
עריכת מקורות עם תמיכה מלאה בשירות שפה (למשל, 'מעבר להגדרה') ב-Android Studio.
אפשר להשתמש בכלי לניפוי באגים ב-Android Studio כדי לנפות באגים בתהליכים מקוריים ומעורבים.
איך לשנות את ה-build כדי להשתמש בסקריפט תצורת build בהתאמה אישית מסוג C/C++
בקטע הזה מתוארות השלבים לשימוש בסקריפט תצורת build מותאם אישית של C/C++ מ-AGP.
שלב 1: משנים את הקובץ build.gradle
ברמת המודול כך שיפנה לסקריפט הגדרה
כדי להפעיל תמיכה ב-נינג'ה ב-AGP, מגדירים את experimentalProperties
בקובץ build.gradle
ברמת המודול:
android {
defaultConfig {
externalNativeBuild {
experimentalProperties["ninja.abiFilters"] = [ "x86", "arm64-v8a" ]
experimentalProperties["ninja.path"] = "source-file-list.txt"
experimentalProperties["ninja.configure"] = "configure-ninja"
experimentalProperties["ninja.arguments"] = [
"\${ndk.moduleMakeFile}",
"--variant=\${ndk.variantName}",
"--abi=Android-\${ndk.abi}",
"--configuration-dir=\${ndk.configurationDir}",
"--ndk-version=\${ndk.moduleNdkVersion}",
"--min-sdk-version=\${ndk.minSdkVersion}"
]
}
}
המאפיינים מפורשים על ידי AGP באופן הבא:
ninja.abiFilters
היא רשימה של ממשקי ABI לבנייה. הערכים החוקיים הם:x86
,x86-64
,armeabi-v7a
ו-arm64-v8a
.ninja.path
הוא נתיב לקובץ של פרויקט C/C++. הפורמט של הקובץ הזה יכול להיות כל דבר שתרצו. שינויים בקובץ הזה יפעילו סנכרון של Gradle ב-Android Studio.ninja.configure
הוא נתיב לקובץ סקריפט שיופעל על ידי Gradle כשיהיה צורך להגדיר את הפרויקט C/C++. הפרויקט מוגדר ב-build הראשון, במהלך סנכרון Gradle ב-Android Studio, או כשיש שינוי באחד מסוגי הקלט של הסקריפט.ninja.arguments
הוא רשימת ארגומנטים שיועברו לסקריפט שהוגדר על ידי ninja.configure. הרכיבים ברשימה הזו יכולים להפנות לקבוצת פקודות מאקרו שהערכים שלהם תלויים בהקשר של ההגדרה הנוכחית ב-AGP:${ndk.moduleMakeFile}
הוא הנתיב המלא לקובץninja.configure
. בדוגמה, זה יהיהC:\path\to\configure-ninja.bat
.${ndk.variantName}
הוא השם של הווריאנט הנוכחי של AGP שנמצא בשלבי פיתוח. לדוגמה, ניפוי באגים או פרסום.${ndk.abi}
הוא השם של ה-AGP ABI הנוכחי שנמצא בשלבי פיתוח. לדוגמה,x86
אוarm64-v8a
.
${ndk.buildRoot}
הוא השם של תיקייה, שנוצרה על ידי AGP, שבה הסקריפט כותב את הפלט. פרטים על כך יוסבר בשלב 2: יצירת סקריפט ההגדרה.${ndk.ndkVersion}
היא גרסת ה-NDK שבה צריך להשתמש. בדרך כלל זהו הערך שמועבר אל android.ndkVersion בקובץbuild.gradle
, או ערך ברירת המחדל אם לא קיים.${ndk.minPlatform}
היא פלטפורמת היעד המינימלית של Android שנדרשת על ידי AGP.
ninja.targets
הוא רשימה של יעדי הנינג'ה הספציפיים שצריך לבנות.
שלב 2: יוצרים את סקריפט ההגדרה
האחריות המינימלית של סקריפט ההגדרה (configure-ninja.bat
בדוגמה הקודמת) היא ליצור קובץ build.ninja
, שכאשר הוא נבנה באמצעות Ninja, הוא יאסוף ויקשר את כל הפלטים המקוריים של הפרויקט. בדרך כלל מדובר בקובצי .o
(אובייקט), .a
(ארכיון) ו-.so
(אובייקט משותף).
סקריפט ההגדרה יכול לכתוב את הקובץ build.ninja
בשני מקומות שונים, בהתאם לצרכים שלכם.
אם מותר ל-AGP לבחור מיקום, סקריפט ההגדרה יכתוב
build.ninja
במיקום שהוגדר במאקרו${ndk.buildRoot}
.אם סקריפט ההגדרה צריך לבחור את המיקום של הקובץ
build.ninja
, הוא כותב גם קובץ בשםbuild.ninja.txt
במיקום שהוגדר במאקרו${ndk.buildRoot}
. הקובץ הזה מכיל את הנתיב המלא לקובץbuild.ninja
שנכתב על ידי סקריפט ההגדרה.
המבנה של הקובץ build.ninja
באופן כללי, רוב המבנה שמייצג במדויק גרסת build של Android C/C++ יפעל. הרכיבים העיקריים שדרושים ל-AGP ול-Android Studio הם:
רשימה של קובצי המקור C/C++ יחד עם הדגלים שדרושים על ידי Clang כדי להדר אותם.
הרשימה של ספריות פלט. אלה בדרך כלל קובצי
.so
(אובייקט משותף), אבל הם יכולים להיות גם.a
(ארכיון) או הפעלה (ללא סיומת).
אם אתם צריכים דוגמאות לאופן יצירת קובץ build.ninja
, תוכלו לעיין בפלט של CMake כשנעשה שימוש במחולל build.ninja
.
הנה דוגמה לתבנית build.ninja
מינימלית.
rule COMPILE
command = /path/to/ndk/clang -c $in -o $out {other flags}
rule LINK
command = /path/to/ndk/clang $in -o $out {other flags}
build source.o : COMPILE source.cpp
build lib.so : LINK source.o
שיטות מומלצות
בנוסף לדרישות (רשימת קובצי המקור וספריות הפלט), בהמשך מפורטות כמה שיטות מומלצות.
הצהרה על פלט בעל שם עם phony
כללים
כשהדבר אפשרי, מומלץ שהמבנה build.ninja
ישתמש בכללי phony
כדי לתת לפלטים של ה-build שמות שקריאים לאנשים. לדוגמה, אם הפלט שלכם נקרא c:/path/to/lib.so
, אתם יכולים לתת לו שם קריא לאנשים באופן הבא.
build curl: phony /path/to/lib.so
היתרון בכך הוא שאפשר לציין את השם הזה כיעד build בקובץ build.gradle
. לדוגמה,
android {
defaultConfig {
externalNativeBuild {
...
experimentalProperties["ninja.targets"] = [ "curl" ]
ציון 'הכול' יעד
כשמציינים יעד all
, זו תהיה קבוצת ברירת המחדל של ספריות שנוצרו על ידי AGP כאשר לא צוינו יעדים באופן מפורש בקובץ build.gradle
.
rule COMPILE
command = /path/to/ndk/clang $in -o $out {other flags}
rule LINK
command = /path/to/ndk/clang $in -o $out {other flags}
build foo.o : COMPILE foo.cpp
build bar.o : COMPILE bar.cpp
build libfoo.so : LINK foo.o
build libbar.so : LINK bar.o
build all: phony libfoo.so libbar.so
ציון שיטת build חלופית (אופציונלי)
תרחיש מתקדם יותר הוא לארוז מערכת build קיימת שלא מבוססת על נינג'ה. במקרה כזה, עדיין צריך לייצג את כל המקורות יחד עם הדגלים שלהם יחד עם ספריות הפלט, כדי שמערכת Android Studio תוכל להציג תכונות מתאימות של שירות שפה, כמו השלמה אוטומטית ו-Go-to-הגדרה. עם זאת, אתם רוצים ש-AGP ידחה את מערכת ה-build הבסיסית במהלך גרסת ה-build בפועל.
כדי לעשות זאת, אפשר להשתמש בפלט build של נינג'ה עם תוסף ספציפי .passthrough
.
דוגמה קונקרטית יותר: נניח שאתם רוצים לעסוק ב-MSBuild. סקריפט ההגדרה יפיק את build.ninja
כרגיל, אבל הוא יוסיף גם יעד העברה שמגדיר איך AGP יפעיל את MSBuild.
rule COMPILE
command = /path/to/ndk/clang $in -o $out {other flags}
rule LINK
command = /path/to/ndk/clang $in -o $out {other flags}
rule MBSUILD_CURL
command = /path/to/msbuild {flags to build curl with MSBuild}
build source.o : COMPILE source.cpp
build lib.so : LINK source.o
build curl : phony lib.so
build curl.passthrough : MBSUILD_CURL
שליחת משוב
התכונה הזו ניסיונית, נשמח לקבל משוב. אפשר לשלוח משוב דרך הערוצים הבאים:
כדי לקבל משוב כללי, אפשר להוסיף תגובה לבאג הזה.
כדי לדווח על באג, פותחים את Android Studio ולוחצים על עזרה > שולחים משוב. חשוב לעיין להתייחסות אל 'מערכות build מותאמות אישית C/C++' כדי לעזור באיתור הבאג.
אם רוצים לדווח על באג אם אפליקציית Android Studio לא מותקנת, אפשר לדווח על באג באמצעות התבנית הזו.