בדף הזה מתואר התחביר של קובץ ה-build של Android.mk
שמשמש את
ndk-build
.
סקירה כללית
הקובץ Android.mk
נמצא בספריית משנה של jni/
של הפרויקט
ומתאר את המקורות והספריות המשותפות למערכת ה-build.
זה בעצם מקטע קטן של קובץ GNU שמערכת ה-build מנתחת פעם אחת,
עוד. הקובץ Android.mk
שימושי לקביעת הגדרות ברמת הפרויקט
Application.mk
, מערכת ה-build ומשתני הסביבה יוצאים
ולא מוגדר. אפשר גם לשנות את ההגדרות ברמת הפרויקט עבור מודולים ספציפיים.
התחביר של Android.mk
מאפשר לקבץ את המקורות למודולים.
מודול הוא ספרייה סטטית, ספרייה משותפת או קובץ הפעלה עצמאי. אפשר להגדיר מודול אחד או יותר בכל קובץ Android.mk
, וניתן להשתמש באותו קובץ מקור בכמה מודולים. רק מערכת ה-build
מציבה ספריות משותפות בחבילת האפליקציה שלך. בנוסף, סטטי
ספריות יכולות ליצור ספריות משותפות.
נוסף לספריות אריזה, מערכת ה-build מטפלת במגוון של
עבורך. לדוגמה, אין צורך לרשום בקובץ Android.mk
קובצי כותרות או יחסי תלות מפורשים בין קבצים שנוצרו. גרסת ה-build של NDK
המערכת מחשבת את הקשרים האלה בשבילכם באופן אוטומטי. כתוצאה מכך, תוכלו ליהנות מתמיכה בפלטפורמה או בכלי פיתוח חדשים במהדורות NDK עתידיות בלי שתצטרכו לגעת בקובץ Android.mk
.
התחביר של הקובץ הזה דומה מאוד לזה שמשמש בקבצים Android.mk
שמופצים עם פרויקט Android Open Source המלא. ההטמעה של מערכת ה-build שמשתמשת בהם שונה, אבל הדמיון ביניהם הוא החלטה מודעת בתכנון שמטרתה להקל על מפתחי האפליקציות לעשות שימוש חוזר בקוד המקור של ספריות חיצוניות.
יסודות
לפני לחקור לעומק את התחביר, כדאי להתחיל בהבנה
את העקרונות הבסיסיים של קובץ Android.mk
. הקטע הזה משתמש
קובץ Android.mk
בדוגמת Hello-JNI למטרה הזו, עם הסבר על התפקיד
שמופעלת כל שורה בקובץ.
קובץ Android.mk
חייב להתחיל בהגדרת המשתנה LOCAL_PATH
:
LOCAL_PATH := $(call my-dir)
המשתנה הזה מציין את המיקום של קובצי המקור בפיתוח
עץ. כאן, פונקציית המאקרו my-dir
, שסופקת על ידי מערכת ה-build, מחזירה את הנתיב של הספרייה הנוכחית (הספרייה שמכילה את הקובץ Android.mk
עצמו).
השורה הבאה מצהירה על המשתנה CLEAR_VARS
, שהערך שלו הוא מערכת ה-build
מספקת.
include $(CLEAR_VARS)
המשתנה CLEAR_VARS
מפנה לקובץ Makefile מיוחד של GNU שמנקה הרבה
LOCAL_XXX
משתנים עבורך, כמו LOCAL_MODULE
, LOCAL_SRC_FILES
ו
LOCAL_STATIC_LIBRARIES
שימו לב שהיא לא מנקה את LOCAL_PATH
. המשתנה הזה חייב לשמור על הערך שלו כי המערכת מנתחת את כל קובצי הבקרה של ה-build בהקשר אחד של ביצוע GNU Make, שבו כל המשתנים הם גלובליים. צריך
(re-) להצהיר (re-) על המשתנה הזה לפני התיאור של כל מודול.
לאחר מכן, המשתנה LOCAL_MODULE
שומר את שם המודול שרוצים לשמור
build. צריך להשתמש במשתנה הזה פעם אחת לכל מודול באפליקציה.
LOCAL_MODULE := hello-jni
כל שם מודול חייב להיות ייחודי ולא מכיל רווחים. כשמערכת ה-build יוצרת את הקובץ הסופי של הספרייה המשותפת, היא מוסיפה באופן אוטומטי את הקידומת והסיומת המתאימות לשם שהקצית ל-LOCAL_MODULE
. לדוגמה,
בדוגמה שמופיעה למעלה נוצרת ספרייה שנקראת
libhello-jni.so
השורה הבאה מסכמת את קובצי המקור, עם רווחים המפרידים מספר קובצי מקור קבצים:
LOCAL_SRC_FILES := hello-jni.c
המשתנה LOCAL_SRC_FILES
חייב להכיל רשימה של קובצי מקור מסוג C או C++
לפתח מודול במודול.
השורה האחרונה עוזרת למערכת לקשר הכול יחד:
include $(BUILD_SHARED_LIBRARY)
המשתנה BUILD_SHARED_LIBRARY
מפנה לסקריפט של GNU Makefile שמאגד את כל המידע שהגדרתם במשתני LOCAL_XXX
מאז include
האחרון. הסקריפט הזה קובע מה ליצור ואיך לעשות אותו.
קיימות דוגמאות מורכבות יותר בספריות הדוגמאות עם הערות
Android.mk
קבצים שאפשר לצפות בהם. בנוסף, בקובץ Sample: native-activity מוסבר בפירוט על קובץ ה-Android.mk
של הדוגמה הזו. לבסוף, בקטע משתנים ומאקרוסים מפורט מידע נוסף על המשתנים מהקטע הזה.
משתנים ומאקרו
מערכת ה-build מספקת משתנים אפשריים רבים לשימוש בקובץ Android.mk
.
רבים מהמשתנים האלה מגיעים עם ערכים שהוקצו מראש. את האחרים, אתם מקצים.
בנוסף למשתנים האלה, אפשר גם להגדיר משתנים שרירותיים משלכם. אם תעשו זאת, חשוב לזכור שמערכת ה-build של NDK שומרת לעצמה את שמות המשתנים הבאים:
- שמות שמתחילים ב-
LOCAL_
, כמוLOCAL_MODULE
. - שמות שמתחילים ב-
PRIVATE_
, ב-NDK_
או ב-APP
. מערכת ה-build משתמשת בהם באופן פנימי. - שמות באותיות קטנות, כמו
my-dir
. מערכת ה-build משתמשת בהם באופן פנימי, נו.
אם אתם צריכים להגדיר משתני נוחות משלכם בקובץ Android.mk
,
מומלץ להוסיף את MY_
לשמות שלהם.
משתני הכללה שמוגדרים על ידי NDK
בקטע הזה מוסבר על משתני GNU Make שהמערכת ליצירת גרסאות build מגדירה לפני הניתוח של הקובץ Android.mk
. בנסיבות מסוימות, ה-NDK
יכול לנתח את קובץ Android.mk
כמה פעמים, תוך שימוש בהגדרה שונה
עבור חלק מהמשתנים האלה בכל פעם.
CLEAR_VARS
המשתנה הזה מפנה לסקריפט build שמגדיר כמעט את כל LOCAL_XXX
המשתנים שמפורטים בקטע "משתנים מוגדרים על ידי מפתחים" בהמשך. משתמשים במשתנה הזה כדי לכלול את הסקריפט הזה לפני שמתארים מודול חדש. התחביר של
באמצעותה:
include $(CLEAR_VARS)
BUILD_EXECUTABLE
המשתנה הזה מפנה לסקריפט build שמאגד את כל המידע על המודול שסיפקתם במשתני LOCAL_XXX
, ומחליט איך ליצור קובץ הפעלה של היעד מהמקורות שציינתם. שימו לב שהשימוש
הסקריפט מחייב שכבר הקצית ערכים ל-LOCAL_MODULE
LOCAL_SRC_FILES
, לכל הפחות (למידע נוסף על המשתנים האלה, אפשר לעיין במאמר
משתנים של תיאור מודול).
התחביר לשימוש במשתנה הזה הוא:
include $(BUILD_EXECUTABLE)
BUILD_SHARED_LIBRARY
המשתנה הזה מפנה לסקריפט של build שאוסף את כל המידע על
המודול שסיפקתם במשתנים של LOCAL_XXX
, וקובע איך
ליצור ספריית יעד משותפת מהמקורות שציינת. חשוב לזכור שכדי להשתמש בסקריפט הזה, צריך להקצות ערכים למשתנים LOCAL_MODULE
ו-LOCAL_SRC_FILES
לפחות (מידע נוסף על המשתנים האלה זמין במאמר משתני תיאור של מודולים).
התחביר לשימוש במשתנה הזה הוא:
include $(BUILD_SHARED_LIBRARY)
משתנה של ספרייה משותפת גורם למערכת ה-build ליצור קובץ ספרייה עם הסיומת .so
.
BUILD_staticIC_LIBRARY
וריאנט של BUILD_SHARED_LIBRARY
המשמש ליצירת ספרייה סטטית.
מערכת ה-build לא מעתיקה ספריות סטטיות לפרויקט/לחבילות שלכם, אלא
יכולים להשתמש בהם כדי ליצור ספריות משותפות (ראו LOCAL_STATIC_LIBRARIES
LOCAL_WHOLE_STATIC_LIBRARIES
, למטה). התחביר לשימוש במשתנה הזה הוא:
include $(BUILD_STATIC_LIBRARY)
משתנה ספרייה סטטית גורם למערכת ה-build ליצור ספרייה עם
התוסף .a
.
PREBUILT_SHARED_LIBRARY
הפניה לסקריפט build שמשמש לציון ספרייה משותפת שנוצרה מראש. ביטול לייק ב:
במקרה של BUILD_SHARED_LIBRARY
ו-BUILD_STATIC_LIBRARY
, כאן הערך של
LOCAL_SRC_FILES
לא יכול להיות קובץ מקור. במקום זאת, הוא חייב להיות נתיב יחיד
ספרייה משותפת שהוגדרה מראש, כמו foo/libfoo.so
. התחביר לשימוש
הוא:
include $(PREBUILT_SHARED_LIBRARY)
אפשר גם להפנות לספרייה שנוצרה מראש במודול אחר באמצעות המשתנה LOCAL_PREBUILTS
. מידע נוסף על שימוש בספריות מוכנות מראש זמין במאמר שימוש בספריות מוכנות מראש.
PREBUILT_STATIC_LIBRARY
זהה ל-PREBUILT_SHARED_LIBRARY
, אבל לספרייה סטטית שהוגדרה מראש. עבור
למידע נוסף על השימוש בתבניות מוכנות מראש, אפשר לעיין במאמר שימוש בספריות מוכנות מראש.
משתני מידע יעד
מערכת ה-build מנתחת את Android.mk
פעם אחת לכל ממשק ABI שצוין ב-APP_ABI
שמוגדר בדרך כלל בקובץ Application.mk
. אם הערך של APP_ABI
הוא all
, מערכת ה-build תנתח את Android.mk
פעם לכל ABI שנתמך ב-NDK. בקטע הזה מתוארים משתנים שמערכת ה-build מגדירה בכל פעם
מנתח את Android.mk
.
TARGET_ARCH
משפחת המעבדים שמערכת ה-build מטרגטת בזמן הניתוח של הקובץ Android.mk
. המשתנה יהיה אחד מהערכים הבאים: arm
, arm64
, x86
או x86_64
.
TARGET_PLATFORM
מספר רמת ה-API של Android שמערכת ה-build מטרגטת בזמן הניתוח של הקובץ Android.mk
. לדוגמה, תמונות המערכת של Android 5.1 מתאימות אל
רמת API ב-Android 22: android-22
. לרשימה מלאה של שמות הפלטפורמות
לתמונות המתאימות של המערכת של Android, ראו ממשקי API נייטיב. בדוגמה הבאה מופיע התחביר לשימוש במשתנה הזה:
ifeq ($(TARGET_PLATFORM),android-22)
# ... do something ...
endif
TARGET_ARCH_ABI
ה-ABI שמערכת ה-build מטרגטת בזמן שהיא מנתחת את קובץ ה-Android.mk
הזה.
בטבלה 1 מוצגת הגדרת ה-ABI שנעשה בה שימוש לכל מעבד וארכיטקטורה נתמכים.
טבלה 1. הגדרות של ממשק ABI לארכיטקטורות ולמעבדים שונים.
מעבד (CPU) וארכיטקטורה | הגדרה |
---|---|
ARMv7 | armeabi-v7a |
ARMv8 AArch64 | arm64-v8a |
i686 | x86 |
x86-64 | x86_64 |
בדוגמה הבאה אפשר לראות איך בודקים אם היעד ARMv8 AArch64 הוא ARMv8 AArch64 שילוב של מעבד (CPU) ו-ABI:
ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
# ... do something ...
endif
לפרטים נוספים על ממשקי ABI של ארכיטקטורה ובעיות תאימות משויכות, מידע נוסף זמין במאמר ממשקי ABI של Android.
לממשקי ABI חדשים לטירגוט יהיו ערכים שונים בעתיד.
TARGET_ABI
שרשור של רמת ה-API של Android לטירגוט ו-ABI. האפשרות הזו שימושית במיוחד כשרוצים לבדוק את התמונה של מערכת היעד במכשיר אמיתי. לדוגמה, כדי לבדוק אם יש מכשיר ARM עם 64 ביט שפועל עם Android API ברמה 22:
ifeq ($(TARGET_ABI),android-22-arm64-v8a)
# ... do something ...
endif
משתנים של תיאור מודול
המשתנים בקטע הזה מתארים את המודול שלכם למערכת ה-build. כל אחד תיאור המודול צריך להתאים לתהליך הבסיסי הבא:
- מאתחלים או מבטלים את ההגדרה של המשתנים שמשויכים למודול באמצעות המשתנה
CLEAR_VARS
. - מקצים ערכים למשתנים שמשמשים לתיאור המודול.
- מגדירים את מערכת ה-build של NDK להשתמש בסקריפט ה-build המתאים למודול, באמצעות המשתנה
BUILD_XXX
.
LOCAL_PATH
המשתנה הזה משמש כדי לתת את הנתיב של הקובץ הנוכחי. צריך להגדיר אותה
בתחילת הקובץ Android.mk
. בדוגמה הבאה אפשר לראות איך לבצע
כך:
LOCAL_PATH := $(call my-dir)
הסקריפט שאליו נקודות CLEAR_VARS
לא מנקה את המשתנה הזה. לכן, צריך להגדיר אותו רק פעם אחת, גם אם קובץ Android.mk
מתאר כמה מודולים.
LOCAL_MODULE
המשתנה הזה שומר את שם המודול שלכם. הוא חייב להיות ייחודי בכל המודולים
שמות, ולא יכולים להכיל רווחים. צריך להגדיר אותו לפני שמוסיפים סקריפטים (מלבד הסקריפט של CLEAR_VARS
). אין צורך להוסיף את הקידומת lib
או את סיומת הקובץ .so
או .a
. מערכת ה-build מבצעת את השינויים האלה באופן אוטומטי. בכל Android.mk
ו-Application.mk
מתייחסים למודול לפי השם שבו לא בוצעו שינויים. לדוגמה,
התוצאה של יצירת מודול ספרייה משותפת בשם libfoo.so
:
LOCAL_MODULE := "foo"
אם רוצים שהמודול שנוצר יהיה בעל שם שונה מ-lib
+ הערך של LOCAL_MODULE
, אפשר להשתמש במשתנה LOCAL_MODULE_FILENAME
כדי לתת למודול שנוצר שם לבחירתכם.
LOCAL_MODULE_FILENAME
המשתנה האופציונלי הזה מאפשר לשנות את השמות ממערכת ה-build
משתמש כברירת מחדל בקבצים שהוא יוצר. לדוגמה, אם השם של
LOCAL_MODULE
הוא foo
. אפשר לאלץ את המערכת לקרוא לקובץ שהיא יוצרת
libnewfoo
. הדוגמה הבאה מראה איך לעשות זאת:
LOCAL_MODULE := foo
LOCAL_MODULE_FILENAME := libnewfoo
לדוגמה, מודול של ספרייה משותפת ייצור קובץ בשם libnewfoo.so
.
LOCAL_SRC_FILES
המשתנה הזה מכיל את רשימת קובצי המקור שמערכת ה-build משתמשת בהם כדי
היא ליצור את המודול. הצגת רשימה רק של הקבצים שמערכת ה-build מעבירה בפועל
מהדר, מכיוון שמערכת ה-build תחשב באופן אוטומטי את כל
של יחסי התלות. שימו לב שאפשר להשתמש גם ביחס ל-LOCAL_PATH
וגם במספר מוחלט
נתיבי קבצים.
מומלץ להימנע מנתיבי קבצים מוחלטים. נתיבי קבצים יחסיים מאפשרים להעביר את הקובץ Android.mk
בקלות רבה יותר.
LOCAL_CPP_תוספים
ניתן להשתמש במשתנה האופציונלי הזה כדי לציין סיומת קובץ שאינה
.cpp
לקובצי המקור מסוג C++. לדוגמה, השורה הבאה משנה את
לתוסף ל-.cxx
. (ההגדרה חייבת לכלול את הנקודה).
LOCAL_CPP_EXTENSION := .cxx
ניתן להשתמש במשתנה הזה כדי לציין כמה תוספים. לדוגמה:
LOCAL_CPP_EXTENSION := .cxx .cpp .cc
LOCAL_CPP_FEATURES
ניתן להשתמש במשתנה האופציונלי הזה כדי לציין שהקוד מסתמך על
תכונות C++. היא מפעילה את דגלי המהדר והקישור הנכונים במהלך ה-build.
תהליך האימות. לקבצים בינאריים מוכנים מראש, המשתנה הזה מצהיר גם אילו מהם כוללים
הבינארית תלויה, וכך היא עוזרת להבטיח שהקישור הסופי פועל כמו שצריך. מומלץ להשתמש במשתנה הזה במקום להפעיל את -frtti
ואת -fexceptions
ישירות בהגדרה של LOCAL_CPPFLAGS
.
השימוש במשתנה הזה מאפשר למערכת ה-build להשתמש בדגלים המתאימים לכל מודול. שימוש ב-LOCAL_CPPFLAGS
גורם למהדר להשתמש בכל הפריטים שצוינו
דגלים בכל המודולים, ללא קשר לצורך בפועל.
לדוגמה, כדי לציין שהקוד משתמש ב-RTTI (פרטי סוג בזמן ריצה), כותבים:
LOCAL_CPP_FEATURES := rtti
כדי לציין שהקוד משתמש בחריגים של C++, כותבים:
LOCAL_CPP_FEATURES := exceptions
אפשר גם לציין כמה ערכים עבור המשתנה הזה. לדוגמה:
LOCAL_CPP_FEATURES := rtti features
הסדר שבו מתארים את הערכים לא חשוב.
LOCAL_C_INCLUDES
ניתן להשתמש במשתנה האופציונלי הזה כדי לציין רשימה של נתיבים,
ספריית NDK root
, להוספה לנתיב החיפוש להכללה במהלך הידור של כל הפריטים
(C, C++ ו-Assembly). לדוגמה:
LOCAL_C_INCLUDES := sources/foo
או אפילו:
LOCAL_C_INCLUDES := $(LOCAL_PATH)/<subdirectory>/foo
צריך להגדיר את המשתנה הזה לפני שמגדירים סימוני הכללה תואמים באמצעות
LOCAL_CFLAGS
או LOCAL_CPPFLAGS
.
מערכת ה-build גם משתמשת בנתיבי LOCAL_C_INCLUDES
באופן אוטומטי בהפעלה
ניפוי באגים מקורי באמצעות ndk-gdb.
LOCAL_ASFLAGS
סימונים שמועברים ל-Clang כשבונים קובצי .s
או .S
.
LOCAL_ASMFLAGS
דגלים שיועברו ל-yasm בזמן ה-build של קבצים מסוג .asm
.
LOCAL_CFLAGS
דגלים שיועברו ל-Clang כשבונים את C, C++
קובצי מקור מסוג assembly (.s
ו-.S
, אבל לא .asm
). היכולת לעשות זאת יכולה להיות שימושית כדי לציין הגדרות מאקרו או אפשרויות הידור נוספות. כדאי להשתמש
LOCAL_CPPFLAGS
כדי לציין דגלים עבור C++ בלבד. משתמשים ב-LOCAL_CONLYFLAGS
כדי לציין דגלים עבור C בלבד.
מומלץ לא לשנות את רמת האופטימיזציה או ניפוי הבאגים בקובץ Android.mk
.
מערכת ה-build יכולה לטפל בהגדרה הזו בשבילך באופן אוטומטי באמצעות
מידע רלוונטי בקובץ Application.mk
. כך מערכת ה-build יכולה ליצור קובצי נתונים שימושיים לצורך ניפוי באגים.
אפשר לציין נתיבי include נוספים על ידי כתיבת:
LOCAL_CFLAGS += -I<path>,
עם זאת, עדיף להשתמש ב-LOCAL_C_INCLUDES
למטרה הזו, כי כך תוכלו להשתמש גם בנתיבים שזמינים לניפוי באגים מקומי באמצעות ndk-gdb.
LOCAL_CONLYFLAGS
דגלים שיועברו ל-Clang במהלך הידור מקורות C. ביטול הלייק
LOCAL_CFLAGS
, LOCAL_CONLYFLAGS
לא יועברו ל-Clang במהלך ההידור
C++ או מקורות הרכבה.
LOCAL_CPPFLAGS
קבוצה אופציונלית של דגלים של מהדרים שיועברו בזמן ה-build של קובצי המקור של C++ בלבד. הם יופיעו אחרי ה-LOCAL_CFLAGS
בחשבון המהדר
בשורת הפקודה. השתמשו ב-LOCAL_CFLAGS
כדי לציין דגלים גם ל-C וגם ל-C++.
LOCAL_staticIC_LIBRARIES
המשתנה הזה מאחסן את רשימת המודולים של הספריות הסטטיות שבהן תלוי.
אם המודול הנוכחי הוא ספרייה משותפת או קובץ הפעלה, המשתנה הזה יאלץ את הספריות האלה לעבור קישור לקובץ הבינארי שנוצר.
אם המודול הנוכחי הוא ספרייה סטטית, המשתנה הזה מציין פשוט שמודולים אחרים שתלויים במודול הנוכחי יהיו תלויים גם בספריות שצוינו.
LOCAL_SHARED_LIBRARIES
המשתנה הזה הוא רשימת מודולים של ספריות משותפות שעליהם המשתנה הזה תלוי במהלך זמן הריצה. המידע הזה נחוץ בזמן הקישור, וכדי להטמיע את את המידע התואם בקובץ שנוצר.
LOCAL_WHOLE_STATIC_LIBRARIES
המשתנה הזה הוא וריאנט של LOCAL_STATIC_LIBRARIES
, והוא מציין
המקשר צריך להתייחס למודולים של הספריות המשויכים כאל ארכיונים שלמים. עבור
ניתן למצוא מידע נוסף על ארכיונים שלמים במסמכי התיעוד של GNU ld
דגל --whole-archive
.
המשתנה הזה שימושי כשיש יחסי תלות מעגליים בין כמה ספריות סטטיות. כשמשתמשים במשתנה הזה כדי לבנות ספרייה משותפת, הוא לאלץ את מערכת ה-build להוסיף את כל קובצי האובייקטים מהספריות הסטטיות הבינארית הסופית. עם זאת, הכלל הזה לא נכון גם כשיוצרים קובצי הפעלה.
LOCAL_LDLIBS
המשתנה הזה מכיל את רשימת הדגלים הנוספים של הקישור לשימוש ביצירת הספרייה המשותפת או קובץ ההפעלה. היא מאפשרת להשתמש בקידומת -l
כדי להעביר
השם של ספריות מערכת ספציפיות. לדוגמה, הדוגמה הבאה מורה למקשר ליצור מודול שמקשר ל-/system/lib/libz.so
בזמן הטעינה:
LOCAL_LDLIBS := -lz
לרשימה של ספריות המערכת החשופות שאפשר לקשר אליהן ב-NDK הזה שלו, ראו ממשקי API נייטיב.
LOCAL_LDFLAGS
רשימה של דגלים אחרים לקישור שבהם מערכת ה-build יכולה להשתמש במהלך הבנייה של
ספרייה משותפת או קובץ הפעלה. לדוגמה, כדי להשתמש במנגנון לקישור בין ld.bfd
ARM/X86:
LOCAL_LDFLAGS += -fuse-ld=bfd
LOCAL_ALLOW_UNDEFINED_SYMBOLS
כברירת מחדל, כשמערכת ה-build נתקלת בהפניה לא מוגדרת בזמן הניסיון ליצור ספרייה משותפת, היא תשליך שגיאה מסוג undefined symbol. הזה יכולה לעזור לכם לאתר באגים בקוד המקור.
כדי להשבית את הבדיקה הזו, מגדירים את המשתנה הזה לערך true
. חשוב לשים לב שההגדרה הזו עשויה
תגרום לטעינת הספרייה המשותפת בזמן הריצה.
LOCAL_ARM_מצב
כברירת מחדל, מערכת ה-build יוצרת קבצים בינאריים של יעד ARM במצב תמונה ממוזערת,
כל הוראה היא ברוחב 16 סיביות ומקושרת לספריות ה-STL
ספריית thumb/
. הגדרת המשתנה הזה כ-arm
מאלצת את מערכת ה-build
ליצור את קובצי האובייקט של המודול במצב arm
32-ביט. בדוגמה הבאה מוסבר איך עושים זאת:
LOCAL_ARM_MODE := arm
אפשר גם להורות למערכת ה-build לבנות מקורות ספציפיים רק ב-arm
על ידי הוספת הסיומת .arm
לשמות הקבצים שבמקור. לדוגמה,
מהדוגמה הבאה אומרת למערכת ה-build תמיד לבצע הידור של bar.c
במצב ARM,
אלא לבנות את foo.c
בהתאם לערך של LOCAL_ARM_MODE
.
LOCAL_SRC_FILES := foo.c bar.c.arm
LOCAL_ARM_NEON
המשתנה הזה רלוונטי רק כשמטרגטים את ה-ABI armeabi-v7a
. הוא
מאפשר להשתמש באלמנטים של מהדר (compiler) ARM Advanced SIMD (NEON) ב-C וב-C++
מקורות, וגם הוראות NEON בקובצי Assembly.
שימו לב שלא כל המעבדים (CPU) מבוססי ARMv7 תומכים בתוספים של קבוצת ההוראות של NEON. לכן, צריך לבצע זיהוי של סביבת זמן הריצה כדי להשתמש בצורה בטוחה בקוד הזה בזמן הריצה. למידע נוסף, ראו תמיכה ב-Neon תכונות המעבד (CPU).
לחלופין, אפשר להשתמש בסיומת .neon
כדי לציין שמערכת ה-build.
הכינו רק קובצי מקור ספציפיים בתמיכה של NEON. בדוגמה הבאה, מערכת ה-build מקמפל את foo.c
עם תמיכה ב-thumb וב-neon, את bar.c
עם תמיכה ב-thumb ואת zoo.c
עם תמיכה ב-ARM וב-NEON:
LOCAL_SRC_FILES = foo.c.neon bar.c zoo.c.arm.neon
אם משתמשים בשתי הסיומות, .arm
חייב להקדים את .neon
.
LOCAL_DISABLE_FORMAT_STRING_CHECKS
כברירת מחדל, מערכת ה-build מהדרת קוד עם הגנה על מחרוזת פורמט. ביצוע
אז יאלץ שגיאת מהדר אם משתמשים במחרוזת בפורמט לא קבוע
פונקציה בסגנון printf
. ההגנה הזו מופעלת כברירת מחדל, אבל אפשר להשבית אותה
אותה על ידי הגדרת הערך של המשתנה הזה ל-true
. לא מומלץ לעשות זאת
ללא סיבה משכנעת.
LOCAL_EXPORT_CFLAGS
המשתנה הזה מתעד קבוצה של דגלי מהדר C/C++ שיש להוסיף אל LOCAL_CFLAGS
בהגדרה של כל מודול אחר שמשתמש בו דרך
משתנים של LOCAL_STATIC_LIBRARIES
או LOCAL_SHARED_LIBRARIES
.
לדוגמה, נניח שיש לכם את שתי המודולים הבאים: foo
ו-bar
, שמבוסס על foo
:
include $(CLEAR_VARS)
LOCAL_MODULE := foo
LOCAL_SRC_FILES := foo/foo.c
LOCAL_EXPORT_CFLAGS := -DFOO=1
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := bar
LOCAL_SRC_FILES := bar.c
LOCAL_CFLAGS := -DBAR=2
LOCAL_STATIC_LIBRARIES := foo
include $(BUILD_SHARED_LIBRARY)
כאן, מערכת ה-build מעבירה את הדגלים -DFOO=1
ו--DBAR=2
אל המהדר
כשבונים את bar.c
. הוא גם מצרף דגלים מיוצאים למודול של המודול
LOCAL_CFLAGS
כדי שתוכלו לשנות אותם בקלות.
בנוסף, היחסים בין המודולים הם טרנזיטיביים: אם zoo
תלוי ב-bar
, שגם הוא תלוי ב-foo
, אז zoo
יורש גם את כל הדגלים שיוצאו מ-foo
.
לבסוף, מערכת ה-build לא משתמשת בדגלים המיוצאים במהלך ה-build המקומי (כלומר, ה-build של המודול שהדגלים שלו מיוצאים). לכן, בדוגמה שלמעלה, לא מועברת -DFOO=1
למהדר בזמן ה-build של foo/foo.c
. שפת תרגום
לפתח באופן מקומי, להשתמש ב-LOCAL_CFLAGS
במקום זאת.
LOCAL_EXPORT_CPPFLAGS
המשתנה הזה זהה ל-LOCAL_EXPORT_CFLAGS
, אבל רק לדגלי C++.
LOCAL_EXPORT_C_INCLUDES
המשתנה הזה זהה ל-LOCAL_EXPORT_CFLAGS
, אבל במקרה של C יש לכלול נתיבים. הוא שימושי במקרים שבהם, לדוגמה, bar.c
צריך לכלול כותרות מהמודול foo
.
LOCAL_EXPORT_LDFLAGS
המשתנה הזה זהה ל-LOCAL_EXPORT_CFLAGS
, אבל עבור דגלים מסוג linker.
LOCAL_EXPORT_LDLIBS
המשתנה הזה זהה ל-LOCAL_EXPORT_CFLAGS
, והוא מציין למערכת ה-build להעביר למהדר שמות של ספריות מערכת ספציפיות. מוסיפים את -l
בהתחלה
של כל ספרייה שציינתם.
שימו לב שמערכת ה-build מצרפת דגלים של קישור מיובאים לערך של המשתנה LOCAL_LDLIBS
של המודול. הסיבה לכך היא האופן שבו מקשרי Unix פועלים.
המשתנה הזה שימושי בדרך כלל כשמודול foo
הוא ספרייה סטטית ויש בו קוד שמבוסס על ספריית מערכת. לאחר מכן תוכלו להשתמש ב-LOCAL_EXPORT_LDLIBS
כדי לייצא את התלות. לדוגמה:
include $(CLEAR_VARS)
LOCAL_MODULE := foo
LOCAL_SRC_FILES := foo/foo.c
LOCAL_EXPORT_LDLIBS := -llog
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := bar
LOCAL_SRC_FILES := bar.c
LOCAL_STATIC_LIBRARIES := foo
include $(BUILD_SHARED_LIBRARY)
בדוגמה הזו, מערכת ה-build שמה את -llog
בסוף הפקודה של ה-linker כשהיא יוצרת את libbar.so
. הפעולה הזו אומרת למקשרים ש-libbar.so
תלוי ב-foo
, הוא תלוי גם בספריית הרישום ביומן של המערכת.
LOCAL_SHORT_COMMANDS
מגדירים את המשתנה הזה ל-true
כשלמודול יש מספר גדול מאוד של מקורות ו/או ספריות סטטיות או משותפות תלויות. הפעולה הזו מאלצת את מערכת ה-build
להשתמש בתחביר @
לארכיונים שמכילים קובצי אובייקטים מתווכים או קישורים
של הספריות.
התכונה הזו יכולה להיות שימושית ב-Windows, שבו שורת הפקודה מקבלת רק 8,191 תווים לכל היותר, ויכול להיות שהיא קטנה מדי לפרויקטים מורכבים. היא משפיעה גם על הידור של קובצי מקור ספציפיים, ומציבה גם את רוב הדגלים של המהדר בתוך קובצי רשימה.
לתשומת ליבכם: כל ערך שאינו true
יחזיר את ההתנהגות לברירת המחדל. אפשר גם להגדיר את APP_SHORT_COMMANDS
בקובץ Application.mk
כדי לאלץ את ההתנהגות הזו בכל המודולים בפרויקט.
לא מומלץ להפעיל את התכונה הזו כברירת מחדל, כי היא מאטה את תהליך ה-build.
LOCAL_THIN_ARCHIVE
מגדירים את המשתנה הזה ל-true
כשמפתחים ספריות סטטיות. הפעולה הזו תגרום
ליצור ארכיון דל, קובץ ספרייה שלא מכיל קובצי אובייקטים,
אלא רק נתיבים של קבצים לאובייקטים שבדרך כלל
מכילים.
האפשרות הזו שימושית כדי לצמצם את גודל הפלט של ה-build. החיסרון הוא שאי אפשר להעביר ספריות כאלה למיקום אחר (כל הנתיבים בתוכן הן יחסיים).
הערכים החוקיים הם true
, false
או ריק. ניתן להגדיר ערך ברירת מחדל בשדה
Application.mk
באמצעות המשתנה APP_THIN_ARCHIVE
.
LOCAL_FILTER_ASM
מגדירים את המשתנה הזה כפקודת מעטפת שבה תשתמש מערכת ה-build כדי לסנן את קובצי האסיפה שחולצו או נוצרו מהקבצים שציינתם בשדה LOCAL_SRC_FILES
. הגדרת המשתנה הזה גורמת לשינויים הבאים:
- מערכת ה-build יוצרת קובץ הרכבה זמני מכל מקור מסוג C או C++ במקום להרכיב אותם לקובץ אובייקט.
- מערכת ה-build מריצה את פקודת המעטפת ב-
LOCAL_FILTER_ASM
בכל קובץ הרכבה זמני ובכל קובץ הרכבה שמופיע ב-LOCAL_SRC_FILES
, וכך יוצרת קובץ הרכבה זמני נוסף. - מערכת ה-build מקמפל את קובצי האסיפה המסוננים האלה לקובץ אובייקט.
לדוגמה:
LOCAL_SRC_FILES := foo.c bar.S
LOCAL_FILTER_ASM :=
foo.c --1--> $OBJS_DIR/foo.S.original --2--> $OBJS_DIR/foo.S --3--> $OBJS_DIR/foo.o
bar.S --2--> $OBJS_DIR/bar.S --3--> $OBJS_DIR/bar.o
'1' תואם לרכיב המהדר, "2" למסנן, ו-"3" המסנן חייב להיות פקודת מעטפת עצמאית שמקבלת את שם הקלט בקובץ כארגומנט הראשון, ואת שם קובץ הפלט בתור הארגומנט השני. לדוגמה:
myasmfilter $OBJS_DIR/foo.S.original $OBJS_DIR/foo.S
myasmfilter bar.S $OBJS_DIR/bar.S
פקודות מאקרו של פונקציה שסופקה על ידי NDK
בקטע הזה מוסבר על המאקרו-פונקציות של GNU Make ש-NDK מספק. כדאי להשתמש
$(call <function>)
כדי להעריך אותם. הם מחזירים מידע טקסטואלי.
my-dir
המאקרו מחזיר את הנתיב של קובץ ה-makefile האחרון שנכלל, שלרוב
הספרייה של Android.mk
הנוכחית. אפשר להשתמש ב-my-dir
כדי להגדיר את LOCAL_PATH
בתחילת הקובץ Android.mk
. לדוגמה:
LOCAL_PATH := $(call my-dir)
בשל אופן הפעולה של GNU Maker, המאקרו הזה באמת מחזיר את הנתיב
ה-Makefile האחרון שמערכת ה-build כללה במהלך ניתוח הסקריפטים של ה-build. עבור
לכן אין לקרוא ל-my-dir
אחרי שמוסיפים קובץ אחר.
לדוגמה:
LOCAL_PATH := $(call my-dir)
# ... declare one module
include $(LOCAL_PATH)/foo/`Android.mk`
LOCAL_PATH := $(call my-dir)
# ... declare another module
הבעיה היא שהקריאה השנייה ל-my-dir
מגדירה את LOCAL_PATH
בתור $PATH/foo
במקום $PATH
, כי זה היה היעד של ההכללה האחרונה שלה.
כדי למנוע את הבעיה הזו, מוסיפים עוד קבצים לקובץ Android.mk
אחרי כל שאר הקבצים. לדוגמה:
LOCAL_PATH := $(call my-dir)
# ... declare one module
LOCAL_PATH := $(call my-dir)
# ... declare another module
# extra includes at the end of the Android.mk file
include $(LOCAL_PATH)/foo/Android.mk
אם לא ניתן לבנות את הקובץ באופן הזה, שמור את הערך של
בקריאה הראשונה של my-dir
למשתנה אחר. לדוגמה:
MY_LOCAL_PATH := $(call my-dir)
LOCAL_PATH := $(MY_LOCAL_PATH)
# ... declare one module
include $(LOCAL_PATH)/foo/`Android.mk`
LOCAL_PATH := $(MY_LOCAL_PATH)
# ... declare another module
קבצי מאכל-כל-subdir
הפונקציה מחזירה את רשימת הקבצים מסוג Android.mk
שנמצאים בכל תיקיות המשנה של הנתיב הנוכחי my-dir
.
אפשר להשתמש בפונקציה הזו כדי לספק למערכת ה-build היררכיות של ספריות מקור שמנוהלות בתוך ספריות אחרות. כברירת מחדל, ה-NDK מחפש רק קבצים בספרייה
שמכיל את הקובץ Android.mk
.
קובץ ה-makefile הזה
הפונקציה מחזירה את הנתיב של קובץ ה-makefile הנוכחי (שממנו מערכת ה-build הפעילה את הפונקציה).
parent-makefile
הפונקציה מחזירה את הנתיב של קובץ ה-makefile ההורה בעץ ההכללה (הנתיב של קובץ ה-makefile שכלל את הקובץ הנוכחי).
grand-parent-makefile
הפונקציה מחזירה את הנתיב של קובץ ה-Makefile הסב בעץ ההכללה (הנתיב של קובץ ה-Makefile שכלל את הקובץ הנוכחי).
מודול ייבוא
פונקציה שמאפשרת למצוא ולכלול את קובץ Android.mk
של המודול באמצעות
הוא שם המודול. דוגמה טיפוסית היא:
$(call import-module,<name>)
בדוגמה זו, מערכת ה-build מחפשת את המודול שתויג ב-<name>
רשימת הספריות שסביבת NDK_MODULE_PATH
שלך מפנה אליהן
בהפניות למשתנים, וכוללת את קובץ ה-Android.mk
שלו באופן אוטומטי עבורכם.