Android.mk

این صفحه نحو فایل ساخت Android.mk مورد استفاده توسط ndk-build را شرح می دهد.

نمای کلی

فایل Android.mk در یک زیر شاخه از فهرست jni/ پروژه شما قرار دارد و منابع و کتابخانه های مشترک شما را برای سیستم ساخت توصیف می کند. این در واقع یک قطعه کوچک فایل ساخت گنو است که سیستم ساخت یک یا چند بار آن را تجزیه می کند. فایل Android.mk برای تعریف تنظیمات کل پروژه که Application.mk ، سیستم ساخت و متغیرهای محیط شما تعریف نشده باقی می‌گذارند مفید است. همچنین می‌تواند تنظیمات کل پروژه را برای ماژول‌های خاص لغو کند.

سینتکس Android.mk به شما امکان می دهد منابع خود را در ماژول ها گروه بندی کنید. یک ماژول یا یک کتابخانه استاتیک، یک کتابخانه مشترک یا یک فایل اجرایی مستقل است. شما می توانید در هر فایل Android.mk یک یا چند ماژول تعریف کنید و می توانید از همان فایل منبع در چندین ماژول استفاده کنید. سیستم ساخت تنها کتابخانه های مشترک را در بسته برنامه شما قرار می دهد. علاوه بر این، کتابخانه های ایستا می توانند کتابخانه های مشترک ایجاد کنند.

علاوه بر کتابخانه های بسته بندی، سیستم ساخت انواع جزئیات دیگر را برای شما مدیریت می کند. برای مثال، نیازی نیست فایل‌های هدر یا وابستگی‌های صریح بین فایل‌های تولید شده را در فایل Android.mk فهرست کنید. سیستم ساخت NDK این روابط را به طور خودکار برای شما محاسبه می کند. در نتیجه، باید بتوانید بدون نیاز به دست زدن به فایل Android.mk خود، از پشتیبانی زنجیره ابزار/پلتفرم جدید در نسخه های آینده NDK بهره مند شوید.

سینتکس این فایل بسیار نزدیک به آن است که در فایل های Android.mk توزیع شده با پروژه کامل متن باز اندروید استفاده می شود. در حالی که پیاده سازی سیستم ساخت که از آنها استفاده می کند متفاوت است، شباهت آنها یک تصمیم طراحی عمدی است که هدف آن تسهیل استفاده مجدد از کد منبع برای کتابخانه های خارجی برای توسعه دهندگان برنامه است.

مبانی

قبل از بررسی جزئیات نحو، مفید است که با درک اصول اولیه فایل 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 به یک Makefile ویژه GNU اشاره می کند که بسیاری از متغیرهای LOCAL_XXX مانند LOCAL_MODULE ، LOCAL_SRC_FILES و LOCAL_STATIC_LIBRARIES را برای شما پاک می کند. توجه داشته باشید که LOCAL_PATH پاک نمی شود. این متغیر باید مقدار خود را حفظ کند زیرا سیستم تمام فایل‌های کنترل ساخت را در یک زمینه اجرای GNU Make تجزیه می‌کند که در آن همه متغیرها سراسری هستند. قبل از توصیف هر ماژول باید این متغیر را مجدداً اعلام کنید.

سپس، متغیر 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 به یک اسکریپت Makefile GNU اشاره include که تمام اطلاعاتی را که در LOCAL_XXX تعریف کرده‌اید جمع‌آوری می‌کند. این اسکریپت تعیین می کند که چه چیزی بسازیم، و چگونه آن را انجام دهیم.

نمونه های پیچیده تری در دایرکتوری های نمونه با فایل های Android.mk کامنت شده وجود دارد که می توانید به آنها نگاه کنید. علاوه بر این، Sample: native-activity توضیح مفصلی از فایل Android.mk آن نمونه ارائه می دهد. در نهایت، متغیرها و ماکروها اطلاعات بیشتری در مورد متغیرها از این بخش ارائه می دهند.

متغیرها و ماکروها

سیستم ساخت بسیاری از متغیرهای ممکن را برای استفاده در فایل Android.mk فراهم می کند. بسیاری از این متغیرها دارای مقادیر از پیش تعیین شده هستند. دیگران، شما تعیین می کنید.

