قبل از انتشار اندروید 7.0، اندروید به طور انحصاری از GNU Make برای توصیف و اجرای قوانین ساخت خود استفاده می کرد. سیستم ساخت Make به طور گسترده ای پشتیبانی و استفاده می شود، اما در مقیاس اندروید کند، مستعد خطا، مقیاس ناپذیر و آزمایش آن دشوار است. سیستم ساخت Soong انعطافپذیری مورد نیاز برای ساختهای اندروید را فراهم میکند.
به همین دلیل، انتظار می رود توسعه دهندگان پلتفرم در اسرع وقت از Make تغییر مکان داده و Soong را اتخاذ کنند. برای دریافت پشتیبانی، سؤالات خود را به گروه Google Android-building ارسال کنید.
سونگ چیست؟
سیستم ساخت Soong در اندروید 7.0 (نوقا) جایگزین Make معرفی شد. این ابزار از ابزار شبیه سازی Kati GNU Make و مؤلفه سیستم ساخت Ninja برای سرعت بخشیدن به ساخت اندروید استفاده می کند.
برای اطلاع از دستورالعملهای کلی و ایجاد تغییرات سیستم برای نویسندگان Android.mk تا در مورد تغییرات مورد نیاز برای انطباق از Make به Soong، به توضیحات Android Make Build System در پروژه منبع باز Android (AOSP) مراجعه کنید.
برای تعاریف اصطلاحات کلیدی و برای جزئیات کامل به مدخل های مربوط به ساخت در واژه نامه مراجعه کنید.
مقایسه Make و Soong
در اینجا مقایسه ای از Make configuration با Soong است که همین کار را در یک فایل پیکربندی Soong (Blueprint یا .bp
) انجام می دهد.
مثال بزن
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libxmlrpc++
LOCAL_MODULE_HOST_OS := linux
LOCAL_RTTI_FLAG := -frtti
LOCAL_CPPFLAGS := -Wall -Werror -fexceptions
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/src
LOCAL_SRC_FILES := $(call \
all-cpp-files-under,src)
include $(BUILD_SHARED_LIBRARY)
مثال کوتاه
cc_library_shared {
name: “libxmlrpc++”,
rtti: true,
cppflags: [
“-Wall”,
“-Werror”,
“-fexceptions”,
],
export_include_dirs: [“src”],
srcs: [“src/**/*.cpp”],
target: {
darwin: {
enabled: false,
},
},
}
برای نمونههای پیکربندی Soong مخصوص تست، پیکربندی ساخت ساده را ببینید.
فرمت فایل Android.bp
از نظر طراحی، فایل های Android.bp
ساده هستند. آنها شامل شرطی یا دستورات جریان کنترلی نیستند. تمام پیچیدگی ها توسط منطق ساخت نوشته شده در Go مدیریت می شود. در صورت امکان، نحو و معنای فایلهای Android.bp
مشابه فایلهای Bazel BUILD است.
ماژول ها
یک ماژول در یک فایل Android.bp
با یک نوع ماژول و به دنبال آن مجموعه ای از ویژگی ها به name: "value",
قالب:
cc_binary {
name: "gzip",
srcs: ["src/test/minigzip.c"],
shared_libs: ["libz"],
stl: "none",
}
هر ماژول باید یک ویژگی name
داشته باشد، و مقدار باید در همه فایلهای Android.bp
منحصر به فرد باشد، به جز مقادیر ویژگی name
در فضاهای نام و ماژولهای از پیش ساخته شده، که ممکن است تکرار شوند.
ویژگی srcs
فایل های منبع مورد استفاده برای ساخت ماژول را به عنوان لیستی از رشته ها مشخص می کند. می توانید با استفاده از نحو مرجع ماژول ":<module-name>"
به خروجی ماژول های دیگری که فایل های منبع تولید می کنند، مانند genrule
یا filegroup
ارجاع دهید.
برای لیستی از انواع ماژول های معتبر و ویژگی های آنها، به مرجع ماژول های Soong مراجعه کنید.
انواع
متغیرها و ویژگی ها به شدت تایپ می شوند، با متغیرها به صورت پویا بر اساس اولین انتساب، و ویژگی ها به صورت ایستا توسط نوع ماژول تنظیم می شوند. انواع پشتیبانی شده عبارتند از:
- بولی (
true
یاfalse
) - اعداد صحیح (
int
) - رشته ها (
"string"
) - لیست رشته ها (
["string1", "string2"]
- نقشهها (
{key1: "value1", key2: ["value2"]}
)
نقشه ها ممکن است حاوی مقادیری از هر نوع باشند، از جمله نقشه های تو در تو. لیست ها و نقشه ها ممکن است دارای کاماهای انتهایی بعد از آخرین مقدار باشند.
گلوب
ویژگی هایی که لیستی از فایل ها را می گیرند، مانند srcs
، می توانند الگوهای glob را نیز بگیرند. الگوهای Glob می توانند شامل علامت عام یونیکس معمولی *
باشند، برای مثال *.java
. الگوهای Glob همچنین میتوانند شامل یک علامت **
به عنوان عنصر مسیر باشند که با صفر یا چند عنصر مسیر مطابقت دارد. برای مثال، java/**/*.java
با الگوهای java/Main.java
و java/com/android/Main.java
مطابقت دارد.
متغیرها
یک فایل Android.bp
ممکن است دارای تخصیص متغیرهای سطح بالا باشد:
gzip_srcs = ["src/test/minigzip.c"],
cc_binary {
name: "gzip",
srcs: gzip_srcs,
shared_libs: ["libz"],
stl: "none",
}
متغیرها به بقیه فایلی که در آن اعلان شده اند و همچنین هر فایل Blueprint فرزندی محدود می شوند. متغیرها با یک استثنا تغییر ناپذیر هستند: آنها را می توان با یک تخصیص +=
به آنها اضافه کرد، اما فقط قبل از اینکه به آنها ارجاع داده شود.
نظرات
فایلهای Android.bp
میتوانند شامل نظرات چندخطی /* */
به سبک C و تک خطی //
به سبک C++ باشند.
اپراتورها
رشته ها، لیست رشته ها و نقشه ها را می توان با استفاده از عملگر + اضافه کرد. اعداد صحیح را می توان با استفاده از عملگر +
خلاصه کرد. ضمیمه کردن یک نقشه اتحاد کلیدها را در هر دو نقشه ایجاد می کند و مقادیر هر کلیدی را که در هر دو نقشه وجود دارد اضافه می کند.
شرایط
Soong از شرطی ها در فایل های Android.bp
پشتیبانی نمی کند. در عوض، پیچیدگی در قوانین ساخت که به شرطیها نیاز دارند در Go، جایی که میتوان از ویژگیهای زبان سطح بالا استفاده کرد، و وابستگیهای ضمنی معرفیشده توسط شرطیها را میتوان ردیابی کرد. اکثر شرطی ها به یک ویژگی نقشه تبدیل می شوند، جایی که یکی از مقادیر موجود در نقشه انتخاب شده و به ویژگی های سطح بالا اضافه می شود.
به عنوان مثال، برای پشتیبانی از فایل های خاص معماری:
cc_library {
...
srcs: ["generic.cpp"],
arch: {
arm: {
srcs: ["arm.cpp"],
},
x86: {
srcs: ["x86.cpp"],
},
},
}
فرمت کننده
Soong شامل یک قالبکننده متعارف برای فایلهای Blueprint، مشابه gofmt است. برای قالببندی مجدد همه فایلهای Android.bp
در فهرست فعلی، اجرا کنید:
bpfmt -w .
قالب متعارف شامل تورفتگی های چهار فاصله، خطوط جدید بعد از هر عنصر از یک لیست چند عنصری، و یک کاما انتهایی در لیست ها و نقشه ها است.
ماژول های ویژه
برخی از گروه های ماژول ویژه دارای ویژگی های منحصر به فردی هستند.
ماژول های پیش فرض
یک ماژول پیش فرض می تواند برای تکرار همان ویژگی ها در چندین ماژول استفاده شود. مثلا:
cc_defaults {
name: "gzip_defaults",
shared_libs: ["libz"],
stl: "none",
}
cc_binary {
name: "gzip",
defaults: ["gzip_defaults"],
srcs: ["src/test/minigzip.c"],
}
ماژول های از پیش ساخته شده
برخی از انواع ماژول های از پیش ساخته شده به یک ماژول اجازه می دهند نامی مشابه با همتایان مبتنی بر منبع خود داشته باشد. برای مثال، زمانی که یک cc_binary
با همین نام وجود داشته باشد، میتواند یک cc_prebuilt_binary
به نام foo
وجود داشته باشد. این به توسعه دهندگان این امکان را می دهد تا انتخاب کنند کدام نسخه را در محصول نهایی خود قرار دهند. اگر یک پیکربندی ساخت شامل هر دو نسخه prefer
، مقدار پرچم ترجیحی در تعریف ماژول از پیش ساخته شده دیکته میکند که کدام نسخه اولویت دارد. توجه داشته باشید که برخی از ماژول های از پیش ساخته شده دارای نام هایی هستند که با پیش ساخته شروع نمی android_app_import
prebuilt
ماژول های فضای نام
تا زمانی که Android به طور کامل از Make به Soong تبدیل نشود، پیکربندی محصول Make باید یک مقدار PRODUCT_SOONG_NAMESPACES
را مشخص کند. مقدار آن باید لیستی از فضاهای نام جدا شده با فاصله باشد که Soong به Make صادر می کند تا با دستور m
ساخته شود. پس از تکمیل تبدیل اندروید به Soong، جزئیات فعال کردن فضاهای نام ممکن است تغییر کند.
Soong این توانایی را برای ماژولها در فهرستهای مختلف فراهم میکند که نام یکسانی را مشخص کنند، به شرطی که هر ماژول در یک فضای نام جداگانه اعلام شود. فضای نام را می توان به صورت زیر اعلام کرد:
soong_namespace {
imports: ["path/to/otherNamespace1", "path/to/otherNamespace2"],
}
توجه داشته باشید که فضای نام دارای ویژگی نام نیست. مسیر آن به طور خودکار به عنوان نام آن اختصاص داده می شود.
به هر ماژول Soong یک فضای نام بر اساس مکان آن در درخت اختصاص داده می شود. هر ماژول Soong در فضای نامی است که توسط soong_namespace
موجود در یک فایل Android.bp
در فهرست راهنمای فعلی یا نزدیکترین فهرست اجداد تعریف شده است. اگر چنین ماژول soong_namespace
یافت نشد، ماژول در فضای نام ریشه ضمنی در نظر گرفته می شود.
در اینجا یک مثال آورده شده است: Soong تلاش می کند تا وابستگی D اعلام شده توسط ماژول M را در فضای نام N که فضاهای نام I1، I2، I3 را وارد می کند، حل کند.
- سپس اگر D یک نام کاملا واجد شرایط از فرم
//namespace:module
، فقط فضای نام مشخص شده برای نام ماژول مشخص شده جستجو می شود. - در غیر این صورت، سونگ ابتدا به دنبال یک ماژول به نام D اعلام شده در فضای نام N می گردد.
- اگر آن ماژول وجود نداشته باشد، Soong به دنبال ماژولی به نام D در فضاهای نام I1، I2، I3 می گردد.
- در نهایت، Soong در فضای نام ریشه نگاه می کند.