CMake

Android NDK תומך בשימוש ב-CMake כדי להדר את קוד C ו-C++ לאפליקציה שלכם. בדף הזה מוסבר איך משתמשים CMake באמצעות NDK באמצעות ExternalNativeBuild של הפלאגין של Android Gradle או כאשר בהפעלה ישירה של CMake.

קובץ ה-toolchain של CMake

NDK תומך ב-CMake באמצעות קובץ Toolchain. קובצי Toolchain הם קובצי CMake להתאמה אישית של ההתנהגות של ה-toolchain לביצוע הידור מוצלב. שרשרת הכלים משמש עבור ה-NDK נמצא ב-NDK ב- <NDK>/build/cmake/android.toolchain.cmake

פרמטרים של build כמו ABI , minSdkVersion וכו' ניתנים בפקודה כשמפעילים את cmake. לרשימת ארגומנטים נתמכים אפשר לעיין במאמר הקטע Toolchain instances.

"החדש" קובץ Toolchain

בשלב מוקדם יותר, קבוצות NDK ניסו הטמעה חדשה של קובץ Toolchain יצמצם את ההבדלים בהתנהגות בין השימוש בקובץ ה-toolchain של ה-NDK באמצעות התמיכה המובנית של CMake. בסופו של דבר, נדרש נפח משמעותי עבודה (שלא הושלמה), אבל לא שיפרה בפועל את ההתנהגות, ולכן אנחנו כבר לא מטפלים בנושא הזה.

"החדש" לקובץ Toolchain יש רגרסיות של התנהגות בהשוואה לקובץ ה-toolchain "מדור קודם". Toolchain. פעולת ברירת המחדל היא תהליך העבודה המומלץ. אם אתם באמצעות -DANDROID_USE_LEGACY_TOOLCHAIN_FILE=OFF, אנחנו ממליצים להסיר את הדגל הזה מה-build שלך. קובץ ה-toolchain החדש מעולם לא זהה לזה של הגרסה הקודמת קובץ Toolchain, ולכן סביר להניח שיש רגרסיות של התנהגות.

למרות שמומלץ לא להשתמש בקובץ Toolchain החדש, אין כרגע להסיר אותו מה-NDK. פעולה כזו תפגע בגרסאות build שמסתמכות על את ההבדלים בהתנהגות בין קובצי ה-toolchain החדשים לקבצים הקודמים, למרבה הצער, שינוי השם של האפשרות כדי להבהיר ש"מדור קודם" הוא למעשה מומלץ גם לגרום נזק למשתמשים באפשרות הזו. אם אתם שמחים להשתמש את קובץ ה-toolchain החדש שאין צורך להעביר, אבל חשוב לדעת שיש באגים ההתנהגות החדשה של קובץ ה-toolchain לא תטופל, ובמקום זאת שתצטרכו לבצע את ההעברה.

שימוש

גרדל

השימוש בקובץ Toolchain של CMake הוא אוטומטי כשמשתמשים externalNativeBuild צפייה בקטעים הוספת קוד C ו-C++ של Android Studio לקבלת מידע נוסף על הפרויקט.

שורת הפקודה

כשמפתחים באמצעות CMake מחוץ ל-Gradle, קובץ ה-toolchain עצמו יש להעביר את הארגומנטים שלו ל-CMake. לדוגמה:

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

ארגומנטים של 'צרור כלים'

ניתן להעביר את הארגומנטים הבאים לקובץ Toolchain של CMake. אם יוצרים עם Gradle, מוסיפים ארגומנטים android.defaultConfig.externalNativeBuild.cmake.arguments כפי שמתואר מסמכי ExternalNativeBuild אם בונים משורת הפקודה, מעבירים את הארגומנטים יוצרים ביחד עם -D. לדוגמה, כדי לאלץ את Armeabi-v7a לא לבנות באמצעות ניאון תמיכה, צריך להעביר את -DANDROID_ARM_NEON=FALSE.

ANDROID_ABI

ממשק ה-ABI של היעד. מידע נוסף על ממשקי ABI נתמכים מופיע במאמר ממשקי ABI של Android.

גרדל

הארגומנט הזה מופיע ב-Gradle באופן אוטומטי. לא להגדיר במפורש ארגומנט בקובץ build.gradle. כדי לקבוע לאילו יעדים של ABIs Gradle: להשתמש ב-abiFilters כפי שמתואר בממשקי ABI של Android.

שורת הפקודה

יצירת גרסאות build ליעד אחד בכל build. כדי לטרגט ליותר ממכשיר Android אחד צריך ליצור ממשק ABI פעם אחת לכל ABI. מומלץ להשתמש בגרסת build אחרת של כל ממשק ABI כדי למנוע התנגשויות בין גרסאות build.

