اگر از CMake یا ndk-build استفاده نمیکنید، اما میخواهید پلاگین Android Gradle (AGP) C/C++ و Android Studio یکپارچهسازی شود، میتوانید با ساخت یک اسکریپت پوسته که اطلاعات ساخت را در آن مینویسد، یک سیستم ساخت سفارشی C/C++ ایجاد کنید. فرمت فایل ساخت Ninja
پشتیبانی آزمایشی از سیستمهای ساخت C/C++ سفارشی به Android Studio و AGP اضافه شده است. این ویژگی با شروع در Android Studio Dolphin | در دسترس است 2021.3.1 قناری 4.
نمای کلی
یک الگوی رایج برای پروژههای C/C++، بهویژه آنهایی که چندین پلتفرم را هدف قرار میدهند، تولید پروژهها برای هر یک از آن پلتفرمها از برخی نمایندگیهای اساسی است. نمونه بارز این الگو CMake است. CMake میتواند پروژههایی را برای Android، iOS و دیگر پلتفرمها از یک نمایش زیربنایی، ذخیره شده در فایل CMakeLists.txt
ایجاد کند.
در حالی که CMake مستقیماً توسط AGP پشتیبانی می شود، تولیدکنندگان پروژه دیگری نیز در دسترس هستند که مستقیماً پشتیبانی نمی شوند:
این نوع از مولدهای پروژه یا از Ninja به عنوان یک نمایش پشتیبان ساخت C/C++ پشتیبانی می کنند یا می توانند برای تولید Ninja به عنوان یک نمایش باطنی سازگار شوند.
هنگامی که به درستی پیکربندی شود، یک پروژه AGP با یک مولد سیستم پروژه C/C++ یکپارچه، کاربران را قادر میسازد:
ساخت از خط فرمان و اندروید استودیو.
منابع را با پشتیبانی کامل از خدمات زبان (به عنوان مثال، تعریف رفتن به تعریف) در Android Studio ویرایش کنید.
از دیباگرهای Android Studio برای اشکال زدایی فرآیندهای بومی و ترکیبی استفاده کنید.
چگونه بیلد خود را برای استفاده از اسکریپت پیکربندی ساخت سفارشی C/C++ تغییر دهید
این بخش مراحل استفاده از اسکریپت پیکربندی ساخت C/C++ سفارشی از AGP را طی میکند.
مرحله 1: فایل build.gradle
سطح ماژول را برای ارجاع به یک اسکریپت پیکربندی تغییر دهید
برای فعال کردن پشتیبانی Ninja در AGP، experimentalProperties
را در فایل build.gradle
سطح ماژول پیکربندی کنید:
android {
defaultConfig {
externalNativeBuild {
experimentalProperties["ninja.abiFilters"] = [ "x86", "arm64-v8a" ]
experimentalProperties["ninja.path"] = "source-file-list.txt"
experimentalProperties["ninja.configure"] = "configure-ninja"
experimentalProperties["ninja.arguments"] = [
"\${ndk.moduleMakeFile}",
"--variant=\${ndk.variantName}",
"--abi=Android-\${ndk.abi}",
"--configuration-dir=\${ndk.configurationDir}",
"--ndk-version=\${ndk.moduleNdkVersion}",
"--min-sdk-version=\${ndk.minSdkVersion}"
]
}
}
ویژگی ها توسط AGP به صورت زیر تفسیر می شوند:
ninja.abiFilters
فهرستی از ABI برای ساخت است. مقادیر معتبر عبارتند از:x86
،x86-64
،armeabi-v7a
، وarm64-v8a
.ninja.path
مسیری به فایل پروژه C/C++ است. فرمت این فایل می تواند هر چیزی که می خواهید باشد. تغییراتی که در این فایل ایجاد میشود، یک درخواست برای همگامسازی Gradle در Android Studio ایجاد میکند.ninja.configure
مسیری به فایل اسکریپت است که زمانی که نیاز به پیکربندی پروژه C/C++ باشد توسط Gradle اجرا می شود. یک پروژه در اولین ساخت، در حین همگام سازی Gradle در Android Studio، یا زمانی که یکی از ورودی های پیکربندی اسکریپت تغییر می کند، پیکربندی می شود.ninja.arguments
لیستی از آرگومان هایی است که به اسکریپت تعریف شده توسط ninja.configure ارسال می شود. عناصر موجود در این لیست می توانند به مجموعه ای از ماکروها اشاره کنند که مقادیر آنها به زمینه پیکربندی فعلی در AGP بستگی دارد:${ndk.moduleMakeFile}
مسیر کامل فایلninja.configure
است. بنابراین در مثال،C:\path\to\configure-ninja.bat
خواهد بود.${ndk.variantName}
نام نوع فعلی AGP است که در حال ساخت است. به عنوان مثال، اشکال زدایی یا انتشار.${ndk.abi}
نام AGP ABI فعلی است که در حال ساخت است. به عنوان مثال،x86
یاarm64-v8a
.
${ndk.buildRoot}
نام پوشه ای است که توسط AGP تولید شده است و اسکریپت خروجی خود را در آن می نویسد. جزئیات این مورد در مرحله 2 توضیح داده خواهد شد: اسکریپت پیکربندی را ایجاد کنید .${ndk.ndkVersion}
نسخه NDK مورد استفاده است. این مقدار معمولاً مقداری است که در فایلbuild.gradle
به android.ndkVersion ارسال میشود یا اگر هیچ کدام وجود نداشته باشد، یک مقدار پیشفرض است.${ndk.minPlatform}
حداقل پلتفرم Android هدف درخواست شده توسط AGP است.
ninja.targets
لیستی از اهداف خاص نینجا است که باید ساخته شوند.
مرحله 2: اسکریپت پیکربندی را ایجاد کنید
حداقل مسئولیت اسکریپت پیکربندی ( configure-ninja.bat
در مثال قبلی) تولید یک فایل build.ninja
است که وقتی با Ninja ساخته میشود، تمام خروجیهای بومی پروژه را کامپایل و پیوند میدهد. معمولاً اینها فایلهای .o
(Object)، .a
(Archive) و .so
(Shared Object) هستند.
اسکریپت configure می تواند بسته به نیاز شما فایل build.ninja
را در دو مکان مختلف بنویسد.
اگر انتخاب مکان برای AGP اشکالی ندارد، اسکریپت پیکربندی
build.ninja
در مکان تنظیم شده در ماکرو${ndk.buildRoot}
می نویسد.اگر اسکریپت پیکربندی باید محل فایل
build.ninja
را انتخاب کند، فایلی به نامbuild.ninja.txt
را نیز در محل تنظیم شده در ماکرو${ndk.buildRoot}
می نویسد. این فایل حاوی مسیر کامل فایلbuild.ninja
است که اسکریپت پیکربندی نوشته است.
ساختار فایل build.ninja
به طور کلی، ساختار اکثری که به طور دقیق یک ساخت Android C/C++ را نشان میدهند، کار خواهند کرد. عناصر کلیدی مورد نیاز AGP و Android Studio عبارتند از:
لیست فایل های منبع C/C++ به همراه پرچم های مورد نیاز Clang برای کامپایل آنها.
فهرست کتابخانه های خروجی اینها معمولاً فایلهای
.so
(اشیاء مشترک) هستند اما میتوانند.a
(بایگانی) یا قابل اجرا (بدون پسوند) باشند.
اگر به مثالهایی در مورد نحوه تولید فایل build.ninja
نیاز دارید، میتوانید هنگام استفاده از ژنراتور build.ninja
به خروجی CMake نگاه کنید.
در اینجا نمونه ای از قالب build.ninja
مینیمال است.
rule COMPILE
command = /path/to/ndk/clang -c $in -o $out {other flags}
rule LINK
command = /path/to/ndk/clang $in -o $out {other flags}
build source.o : COMPILE source.cpp
build lib.so : LINK source.o
بهترین شیوه ها
علاوه بر الزامات (فهرست فایل های منبع و کتابخانه های خروجی)، در اینجا برخی از بهترین روش های توصیه شده وجود دارد.
خروجی های نامگذاری شده را با قوانین phony
اعلام کنید
در صورت امکان، توصیه میشود که ساختار build.ninja
از قوانین phony
برای دادن نامهای قابل خواندن توسط انسان به خروجیهای ساخت استفاده کند. بنابراین برای مثال، اگر خروجیای به نام c:/path/to/lib.so
دارید، میتوانید به صورت زیر به آن یک نام قابل خواندن برای انسان بدهید.
build curl: phony /path/to/lib.so
مزیت انجام این کار این است که می توانید این نام را به عنوان هدف ساخت در فایل build.gradle
مشخص کنید. به عنوان مثال،
android {
defaultConfig {
externalNativeBuild {
...
experimentalProperties["ninja.targets"] = [ "curl" ]
یک هدف "همه" را مشخص کنید
وقتی یک all
را مشخص میکنید، این مجموعه پیشفرض کتابخانههای ساختهشده توسط AGP خواهد بود، زمانی که هیچ هدفی بهصراحت در فایل build.gradle
مشخص نشده باشد.
rule COMPILE
command = /path/to/ndk/clang $in -o $out {other flags}
rule LINK
command = /path/to/ndk/clang $in -o $out {other flags}
build foo.o : COMPILE foo.cpp
build bar.o : COMPILE bar.cpp
build libfoo.so : LINK foo.o
build libbar.so : LINK bar.o
build all: phony libfoo.so libbar.so
یک روش ساخت جایگزین را مشخص کنید (اختیاری)
یک مورد استفاده پیشرفته تر، بسته بندی یک سیستم ساخت موجود است که مبتنی بر نینجا نیست. در این مورد، شما هنوز باید همه منابع را با پرچمهایشان به همراه کتابخانههای خروجی نشان دهید تا اندروید استودیو بتواند ویژگیهای خدمات زبانی مناسبی مانند تکمیل خودکار و تعریف رفتن را ارائه دهد. با این حال، میخواهید AGP در طول ساخت واقعی، به سیستم ساخت زیربنایی موکول شود.
برای انجام این کار، می توانید از یک خروجی ساخت نینجا با پسوند خاص .passthrough
استفاده کنید.
به عنوان مثال ملموس تر، فرض کنید می خواهید یک MSBuild را بپیچید. اسکریپت پیکربندی شما طبق معمول build.ninja
را ایجاد می کند، اما همچنین یک هدف عبوری اضافه می کند که نحوه فراخوانی AGP MSBuild را مشخص می کند.
rule COMPILE
command = /path/to/ndk/clang $in -o $out {other flags}
rule LINK
command = /path/to/ndk/clang $in -o $out {other flags}
rule MBSUILD_CURL
command = /path/to/msbuild {flags to build curl with MSBuild}
build source.o : COMPILE source.cpp
build lib.so : LINK source.o
build curl : phony lib.so
build curl.passthrough : MBSUILD_CURL
بازخورد بدهید
این ویژگی آزمایشی است، بنابراین بازخورد بسیار قابل قدردانی است. از طریق کانال های زیر می توانید نظرات خود را اعلام کنید:
برای بازخورد کلی، یک نظر به این اشکال اضافه کنید.
برای گزارش یک اشکال، Android Studio را باز کنید و روی Help > Submit Feedback کلیک کنید. حتماً به «Custom C/C++ Build Systems» رجوع کنید تا به رفع اشکال کمک کنید.
برای گزارش یک اشکال در صورتی که Android Studio را نصب نکردهاید، با استفاده از این الگو یک اشکال را ثبت کنید.