سیستم ساخت سونگ

قبل از انتشار اندروید 7.0، اندروید به طور انحصاری از GNU Make برای توصیف و اجرای قوانین ساخت خود استفاده می کرد. سیستم ساخت Make به طور گسترده ای پشتیبانی و استفاده می شود، اما در مقیاس اندروید کند، مستعد خطا، مقیاس ناپذیر، و آزمایش آن دشوار است. سیستم ساخت Soong انعطاف‌پذیری مورد نیاز برای ساخت‌های اندروید را فراهم می‌کند.

به همین دلیل، انتظار می رود توسعه دهندگان پلتفرم در اسرع وقت از Make تغییر مکان داده و Soong را اتخاذ کنند. برای دریافت پشتیبانی، سؤالات خود را به گروه Google Android-building ارسال کنید.

سونگ چیست؟

سیستم ساخت Soong در اندروید 7.0 (نوقا) جایگزین Make معرفی شد. این ابزار از ابزار کلون Kati GNU Make و مؤلفه سیستم ساخت Ninja برای سرعت بخشیدن به ساخت‌های اندروید استفاده می‌کند.

برای آشنایی با تغییرات مورد نیاز برای انطباق از Make به Soong، توضیحات کلی Android Make Build System را در پروژه متن باز Android (AOSP) برای دستورالعمل‌های کلی و ایجاد تغییرات سیستم برای نویسندگان Android.mk ببینید.

برای تعاریف اصطلاحات کلیدی و برای جزئیات کامل به مدخل های مربوط به ساخت در واژه نامه مراجعه کنید.

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

ماژول های ویژه

برخی از گروه های ماژول ویژه دارای ویژگی های منحصر به فردی هستند.

ماژول های پیش فرض

یک ماژول پیش فرض می تواند برای تکرار همان ویژگی ها در چندین ماژول استفاده شود. به عنوان مثال:

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 در تعریف ماژول از پیش ساخته شده دیکته می‌کند که کدام نسخه اولویت دارد. توجه داشته باشید که برخی از ماژول های از پیش ساخته شده دارای نام هایی هستند که با prebuilt شروع نمی شوند، مانند android_app_import .

ماژول های فضای نام

تا زمانی که 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 را وارد می کند، حل کند.

  1. سپس اگر D یک نام کاملا واجد شرایط از فرم //namespace:module باشد، فقط فضای نام مشخص شده برای نام ماژول مشخص شده جستجو می شود.
  2. در غیر این صورت، سونگ ابتدا به دنبال یک ماژول به نام D اعلام شده در فضای نام N می گردد.
  3. اگر آن ماژول وجود نداشته باشد، Soong به دنبال ماژولی به نام D در فضاهای نام I1، I2، I3 می گردد.
  4. در نهایت، Soong در فضای نام ریشه نگاه می کند.