توضّح هذه الصفحة بنية ملف إصدار Android.mk
الذي يستخدمه
ndk-build
.
نظرة عامة
يتوفّر الملف Android.mk
في دليل فرعي من دليل jni/
الخاص بمشروعك، ويصف المصادر والمكتبات المشتركة في نظام الإصدار.
وهو عبارة عن جزء صغير من ملف makefile في GNU يفكّه نظام الإنشاء مرة واحدة أو
أكثر. يكون ملف Android.mk
مفيدًا لتحديد الإعدادات على مستوى المشروع التي لا تحدّدها
Application.mk
ونظام الإنشاء ومتغيّرات البيئة. ويمكنها أيضًا إلغاء الإعدادات على مستوى المشروع لوحدات معيّنة.
تسمح لك بنية Android.mk
بتجميع المصادر في وحدات.
الوحدة هي إما مكتبة ثابتة أو مكتبة مشتركة أو وحدة مستقلة قابلة للتنفيذ. يمكنك تحديد وحدة واحدة أو أكثر في كل ملف Android.mk
،
ويمكنك استخدام الملف المصدر نفسه في وحدات متعددة. لا يضع نظام الإنشاء سوى المكتبات المشتركة في حِزمة تطبيقك. بالإضافة إلى ذلك، يمكن للمكتبات الثابتة
إنشاء مكتبات مشتركة.
بالإضافة إلى حزم المكتبات، يعالج نظام الإنشاء مجموعة متنوعة من
التفاصيل الأخرى نيابةً عنك. على سبيل المثال، لا تحتاج إلى إدراج ملفات الرأس أو التبعيات الواضحة
بين الملفات التي تم إنشاؤها في ملف Android.mk
. يحسب نظام إنشاء NDK
هذه العلاقات تلقائيًا نيابةً عنك. نتيجةً لذلك، من المفترض أن تتمكّن من الاستفادة من دعم المنصة/سلسلة الأدوات الجديدة في إصدارات NDK المستقبلية بدون الحاجة إلى النقر على ملف Android.mk
.
بنية هذا الملف قريبة جدًا من البنية المستخدَمة في ملفات Android.mk
التي تم توزيعها من خلال مشروع مفتوح المصدر لنظام Android الكامل. على الرغم من أنّ نظام الإنشاء
الذي يستخدمهما مختلف، إلا أنّ تشابههما هو قرار intentional
تصميمي يهدف إلى تسهيل إعادة استخدام
الرمز المصدر للمكتبات الخارجية من قِبل مطوّري التطبيقات.
الأساسيات
قبل استكشاف البنية بالتفصيل، من المفيد أن تبدأ بفهم أساسيات ما يحتويه ملف Android.mk
. يستخدم هذا القسم
ملف Android.mk
في نموذج Hello-JNI نحو هذه النهاية، موضحًا الدور الذي يؤديه كل سطر في الملف.
يجب أن يبدأ ملف Android.mk
بتحديد المتغيّر LOCAL_PATH
:
LOCAL_PATH := $(call my-dir)
يشير هذا المتغيّر إلى موقع الملفات المصدر في شجرة التطوير. هنا، تعرض دالة الماكرو my-dir
، التي يوفّرها نظام الإصدار، مسار الدليل الحالي (الدليل الذي يحتوي على ملف Android.mk
نفسه).
يعرِض السطر التالي المتغيّر CLEAR_VARS
الذي يقدّم نظام الإنشاء
قيمته.
include $(CLEAR_VARS)
يشير المتغيّر CLEAR_VARS
إلى ملف GNU Makefile خاص يزيل العديد من متغيّرات
LOCAL_XXX
نيابةً عنك، مثل LOCAL_MODULE
وLOCAL_SRC_FILES
و
LOCAL_STATIC_LIBRARIES
. يُرجى العلم بأنّ السمة LOCAL_PATH
غير واضحة. يجب أن يحتفظ هذا المتغير بقيمته لأن النظام يحلل جميع ملفات تحكم الإصدار
في سياق تنفيذ GNU واحد حيث تكون جميع المتغيرات عمومية. يجب
(إعادة) تعريف هذا المتغيّر قبل وصف كل وحدة.
بعد ذلك، يُخزِّن المتغيّر LOCAL_MODULE
اسم الوحدة التي تريد إنشاءها. استخدِم هذا المتغيّر مرّة واحدة لكل وحدة في تطبيقك.
LOCAL_MODULE := hello-jni
يجب أن يكون اسم كل وحدة فريدًا وألا يحتوي على أي مسافات. عند إنشاء نظام الإنشاء لملف المكتبة المشتركة النهائي، يضيف تلقائيًا البادئة واللاحقة المناسبتين إلى الاسم الذي تحدّده لـ 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
. يحدّد هذا النص البرمجي ما يجب إنشائه وكيفية تنفيذه.
تتوفّر أمثلة أكثر تعقيدًا في أدلة العيّنات، مع ملفات kommentiert
Android.mk
يمكنك الاطّلاع عليها. بالإضافة إلى ذلك، يقدّم القسم نموذج: نشاط أصلي شرحًا تفصيليًا لملف Android.mk
الخاص بالعيّنة. أخيرًا، تقدّم المتغيّرات والوحدات النمطية مزيدًا من المعلومات عن المتغيّرات من
هذا القسم.
المتغيّرات ووحدات الماكرو
يوفّر نظام التصميم العديد من المتغيرات المحتمَلة لاستخدامها في ملف Android.mk
.
وتأتي العديد من هذه المتغيّرات مع قيم محدّدة مسبقًا. أما العناصر الأخرى، فيمكنك تحديدها بنفسك.
بالإضافة إلى هذه المتغيّرات، يمكنك أيضًا تحديد متغيّرات عشوائية. إذا قمت بذلك، فضع في اعتبارك أن نظام إصدار NDK يحتفظ بأسماء المتغيرات التالية:
- الأسماء التي تبدأ بـ
LOCAL_
، مثلLOCAL_MODULE
- الأسماء التي تبدأ بـ
PRIVATE_
أوNDK_
أوAPP
يستخدم نظام الإنشاء هذه الإعدادات داخليًا. - الأسماء المكتوبة بأحرف صغيرة، مثل
my-dir
يستخدم نظام الإنشاء هذه الملفات داخليًا أيضًا.
إذا كنت بحاجة إلى تحديد متغيّرات تسهيل الاستخدام في ملف Android.mk
، ننصحك بprepending MY_
إلى أسمائها.
تتضمن المتغيرات التي يحددها NDK.
يتناول هذا القسم متغيّرات GNU Make التي يحدّدها نظام الإنشاء
قبل تحليل ملف Android.mk
. في حالات معيّنة، قد يفرِّغ NDKAndroid.mk
ملفك عدة مرات باستخدام تعريف مختلف لبعضها في كل مرة.
محو
يشير هذا المتغيّر إلى نص برمجي للإنشاء يلغِي تحديد جميع متغيّرات LOCAL_XXX
تقريبًا المدرَجة في قسم "المتغيّرات التي يحدّدها المطوّر" أدناه. استخدم هذا المتغير لتضمين هذا البرنامج النصي قبل وصف وحدة جديدة. بناء الجملة
لاستخدامها هو:
include $(CLEAR_VARS)
إنشاء_قابلة للتنفيذ
يشير هذا المتغيّر إلى نص برمجي للإنشاء يجمع كل المعلومات حول
الوحدة التي قدّمتها في متغيّرات LOCAL_XXX
، ويحدّد كيفية
إنشاء ملف تنفيذي مستهدَف من المصادر التي أدرجتها. يُرجى العِلم أنّ استخدام هذا الرمز المبرمَج
يتطلّب منك تحديد قيم للمتغيّرينLOCAL_MODULE
و
LOCAL_SRC_FILES
على الأقل (لمزيد من المعلومات عن هذين المتغيّرين، يُرجى الاطّلاع على متغيّرات وصف الوحدة).
بناء الجملة لاستخدام هذا المتغيّر هو:
include $(BUILD_EXECUTABLE)
BUILD_SHARED_LIBRARY
يشير هذا المتغيّر إلى نص برمجي للإصدار يجمع كل المعلومات حول الوحدة التي قدّمتها في متغيّرات LOCAL_XXX
، ويحدّد كيفية إنشاء مكتبة مشتركة مستهدَفة من المصادر التي أدرجتها. يُرجى العِلم أنّ استخدام هذا النص البرمجي يتطلّب منك تحديد قيم للسمتَين LOCAL_MODULE
وLOCAL_SRC_FILES
، على الأقل (لمزيد من المعلومات حول هذين المتغيّرين، يُرجى الاطّلاع على متغيّرات وصف الوحدة).
بناء الجملة لاستخدام هذا المتغيّر هو:
include $(BUILD_SHARED_LIBRARY)
يؤدي متغيّر المكتبة المشتركة إلى إنشاء نظام التصميم لملف مكتبة بامتداد .so
.
BUILD_STATIC_LIBRARY
تمثّل هذه السمة صيغة من BUILD_SHARED_LIBRARY
تُستخدم لإنشاء مكتبة ثابتة. لا ينسخ
نظام الإنشاء المكتبات الثابتة إلى مشروعك/حِزمك، ولكن يمكنه
استخدامها لإنشاء مكتبات مشترَكة (راجِع LOCAL_STATIC_LIBRARIES
و
LOCAL_WHOLE_STATIC_LIBRARIES
أدناه). بناء الجملة لاستخدام هذا المتغير هو:
include $(BUILD_STATIC_LIBRARY)
يؤدي متغيّر المكتبة الثابتة إلى إنشاء نظام التصميم لمكتبة بإضافة .a
.
PREBUILT_SHARED_LIBRARY
يشير إلى نص برمجي للإصدار يُستخدَم لتحديد مكتبة مشتركة مصمّمة مسبقًا. على عكس
حال BUILD_SHARED_LIBRARY
وBUILD_STATIC_LIBRARY
، لا يمكن أن تكون قيمة
LOCAL_SRC_FILES
ملف مصدر. بدلاً من ذلك، يجب أن يكون مسارًا واحدًا يؤدي إلى
مكتبة مشتركة مُنشأة مسبقًا، مثل foo/libfoo.so
. بناء جملة استخدام هذا المتغيّر هو:
include $(PREBUILT_SHARED_LIBRARY)
يمكنك أيضًا الإشارة إلى مكتبة تم إنشاؤها مسبقًا في وحدة أخرى باستخدام المتغيّر LOCAL_PREBUILTS
. لمزيد من المعلومات حول استخدام المباني المنشأة مسبقًا، يمكنك الاطّلاع على استخدام المكتبات المنشأة مسبقًا.
PREBUILT_StatIC_LIBRARY
يُرجى الاطّلاع على PREBUILT_SHARED_LIBRARY
، ولكن بالنسبة إلى مكتبة ثابتة مُسبقة الإنشاء. لمزيد من المعلومات عن استخدام الوحدات المُسبقة الإنشاء، يُرجى الاطّلاع على استخدام المكتبات المُسبقة الإنشاء.
متغيّرات معلومات الاستهداف
يحلِّل نظام التصميم Android.mk
مرة واحدة لكل واجهة تطبيق ثنائية (ABI) يحدّدها المتغيّر APP_ABI
، والذي يتم تحديده عادةً في ملف Application.mk
. إذا كانت قيمة APP_ABI
هي all
، سيحلّل نظام التصميم Android.mk
مرة واحدة لكل واجهة ABI متوافقة مع NDK. يصف هذا القسم المتغيّرات التي يحدّدها نظام التصميم في كل مرة يتم فيها تحليل Android.mk
.
TARGET_ARCH
مجموعة وحدة المعالجة المركزية التي يستهدفها نظام التصميم أثناء تحليل ملف Android.mk
هذا. سيكون هذا المتغيّر أحد ما يلي: arm
أو arm64
أو x86
أو x86_64
.
TARGET_PLATFORM
رقم مستوى واجهة برمجة تطبيقات Android الذي يستهدفه نظام التصميم أثناء تحليل ملف
Android.mk
هذا. على سبيل المثال، تتوافق صور نظام Android 5.1 مع
المستوى 22 لواجهة برمجة تطبيقات Android: android-22
. للحصول على قائمة كاملة بأسماء الأنظمة الأساسية وصور نظام Android المقابلة، يمكنك الاطّلاع على واجهات برمجة التطبيقات الأصلية. يوضِّح المثال التالي بنية استخدام هذا المتغيّر:
ifeq ($(TARGET_PLATFORM),android-22)
# ... do something ...
endif
TARGET_ARCH_ABI
واجهة برمجة التطبيقات التي يستهدفها نظام التصميم أثناء تحليل ملف Android.mk
هذا.
يعرض الجدول 1 إعدادات ABI المُستخدَمة لكل وحدة معالجة مركزية (CPU) وبنية متوافقة.
وحدة المعالجة المركزية والبنية | الإعدادات |
---|---|
ARMv7 | armeabi-v7a |
ARMv8 AArch64 | arm64-v8a |
i686 | x86 |
X86- 64 | x86_64 |
يوضّح المثال التالي كيفية التحقق من ARMv8 AArch64 كالمزج المستهدف بين وحدة المعالجة المركزية (CPU) وواجهة التطبيق الثنائية (ABI):
ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
# ... do something ...
endif
لمعرفة مزيد من التفاصيل حول واجهات ABI للبنية ومشاكل التوافق المرتبطة بها، يُرجى الرجوع إلى واجهات التطبيق الثنائية (ABI) في Android.
سيكون لواجهات ABI المستهدَفة الجديدة في المستقبل قيم مختلفة.
الهدف_المستهدف
سلسلة من مستوى واجهة برمجة تطبيقات Android وABI المستهدَفَين وهي مفيدة بشكل خاص عند إجراء اختبار على صورة نظام مستهدَفة معيّنة لجهاز حقيقي. على سبيل المثال، للتحقّق من وجود جهاز ARM بسعة 64 بت يعمل بالمستوى 22 من واجهة برمجة تطبيقات Android:
ifeq ($(TARGET_ABI),android-22-arm64-v8a)
# ... do something ...
endif
متغيّرات وصف الوحدة
تصف المتغيرات الواردة في هذا القسم الوحدة الخاصة بك بنظام الإصدار. ينبغي أن يتبع كل وصف وحدة التدفق الأساسي هذا:
- يمكنك إعداد المتغيّرات المرتبطة بالوحدة أو إلغاء تحديدها باستخدام المتغيّر
CLEAR_VARS
. - عيّن قيمًا للمتغيرات المستخدمة لوصف الوحدة.
- اضبط نظام تصميم NDK على استخدام النص البرمجي المناسب للإصدار للوحدة النمطية، باستخدام المتغير
BUILD_XXX
.
المسار المحلي
يُستخدم هذا المتغير لتحديد مسار الملف الحالي. يجب تحديده في بداية ملف Android.mk
. يوضّح المثال التالي كيفية إجراء ذلك:
LOCAL_PATH := $(call my-dir)
لا يؤدي النص البرمجي الذي يشير إليه CLEAR_VARS
إلى محو هذا المتغيّر. لذلك، ما عليك سوى تحديدها مرة واحدة، حتى إذا كان ملف Android.mk
يصف وحدات متعددة.
LOCAL_MODULE
يُخزِّن هذا المتغيّر اسم وحدتك. ويجب أن تكون فريدة بين جميع أسماء الوحدات،
ويجب ألا تحتوي على أي مسافات. عليك تحديدها قبل تضمين أي نصوص برمجية (بخلاف النص البرمجي الخاص بـ CLEAR_VARS
). لا تحتاج إلى إضافة البادئة lib
أو امتداد الملف .so
أو .a
، لأنّ نظام التصميم يُجري هذه التعديلات تلقائيًا. في ملفات Android.mk
وApplication.mk
،
اطّلِع على الوحدة من خلال اسمها غير المعدّل. على سبيل المثال، يؤدي السطر التالي
إلى إنشاء وحدة مكتبة مشتركة باسم libfoo.so
:
LOCAL_MODULE := "foo"
إذا أردت أن يكون للوحدة التي تم إنشاؤها اسم غير lib
مع القيمة LOCAL_MODULE
، يمكنك استخدام المتغيّر LOCAL_MODULE_FILENAME
لإعطاء الوحدة التي تم إنشاؤها اسمًا من اختيارك.
LOCAL_MODULE_FILENAME
يتيح لك هذا المتغيّر الاختياري إلغاء الأسماء التي يستخدمها نظام التصميم تلقائيًا للملفات التي يُنشئها. على سبيل المثال، إذا كان اسم
LOCAL_MODULE
هو foo
، يمكنك إجبار النظام على استدعاء الملف الذي ينشئه
libnewfoo
. يوضّح المثال التالي كيفية تحقيق ذلك:
LOCAL_MODULE := foo
LOCAL_MODULE_FILENAME := libnewfoo
بالنسبة إلى وحدة مكتبة مشتركة، سيُنشئ هذا المثال ملفًا باسم
libnewfoo.so
.
LOCAL_SRC_FILES
يحتوي هذا المتغيّر على قائمة ملفات المصدر التي يستخدمها نظام الإنشاء ل
إنشاء الوحدة. لا تُدرِج سوى الملفات التي ينقلها نظام الإنشاء
فعليًا إلى المُجمِّع، لأنّ نظام الإنشاء يحسب تلقائيًا أي تبعيات مرتبطة
. يُرجى العلم أنّه يمكنك استخدام كلّ من المسارات النسبية (بالنسبة إلى LOCAL_PATH
) ومسارات الملفات المطلقة.
ننصحك بتجنُّب مسارات الملفات المطلقة، لأنّ المسارات النسبية تجعل ملف Android.mk
أكثر قابلية للنقل.
LOCAL_CPP_امتداد
يمكنك استخدام هذا المتغيّر الاختياري للإشارة إلى امتداد ملف غير
.cpp
لملفات المصدر بتنسيق C++. على سبيل المثال، يغيّر السطر التالي الإضافة إلى .cxx
. (يجب أن يتضمّن الإعداد النقطة).
LOCAL_CPP_EXTENSION := .cxx
ويمكنك استخدام هذا المتغيّر لتحديد إضافات متعدّدة. على سبيل المثال:
LOCAL_CPP_EXTENSION := .cxx .cpp .cc
LOCAL_CPP_FEATURES
يمكنك استخدام هذا المتغيّر الاختياري للإشارة إلى أنّ الرمز يعتمد على ميزات معيّنة
في C++. وهو يمكّن علامات برنامج التجميع والرابط الصحيحة أثناء عملية الإنشاء. بالنسبة إلى الملفات الثنائية المُنشأة مسبقًا، يوضّح هذا المتغيّر أيضًا الميزات التي يعتمد عليها الملف الثنائي، ما يساعد في ضمان عمل عملية الربط النهائية بشكلٍ صحيح. ننصحك
باستخدام هذا المتغيّر بدلاً من تفعيل -frtti
و
-fexceptions
مباشرةً في تعريف LOCAL_CPPFLAGS
.
يتيح استخدام هذا المتغيّر لنظام الإنشاء استخدام العلامات المناسبة
لكل وحدة. يؤدي استخدام LOCAL_CPPFLAGS
إلى استخدام المحول البرمجي لجميع العلامات المحددة لجميع الوحدات، بغض النظر عن الحاجة الفعلية.
على سبيل المثال، للإشارة إلى أن التعليمات البرمجية تستخدم RTTI (معلومات نوع وقت التشغيل)، اكتب:
LOCAL_CPP_FEATURES := rtti
للإشارة إلى أن التعليمات البرمجية تستخدم استثناءات C++، اكتب:
LOCAL_CPP_FEATURES := exceptions
يمكنك أيضًا تحديد قيم متعدّدة لهذا المتغيّر. مثلاً:
LOCAL_CPP_FEATURES := rtti features
ولا يهمّ الترتيب الذي تصف به القيم.
ما يلي:
يمكنك استخدام هذا المتغيّر الاختياري لتحديد قائمة بالمسارات، نسبةً إلى دليل NDK root
، وإضافتها إلى مسار بحث التضمين عند تجميع كل المصادر (C وC++ وAssembly). مثلاً:
LOCAL_C_INCLUDES := sources/foo
أو حتى:
LOCAL_C_INCLUDES := $(LOCAL_PATH)/<subdirectory>/foo
حدِّد هذا المتغيّر قبل ضبط أيّ علامات تضمين مقابلة من خلال
LOCAL_CFLAGS
أو LOCAL_CPPFLAGS
.
يستخدم نظام الإنشاء أيضًا مسارات LOCAL_C_INCLUDES
تلقائيًا عند بدء debugging native باستخدام ndk-gdb.
LOCAL_ASFLAGS
علامات سيتم تمريرها إلى Clang عند إنشاء ملفات .s
أو .S
.
LOCAL_ASMFLAGS
العلامات التي سيتم تمريرها إلى yasm عند إنشاء ملفات .asm
LOCAL_CFLAGS
علامات سيتم تمريرها إلى Clang عند إنشاء ملفات مصدر C وC++ وبعض ملفّات رمز assembly (.s
و.S
، ولكن ليس .asm
). يمكن أن تكون إمكانية إجراء ذلك مفيدة لتحديد تعريفات وحدات الماكرو أو خيارات الترجمة إضافية. يمكنك استخدام
LOCAL_CPPFLAGS
لتحديد علامات لـ C++ فقط. استخدِم LOCAL_CONLYFLAGS
لتحديد العلامات لفئة C فقط.
جرِّب عدم تغيير مستوى التحسين/تصحيح الأخطاء في ملف Android.mk
.
يمكن لنظام التصميم معالجة هذا الإعداد تلقائيًا نيابةً عنك، باستخدام
المعلومات ذات الصلة في ملف Application.mk
. ويسمح إجراء ذلك بهذه الطريقة لنظام الإنشاء بإنشاء ملفات بيانات مفيدة تُستخدَم أثناء تصحيح الأخطاء.
من الممكن تحديد مسارات تضمين إضافية عن طريق كتابة:
LOCAL_CFLAGS += -I<path>,
ومع ذلك، من الأفضل استخدام LOCAL_C_INCLUDES
لهذا الغرض، لأنّه
يُتيح أيضًا استخدام المسارات المتاحة لتصحيح الأخطاء الأصلي باستخدام
ndk-gdb.
LOCAL_CONLYFLAGS
العلامات التي سيتم تمريرها إلى Clang عند تجميع مصادر C على عكس
LOCAL_CFLAGS
، لن يتم تمرير LOCAL_CONLYFLAGS
إلى Clang عند تجميع
C++ أو مصادر التجميع.
LOCAL_CPPFLAGS
مجموعة اختيارية من علامات برنامج التحويل البرمجي التي سيتم تمريرها عند إنشاء ملفات مصدر C++ فقط. ستظهر بعد LOCAL_CFLAGS
في سطر تعليمات المُجمِّع. استخدِم LOCAL_CFLAGS
لتحديد العلامات لكل من C وC++.
LOCAL_STATIC_LIBRARIES
يخزِّن هذا المتغيّر قائمة وحدات المكتبات الثابتة التي تعتمد عليها الوحدت الحالية.
إذا كانت الوحدة الحالية مكتبة مشتركة أو ملف قابل للتنفيذ، سيؤدي هذا المتغيّر إلى فرض ربط هذه المكتبات بالملف الثنائي الناتج.
إذا كانت الوحدة الحالية هي مكتبة ثابتة، فإن هذا المتغير يشير ببساطة إلى أن الوحدات الأخرى اعتمادًا على الوحدة الحالية ستعتمد أيضًا على المكتبات المدرجة.
LOCAL_SHARED_LIBRARIES
هذا المتغيّر هو قائمة وحدات المكتبات المشتركة التي تعتمد عليها هذه الوحدة أثناء التشغيل. هذه المعلومات ضرورية في وقت الربط، ولإدراج المعلومات المقابلة في الملف الذي تم إنشاؤه.
LOCAL_WHOLE_STATIC_LIBRARIES
هذا المتغيّر هو أحد متغيرات LOCAL_STATIC_LIBRARIES
، ويوضّح أنّ الرابط يجب أن يتعامل مع وحدات المكتبة المرتبطة على أنّها أرشيفات كاملة. لمزيد من المعلومات حول الأرشيفات بالكامل، يُرجى الاطّلاع على مستندات GNU ld الخاصة بعلامة --whole-archive
.
يكون هذا المتغير مفيدًا عندما تكون هناك تبعيات دائرية بين العديد من المكتبات الثابتة. عند استخدام هذا المتغيّر لإنشاء مكتبة مشترَكة، سيؤدي ذلك إلى فرض نظام الإنشاء على إضافة جميع ملفات العناصر من مكتباتك الثابتة إلىملف الثنائي النهائي. ولكن، الأمر نفسه لا ينطبق عند إنشاء ملفات تنفيذية.
المحلية
يحتوي هذا المتغيّر على قائمة بعلامات الربط الإضافية لاستخدامها في إنشاء مكتبتك المشترَكة أو الملف القابل للتنفيذ. ويتيح لك استخدام البادئة -l
لتمرير اسم مكتبات نظام معيّنة. على سبيل المثال، يطلب المثال التالي من الرابط إنشاء وحدة مرتبطة بالعنوان /system/lib/libz.so
في وقت التحميل:
LOCAL_LDLIBS := -lz
للاطّلاع على قائمة مكتبات النظام المعروضة التي يمكنك الربط بها في إصدار NDK هذا، يُرجى الاطّلاع على واجهات برمجة التطبيقات الأصلية.
LOCAL_LDFLAGS
تمثّل هذه السمة قائمة علامات الروابط الأخرى الخاصة بنظام الإصدار لاستخدامها عند إنشاء مكتبتك المشتركة أو إنشاء مكتبة قابلة للتنفيذ. على سبيل المثال، لاستخدام رابط ld.bfd
على
ARM/X86:
LOCAL_LDFLAGS += -fuse-ld=bfd
LOCAL_ALLOW_UNDEFINED_SYMBOLS
عندما يواجه نظام الإصدار مرجعًا غير معروف أثناء محاولة إنشاء مرجع مشترك، سيظهر الخطأ رمز غير محدّد. يمكن أن يساعدك هذا الخطأ في رصد الأخطاء في رمز المصدر.
لإيقاف هذا التحقّق، اضبط هذا المتغيّر على true
. يُرجى العِلم أنّ هذا الإعداد قد يؤدي إلىتحميل المكتبة المشتركة أثناء التشغيل.
LOCAL_ARM_MODE
ينشئ نظام الإنشاء تلقائيًا ملفات ثنائية لأجهزة ARM المستهدَفة في وضع thumb،
حيث يكون طول كل تعليمات 16 بت ويتم ربطها بمكتبات STL في الدليل
thumb/
. يجبر نظام التصميم عند تحديد هذا المتغيّر على أنّه arm
على إنشاء ملفات عناصر الوحدة في وضع arm
32 بت. يوضّح المثال التالي كيفية إجراء ذلك:
LOCAL_ARM_MODE := arm
يمكنك أيضًا توجيه نظام التصميم لإنشاء مصادر محدّدة فقط في وضع arm
من خلال إلحاق اللاحقة .arm
بأسماء الملفات المصدر. على سبيل المثال، يطلب
المثال التالي من نظام الإنشاء تجميع bar.c
دائمًا في وضع ARM،
ولكنه يطلب إنشاء foo.c
وفقًا لقيمة LOCAL_ARM_MODE
.
LOCAL_SRC_FILES := foo.c bar.c.arm
LOCAL_ARM_NEON
لا يهمّ هذا المتغيّر إلا عند استهداف ABI armeabi-v7a
. ويسمح
باستخدام وظائف المخطِّط الأساسية لوحدة معالجة البيانات المتسلسلة المحسَّنة (NEON) من ARM في ملفّات برمجة C وC++، بالإضافة إلى تعليمات NEON في ملفات الترميز.
يُرجى العلم أنّ بعض وحدات المعالجة المركزية المستندة إلى ARMv7 لا تتوافق مع إضافات مجموعة تعليمات NEON. ولهذا السبب، يجب رصد بيئة التشغيل لتتمكّن من استخدام هذا الرمز بأمان أثناء وقت التشغيل. لمزيد من المعلومات، يمكنك الاطّلاع على التوافق مع النيون وميزات وحدة المعالجة المركزية (CPU).
بدلاً من ذلك، يمكنك استخدام اللاحقة .neon
للإشارة إلى أنّ نظام التصميم لا يجمع سوى ملفات مصدر محدَّدة مع دعم NEON. في المثال التالي، يجمع نظام التصميم foo.c
مع دعم الإبهام والنيون، وbar.c
مع دعم الضغط، وzoo.c
مع دعم ARM وNEON:
LOCAL_SRC_FILES = foo.c.neon bar.c zoo.c.arm.neon
في حال استخدام كلتا اللاحقتَين، يجب أن يسبق .arm
.neon
.
LOCAL_DISABLE_FORMAT_STRING_CHECKS
يُنشئ نظام الإنشاء الرمز البرمجي تلقائيًا مع حماية سلسلة التنسيق. يؤدي ذلك
إلى فرض خطأ في برنامج التحويل البرمجي في حال استخدام سلسلة تنسيق غير ثابتة في
دالة نمط 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)
هنا، يمرر نظام التصميم العلامتين -DFOO=1
و-DBAR=2
إلى المحول البرمجي عند إنشاء bar.c
. وهي تضيف العلامات التي تمّ تصديرها في LOCAL_CFLAGS
إلى الوحدة
الخاصة بك لتتمكّن من تجاوزها بسهولة.
بالإضافة إلى ذلك، تكون العلاقة بين الوحدات تبادلية: إذا كانت zoo
تعتمد على
bar
، والتي تعتمد بدورها على foo
، سترث zoo
أيضًا جميع العلامات
المصدَّرة من foo
.
أخيرًا، لا يستخدم نظام الإنشاء العلامات التي تم تصديرها عند الإنشاء على الجهاز فقط
(أي إنشاء الوحدة التي يتم تصدير علاماتها). وبالتالي، في المثال
أعلاه، لا يتم تمرير -DFOO=1
إلى المُجمِّع عند إنشاء foo/foo.c
. لبدء عملية
الإنشاء على الجهاز، استخدِم LOCAL_CFLAGS
بدلاً من ذلك.
LOCAL_EXPORT_CPPFLAGS
هذا المتغيّر هو نفسه LOCAL_EXPORT_CFLAGS
، ولكن لعلامات C++ فقط.
LOCAL_EXPORT_C_INCLUDES
هذا المتغير مماثل لـ LOCAL_EXPORT_CFLAGS
، ولكن لـ C تضمين المسارات. وهو مفيد في الحالات التي تحتاج فيها، على سبيل المثال، إلى تضمين عناوين من الوحدة foo
bar.c
.
LOCAL_EXPORT_LDFLAGS
هذا المتغيّر مماثل لـ LOCAL_EXPORT_CFLAGS
، ولكن بالنسبة لعلامات الربط.
LOCAL_EXPORT_LDLIBS
هذا المتغيّر هو نفسه LOCAL_EXPORT_CFLAGS
، ويطلب من نظام الإنشاء
تمرير أسماء مكتبات نظام معيّنة إلى المُجمِّع. أضِف -l
إلى اسم كل مكتبة تختارها
يُرجى العلم أنّ نظام الإنشاء يُلحق علامات الربط المستورَدة بقيمة المتغيّر 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)
في هذا المثال، يضع نظام التصميم -llog
في نهاية أمر الربط
عند إنشاء libbar.so
. ويؤدي ذلك إلى إعلام القائم بالرابط بأنّ libbar.so
يعتمد على foo
، وبالتالي يعتمد أيضًا على مكتبة تسجيل النظام.
الأوامر_المحلية
اضبط هذا المتغيّر على true
عندما تحتوي الوحدة على عدد كبير جدًا من المصادر و/أو المكتبات الثابتة أو المشتركة التابعة. يؤدي ذلك إلى إجبار نظام التصميم على استخدام بنية @
للأرشيفات التي تحتوي على ملفات كائنات وسيطة أو ربط المكتبات.
يمكن أن تكون هذه الميزة مفيدة على نظام التشغيل Windows، حيث يقبل سطر الأوامر 8191 حرفًا فقط كحد أقصى، والتي قد تكون صغيرة جدًا بحيث لا يمكن استخدامها في المشاريع المعقدة. ويؤثر ذلك أيضًا في compiling compilation of individual source files، ويضع تقريبًا جميع علامات compiler داخل ملفات القوائم أيضًا.
يُرجى العِلم أنّ أي قيمة غير true
ستؤدي إلى إعادة السلوك التلقائي. يمكنك
أيضًا تحديد APP_SHORT_COMMANDS
في ملف Application.mk
لفرض
هذا السلوك على جميع الوحدات في مشروعك.
لا ننصح بتفعيل هذه الميزة تلقائيًا، لأنّها تجعل الإصدار أبطأ.
LOCAL_THIN_ARCHIVE
اضبط هذا المتغيّر على true
عند إنشاء مكتبات ثابتة. سيؤدي ذلك إلى إنشاء أرشيف رفيع، وهو ملف مكتبة لا يحتوي على ملفات كائنات، بل سيؤدي بدلاً من ذلك إلى إنشاء مسارات ملفات إلى الكائنات الفعلية التي تحتوي عليها عادةً.
يكون ذلك مفيدًا لتقليل حجم الناتج من عملية الإنشاء. والعيوب هو أنّه لا يمكن نقل هذه المكتبات إلى مكان مختلف (تكون جميع المسارات داخلها نسبية).
القيم الصالحة هي true
أو false
أو فارغة. يمكن ضبط قيمة تلقائية في ملف
Application.mk
من خلال المتغيّر APP_THIN_ARCHIVE
.
LOCAL_FILTER_ASM
حدِّد هذا المتغيّر كأمر shell سيستخدمه نظام الإنشاء لفلترة
ملفات التجميع المستخرَجة أو التي تم إنشاؤها من الملفات التي حدّدتها لملف
LOCAL_SRC_FILES
. يؤدي تحديد هذا المتغيّر إلى حدوث ما يلي:
- يُنشئ نظام التصميم ملف تجميع مؤقت من أي ملف مصدر C أو C++ ، بدلاً من تجميعها في ملف كائن.
- ينفِّذ نظام الإصدار أمر Shell في
LOCAL_FILTER_ASM
على أي ملف تجميع مؤقت وعلى أي ملف تجميع مدرج فيLOCAL_SRC_FILES
، وبالتالي إنشاء ملف تجميع مؤقت آخر. - يُجمِّع نظام الإنشاء ملفات التجميع هذه التي تمّت فلترتها في ملف رمز.
مثلاً:
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>)
لتقييمها، فهي تعرض معلومات نصية.
أمري
يعرض هذا الماكرو مسار آخر ملف make مضمّن، والذي يكون عادةً هو
دليل Android.mk
الحالي. تكون السمة my-dir
مفيدة لتحديد
LOCAL_PATH
في بداية ملف Android.mk
. مثلاً:
LOCAL_PATH := $(call my-dir)
بسبب طريقة عمل GNU Make، ما تعرضه وحدة الماكرو هذه في الواقع هو مسار ملف makefile الأخير الذي أدرجه نظام الإنشاء عند تحليل النصوص البرمجية للإنشاء. لهذا السبب، يجب عدم استدعاء 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
all-subdir-makefiles
عرض قائمة ملفات Android.mk
المتوفّرة في جميع الأدلة الفرعية لمسارmy-dir
الحالي
يمكنك استخدام هذه الدالة لتوفير تسلسلات هرمية لدليل المصدر ومدمجة بشكل عميق لنظام التصميم. يبحث NDK تلقائيًا عن الملفات في الدليل الذي يحتوي على ملف Android.mk
فقط.
this-makefile
تعرض مسار ملف Makefile الحالي (الذي من خلاله يسمى نظام الإصدار الدالة).
parent-makefile
تعرض مسار ملف makefile الرئيسي في شجرة التضمين (مسار ملف makefile الذي يتضمن الملف الحالي).
grand-parent-makefile
عرض مسار ملف makefile للجد في شجرة التضمين (مسارملف makefile الذي يتضمّن الملف الحالي)
import-module
يشير ذلك المصطلح إلى دالة تتيح لك العثور على ملف Android.mk
الخاص بالوحدة وتضمينه باستخدام اسم الوحدة. وفي ما يلي مثال نموذجي:
$(call import-module,<name>)
في هذا المثال، يبحث نظام التصميم عن الوحدة التي تم وضع علامة <name>
عليها في قائمة الأدلة المُشار إليها في متغيّرات بيئة NDK_MODULE_PATH
، ويتضمّن ملف Android.mk
تلقائيًا بالنيابة عنك.