علاوه بر این متغیرها، می توانید متغیرهای دلخواه خود را نیز تعریف کنید. در صورت انجام این کار، به خاطر داشته باشید که سیستم ساخت NDK نام متغیرهای زیر را ذخیره می کند:

  • نام هایی که با LOCAL_ شروع می شوند، مانند LOCAL_MODULE .
  • نام هایی که با PRIVATE_ ، NDK_ یا APP شروع می شوند. سیستم ساخت از اینها به صورت داخلی استفاده می کند.
  • اسامی با حروف کوچک، مانند my-dir . سیستم ساخت از اینها به صورت داخلی نیز استفاده می کند.

اگر می خواهید متغیرهای راحتی خود را در یک فایل Android.mk تعریف کنید، توصیه می کنیم MY_ به نام آنها اضافه کنید.

NDK-تعریف شده شامل متغیرها است

این بخش در مورد متغیرهای GNU Make صحبت می کند که سیستم ساخت قبل از تجزیه فایل Android.mk شما تعریف می کند. تحت شرایط خاصی، NDK ممکن است فایل Android.mk شما را چندین بار تجزیه کند و هر بار از تعریف متفاوتی برای برخی از این متغیرها استفاده کند.

CLEAR_VARS

این متغیر به یک اسکریپت ساخت اشاره می‌کند که تقریباً همه متغیرهای LOCAL_XXX فهرست‌شده در بخش «متغیرهای تعریف‌شده توسط برنامه‌نویس» را در زیر تعریف نمی‌کند. از این متغیر برای گنجاندن این اسکریپت قبل از توصیف یک ماژول جدید استفاده کنید. نحو استفاده از آن عبارت است از:

include $(CLEAR_VARS)

BUILD_EXECUTABLE

این متغیر به یک اسکریپت ساخت اشاره می کند که تمام اطلاعات مربوط به ماژولی را که در متغیرهای LOCAL_XXX خود ارائه کرده اید جمع آوری می کند و نحوه ساخت یک فایل اجرایی هدف را از منابعی که فهرست کرده اید تعیین می کند. توجه داشته باشید که استفاده از این اسکریپت مستلزم آن است که از قبل مقادیری را حداقل به LOCAL_MODULE و LOCAL_SRC_FILES اختصاص داده باشید (برای اطلاعات بیشتر در مورد این متغیرها، به متغیرهای توضیح ماژول مراجعه کنید).

نحو استفاده از این متغیر به صورت زیر است:

include $(BUILD_EXECUTABLE)

BUILD_SHARED_LIBRARY

این متغیر به یک اسکریپت ساخت اشاره می‌کند که تمام اطلاعات مربوط به ماژولی را که در متغیرهای LOCAL_XXX خود ارائه کرده‌اید جمع‌آوری می‌کند و نحوه ساخت یک کتابخانه مشترک هدف را از منابعی که فهرست کرده‌اید تعیین می‌کند. توجه داشته باشید که استفاده از این اسکریپت مستلزم آن است که از قبل مقادیری را حداقل به LOCAL_MODULE و LOCAL_SRC_FILES اختصاص داده باشید (برای اطلاعات بیشتر در مورد این متغیرها، به متغیرهای توضیح ماژول مراجعه کنید).

نحو استفاده از این متغیر به صورت زیر است:

include $(BUILD_SHARED_LIBRARY)

یک متغیر shared-library باعث می شود که سیستم ساخت یک فایل کتابخانه با پسوند .so تولید کند.

BUILD_STATIC_LIBRARY

گونه ای از BUILD_SHARED_LIBRARY که برای ساخت یک کتابخانه ثابت استفاده می شود. سیستم ساخت، کتابخانه‌های استاتیک را در پروژه/بسته‌های شما کپی نمی‌کند، اما می‌تواند از آنها برای ساخت کتابخانه‌های مشترک استفاده کند (به LOCAL_STATIC_LIBRARIES و LOCAL_WHOLE_STATIC_LIBRARIES ، در زیر مراجعه کنید). نحو استفاده از این متغیر به صورت زیر است:

include $(BUILD_STATIC_LIBRARY)

یک متغیر 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

خانواده CPU که سیستم ساخت آن را هدف قرار می دهد، زیرا این فایل Android.mk را تجزیه می کند. این متغیر یکی از موارد زیر خواهد بود: arm ، arm64 ، x86 ، یا x86_64 .

TARGET_PLATFORM

شماره سطح Android API که سیستم ساخت آن را هدف قرار می دهد، زیرا این فایل Android.mk را تجزیه می کند. به عنوان مثال، تصاویر سیستم Android 5.1 مطابق با Android API سطح 22: android-22 . برای فهرست کاملی از نام‌های پلتفرم و تصاویر مربوط به سیستم Android، به Native API مراجعه کنید. مثال زیر نحو استفاده از این متغیر را نشان می دهد:

ifeq ($(TARGET_PLATFORM),android-22)
    # ... do something ...
endif

TARGET_ARCH_ABI

سیستم ساخت ABI هنگام تجزیه این فایل Android.mk هدف قرار می دهد. جدول 1 تنظیمات ABI مورد استفاده برای هر CPU و معماری پشتیبانی شده را نشان می دهد.

جدول 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 های هدف جدید در آینده مقادیر متفاوتی خواهند داشت.

TARGET_ABI

ترکیبی از سطح API هدف Android و ABI. این به ویژه زمانی مفید است که می خواهید در برابر یک تصویر سیستم هدف خاص برای یک دستگاه واقعی آزمایش کنید. به عنوان مثال، برای بررسی یک دستگاه ARM 64 بیتی که روی Android API سطح 22 اجرا می شود:

ifeq ($(TARGET_ABI),android-22-arm64-v8a)
  # ... do something ...
endif

متغیرهای توصیف ماژول

متغیرهای این بخش ماژول شما را برای سیستم ساخت توصیف می کنند. هر توضیح ماژول باید این جریان اصلی را دنبال کند:

  1. با استفاده از متغیر CLEAR_VARS ، متغیرهای مرتبط با ماژول را مقداردهی اولیه کنید یا تعریف نکنید.
  2. مقادیری را به متغیرهای مورد استفاده برای توصیف ماژول اختصاص دهید.
  3. با استفاده از متغیر BUILD_XXX ، سیستم ساخت NDK را طوری تنظیم کنید که از اسکریپت ساخت مناسب برای ماژول استفاده کند.

LOCAL_PATH

این متغیر برای نشان دادن مسیر فایل فعلی استفاده می شود. شما باید آن را در ابتدای فایل 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_EXTENSION

می توانید از این متغیر اختیاری برای نشان دادن پسوند فایلی غیر از .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

ترتیبی که شما مقادیر را توصیف می کنید مهم نیست.

LOCAL_C_INCLUDES

می‌توانید از این متغیر اختیاری برای تعیین فهرستی از مسیرها، نسبت به دایرکتوری root NDK، برای افزودن به مسیر جستجوی شامل هنگام کامپایل کردن همه منابع (C، C++ و Assembly) استفاده کنید. به عنوان مثال:

LOCAL_C_INCLUDES := sources/foo

یا حتی:

LOCAL_C_INCLUDES := $(LOCAL_PATH)/<subdirectory>/foo

این متغیر را قبل از تنظیم هر پرچم گنجاندن مربوطه از طریق LOCAL_CFLAGS یا LOCAL_CPPFLAGS تعریف کنید.

سیستم ساخت همچنین از مسیرهای LOCAL_C_INCLUDES به طور خودکار هنگام راه‌اندازی اشکال‌زدایی بومی با ndk-gdb استفاده می‌کند.

LOCAL_ASFLAGS

پرچم هایی که هنگام ساخت فایل های .s یا .S به Clang منتقل می شوند.

LOCAL_ASMFLAGS

پرچم هایی که هنگام ساخت فایل های .asm به yasm منتقل می شوند.

LOCAL_CFLAGS

پرچم هایی که هنگام ساختن فایل های منبع C، C++ و برخی اسمبلی ( .s و .S ، اما نه .asm ) به Clang منتقل می شوند. توانایی انجام این کار می تواند برای تعیین تعاریف ماکرو اضافی یا گزینه های کامپایل مفید باشد. از LOCAL_CPPFLAGS برای مشخص کردن پرچم‌ها فقط برای C++ استفاده کنید. از LOCAL_CONLYFLAGS برای تعیین پرچم فقط برای C استفاده کنید.

سعی کنید سطح بهینه سازی/اشکال زدایی را در فایل Android.mk خود تغییر ندهید. سیستم ساخت با استفاده از اطلاعات مربوطه در فایل Application.mk می تواند این تنظیمات را به صورت خودکار برای شما انجام دهد. انجام این کار به سیستم ساخت اجازه می دهد تا فایل های داده مفیدی را که در حین اشکال زدایی استفاده می شود تولید کند.

می توان مسیرهای شامل اضافی را با نوشتن مشخص کرد:

LOCAL_CFLAGS += -I<path>,

با این حال، بهتر است از LOCAL_C_INCLUDES برای این منظور استفاده کنید، زیرا انجام این کار امکان استفاده از مسیرهای موجود برای اشکال زدایی بومی با ndk-gdb را نیز فراهم می کند.

LOCAL_CONLYFLAGS