ערך הערות
armeabi-v7a
armeabi-v7a with NEON בדיוק כמו במלון armeabi-v7a.
arm64-v8a
x86
x86_64

ANDROID_ARM_MODE

המדיניות קובעת אם ליצור הוראות לזרוע או לזרוע הבקרה עבור Armeabi-v7a. לא השפעה על ממשקי ABI אחרים. מידע נוסף זמין במאמר ממשקי ABI של Android התיעוד.

ערך הערות
זרוע
אגודל פעולת ברירת המחדל.

ANDROID_NATIVE_API_LEVEL

כינוי עבור ANDROID_PLATFORM.

ANDROID_PLATFORM

מציינת את רמת ה-API המינימלית שנתמכת על ידי האפליקציה או הספרייה. הזה תואם לערך minSdkVersion של האפליקציה.

גרדל

כשמשתמשים בפלאגין Android Gradle, הערך הזה מוגדר באופן אוטומטי בתור תואם ל-minSdkVersion של האפליקציה ואין להגדיר אותו באופן ידני.

שורת הפקודה

כשמפעילים את CMake ישירות, הערך הזה מוגדר כברירת מחדל לרמת ה-API הנמוכה ביותר. נתמך על ידי ה-NDK בשימוש. לדוגמה, עם NDK r20, הערך הזה מוגדר כברירת מחדל לרמת API 16.

אפשר להזין את הפרמטר הזה בכמה פורמטים:

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

הפורמט $API_LETTER מאפשר לציין את android-N בלי לקבוע את המספר שמשויך לגרסה הזו. שימו לב שבחלק מהגרסאות קיבלה עלייה ב-API ללא הגדלה של אות. אפשר לציין את ממשקי ה-API האלה על ידי הוספת הסיומת -MR1. לדוגמה, רמת API 25 היא android-N-MR1.

ANDROID_STL

מציינת באיזה STL להשתמש עבור האפליקציה הזו. למידע נוסף, ראה C++ תמיכה בספריות. כברירת מחדל, ייעשה שימוש ב-c++_static.

ערך הערות
c++_shared גרסת הספרייה המשותפת של libc++.
c++_static גרסת הספרייה הסטטית של libc++.
ללא אין תמיכה בספריות רגילות ב-C++.
מערכת STL של המערכת

הסבר על הפקודה של CMake build

במהלך ניפוי באגים של CMake, כדאי לדעת מהו ה-build הספציפי ארגומנטים שבהם Gradle משתמשת במהלך הידור צולב ל-Android.

הפלאגין Android Gradle שומר את ארגומנטים של ה-build שבהם הוא משתמש כדי לבצע יצירת גרסת build לכל ממשק ABI וסוג build מתאימים ל-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, צריך לפעול לפי מסמכי התלות של Studio כדי לייבא אותם ולהשתמש בהם. אם לא משתמשים ב-AGP, אפשר לעקוב https://google.github.io/prefab/example-workflow.html, אבל סביר להניח שיש הרבה קל יותר לעבור ל-AGP.

לגבי ספריות שלא מופצות כ-AAR, יש הוראות בנוגע לשימוש לספריות עם CMake, יש לעיין בתיעוד של add_library בנוגע ל-IMPORTED יעדים במדריך ל-CMake.

פיתוח קוד של צד שלישי

יש כמה דרכים לפתח קוד של צד שלישי כחלק מ-CMake ולבחור מבין האפשרויות המתאימות ביותר בהתאם למצב שלכם. הטוב ביותר תהיה בדרך כלל לא לעשות את זה בכלל. במקום זאת, יוצרים AAR עבור ו צורכים אותם באפליקציה שלכם. אתם לא חייבים לפרסם את המלצות ה-AAR. היא יכולה להיות פנימית בפרויקט Gradle שלכם.

אם זה לא אפשרי:

  • לספק (כלומר, להעתיק) את המקור של הצד השלישי למאגר שלכם ולהשתמש בו add_subdirectory כדי לבנות אותו. זה פועל רק אם הספרייה השנייה שנוצרו באמצעות CMake.
  • מגדירים ExternalProject (פרויקט חיצוני).
  • בונים את הספרייה בנפרד מהפרויקט ופועלים לפי ההוראות אפשר להשתמש בספריות מוכנות מראש כדי לייבא את הקובץ כתוכן שנוצר מראש.

תמיכה ב-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 לביצוע הבדיקה במאגר ה-GIT של NDK.

דיווח על בעיות

אם נתקלתם בבעיות ב-NDK או בקובץ ה-toolchain של CMake, דווחו עליהן דרך הכלי למעקב אחרי בעיות android-ndk/ndk ב-GitHub. ל-Gradle או אם יש בעיות בפלאגין Android Gradle, אפשר לדווח על באג ב-Studio במקום זאת.