این صفحه نحو فایل ساخت 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 و معماری پشتیبانی شده را نشان می دهد.
پردازنده و معماری | تنظیم |
---|---|
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
متغیرهای توصیف ماژول
متغیرهای این بخش ماژول شما را برای سیستم ساخت توصیف می کنند. هر توضیح ماژول باید این جریان اصلی را دنبال کند:
- با استفاده از متغیر
CLEAR_VARS
، متغیرهای مرتبط با ماژول را مقداردهی اولیه کنید یا تعریف نکنید. - مقادیری را به متغیرهای مورد استفاده برای توصیف ماژول اختصاص دهید.
- با استفاده از متغیر
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
تعیین کردهاید، استفاده میکند. تعریف این متغیر باعث بروز موارد زیر می شود:
- سیستم ساخت، به جای کامپایل کردن آنها در یک فایل شی، یک فایل اسمبلی موقت از هر فایل منبع C یا C++ تولید می کند.
- سیستم ساخت، فرمان پوسته را در
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>)
برای ارزیابی آنها استفاده کنید. آنها اطلاعات متنی را برمی گردانند.
کارگردان من
این ماکرو مسیر آخرین فایل ایجاد شده را برمیگرداند که معمولاً فهرست راهنمای 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
آن را بهطور خودکار برای شما شامل میشود.