پرچم هایی که هنگام کامپایل منابع C به Clang منتقل می شوند. برخلاف LOCAL_CFLAGS ، LOCAL_CONLYFLAGS هنگام کامپایل C++ یا منابع اسمبلی به Clang منتقل نمی‌شود.

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 مراجعه کنید.

این متغیر زمانی مفید است که وابستگی های دایره ای در بین چندین کتابخانه ایستا وجود داشته باشد. هنگامی که از این متغیر برای ساخت یک کتابخانه مشترک استفاده می کنید، سیستم ساخت را مجبور می کند تا تمام فایل های شی از کتابخانه های استاتیک شما را به باینری نهایی اضافه کند. با این حال، هنگام تولید فایل های اجرایی، این موضوع صادق نیست.

LOCAL_LDLIBS

این متغیر حاوی لیستی از پرچم های پیوند دهنده اضافی برای استفاده در ساخت کتابخانه مشترک یا فایل اجرایی شما است. این به شما امکان می دهد از پیشوند -l برای ارسال نام کتابخانه های سیستمی خاص استفاده کنید. به عنوان مثال، مثال زیر به لینک دهنده می گوید که ماژولی ایجاد کند که در زمان بارگذاری به /system/lib/libz.so پیوند می دهد:

LOCAL_LDLIBS := -lz

برای فهرست کتابخانه‌های سیستمی که می‌توانید در این نسخه NDK پیوند برقرار کنید، به Native API مراجعه کنید.

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

این متغیر فقط زمانی اهمیت دارد که armeabi-v7a ABI را هدف قرار دهید. این اجازه می دهد تا از ذاتی کامپایلر ARM Advanced SIMD (NEON) در منابع C و C++ و همچنین دستورالعمل های NEON در فایل های Assembly استفاده کنید.

توجه داشته باشید که همه CPU های مبتنی بر 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 -style استفاده شود، انجام این کار باعث ایجاد خطای کامپایلر می شود. این حفاظت به طور پیش‌فرض روشن است، اما می‌توانید با تنظیم مقدار این متغیر روی 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 را به ارث می‌برد.

در نهایت، سیستم ساخت هنگام ساخت محلی (یعنی ساخت ماژولی که پرچم‌های آن را صادر می‌کند) از پرچم‌های صادراتی استفاده نمی‌کند. بنابراین، در مثال بالا، هنگام ساخت foo/foo.c -DFOO=1 به کامپایلر ارسال نمی کند. برای ساخت محلی، به جای آن از LOCAL_CFLAGS استفاده کنید.

LOCAL_EXPORT_CPPFLAGS

این متغیر مانند LOCAL_EXPORT_CFLAGS است، اما فقط برای پرچم‌های C++.

LOCAL_EXPORT_C_INCLUDES

این متغیر مانند LOCAL_EXPORT_CFLAGS است، اما برای C شامل مسیرها می شود. در مواردی مفید است که، برای مثال، bar.c نیاز به اضافه کردن هدرها از module foo دارد.

LOCAL_EXPORT_LDFLAGS

این متغیر همان LOCAL_EXPORT_CFLAGS است، اما برای پرچم‌های پیوند دهنده.

LOCAL_EXPORT_LDLIBS

این متغیر همان LOCAL_EXPORT_CFLAGS است که به سیستم ساخت می‌گوید نام کتابخانه‌های سیستم خاص را به کامپایلر ارسال کند. -l به نام هر کتابخانه ای که مشخص می کنید اضافه کنید.

توجه داشته باشید که سیستم ساخت پرچم های پیوند دهنده وارد شده را به مقدار متغیر LOCAL_LDLIBS ماژول شما اضافه می کند. این کار را به دلیل نحوه کار لینکرهای یونیکس انجام می دهد.

این متغیر معمولاً زمانی مفید است که module foo یک کتابخانه ثابت است و دارای کدی است که به کتابخانه سیستم بستگی دارد. سپس می توانید از LOCAL_EXPORT_LDLIBS to برای صادر کردن وابستگی استفاده کنید. به عنوان مثال:

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 تنظیم کنید. انجام این کار سیستم ساخت را مجبور می کند تا از دستور @ برای آرشیوهای حاوی فایل های شی میانی یا کتابخانه های پیوند دهنده استفاده کند.

این ویژگی می تواند در ویندوز مفید باشد، جایی که خط فرمان حداکثر 8191 کاراکتر را می پذیرد که برای پروژه های پیچیده می تواند بسیار کوچک باشد. همچنین بر کامپایل کردن فایل‌های منبع فردی تأثیر می‌گذارد و تقریباً همه پرچم‌های کامپایلر را در فایل‌های فهرست نیز قرار می‌دهد.

توجه داشته باشید که هر مقداری غیر از true به رفتار پیش‌فرض برمی‌گردد. همچنین می‌توانید APP_SHORT_COMMANDS در فایل Application.mk خود تعریف کنید تا این رفتار را برای همه ماژول‌های پروژه خود مجبور کنید.

ما توصیه نمی کنیم که این ویژگی را به طور پیش فرض فعال کنید، زیرا ساخت را کندتر می کند.

LOCAL_THIN_ARCHIVE

هنگام ساخت کتابخانه های ایستا، این متغیر را روی true تنظیم کنید. با انجام این کار، یک بایگانی نازک ایجاد می‌شود، یک فایل کتابخانه‌ای که حاوی فایل‌های شی نیست، بلکه فقط مسیرهایی را به سمت اشیاء واقعی که معمولاً شامل می‌شود، فایل می‌کند.

این برای کاهش اندازه خروجی ساخت شما مفید است. اشکال این است که چنین کتابخانه هایی را نمی توان به مکان دیگری منتقل کرد (همه مسیرهای داخل آنها نسبی هستند).

مقادیر معتبر true ، false یا خالی هستند. یک مقدار پیش فرض را می توان در فایل Application.mk از طریق متغیر APP_THIN_ARCHIVE تنظیم کرد.

LOCAL_FILTER_ASM

این متغیر را به‌عنوان یک فرمان پوسته تعریف کنید که سیستم ساخت برای فیلتر کردن فایل‌های اسمبلی استخراج‌شده یا تولید شده از فایل‌هایی که برای LOCAL_SRC_FILES تعیین کرده‌اید، استفاده می‌کند. تعریف این متغیر باعث بروز موارد زیر می شود:

  1. سیستم ساخت، به جای کامپایل کردن آنها در یک فایل شی، یک فایل اسمبلی موقت از هر فایل منبع C یا C++ تولید می کند.
  2. سیستم ساخت، فرمان پوسته را در LOCAL_FILTER_ASM روی هر فایل اسمبلی موقت و هر فایل اسمبلی فهرست شده در LOCAL_SRC_FILES اجرا می‌کند، بنابراین فایل اسمبلی موقت دیگری تولید می‌کند.
  3. سیستم ساخت این فایل های اسمبلی فیلتر شده را در یک فایل شی کامپایل می کند.

به عنوان مثال:

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>) برای ارزیابی آنها استفاده کنید. آنها اطلاعات متنی را برمی گردانند.

کارگردان من

این ماکرو مسیر آخرین فایل ایجاد شده را برمی‌گرداند که معمولاً فهرست راهنمای Android.mk فعلی است. my-dir برای تعریف LOCAL_PATH در ابتدای فایل Android.mk شما مفید است. به عنوان مثال:

LOCAL_PATH := $(call my-dir)

با توجه به نحوه کار گنو Make، چیزی که این ماکرو واقعاً برمی گرداند، مسیر آخرین فایل میک است که سیستم ساخت هنگام تجزیه اسکریپت های ساخت گنجانده شده است. به همین دلیل، پس از قرار دادن فایل دیگری، نباید با 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 $PATH/foo تعریف می‌کند، زیرا این همان جایی بود که جدیدترین شامل آن اشاره کرد.

شما می توانید با قرار دادن شامل های اضافی پس از هر چیز دیگری در فایل 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 می‌گردد.

این-میک فایل

مسیر makefile فعلی (که سیستم ساخت از آن تابع نامیده می شود) را برمی گرداند.

والد-میک فایل

مسیر فایل makefil والد را در درخت گنجاندن (مسیر فایل make که شامل فایل فعلی است) برمی گرداند.

والدین بزرگ

مسیر makefile پدربزرگ و مادربزرگ را در درخت گنجاندن (مسیر makefile که شامل فایل فعلی می‌شود) برمی‌گرداند.

ماژول واردات

تابعی که به شما امکان می دهد فایل Android.mk یک ماژول را با نام ماژول پیدا و اضافه کنید. یک مثال معمولی به شرح زیر است:

$(call import-module,<name>)

در این مثال، سیستم ساخت به دنبال ماژولی با برچسب <name> در لیست دایرکتوری‌های ارجاع شده به متغیر محیطی NDK_MODULE_PATH شما می‌گردد و فایل Android.mk آن را به‌طور خودکار برای شما شامل می‌شود.