نظام البناء Soong

قبل إصدار Android 7.0 ، استخدم Android GNU Make حصريًا لوصف وتنفيذ قواعد البناء الخاصة به. يتم دعم واستخدام نظام Make build على نطاق واسع ، ولكن على نطاق Android أصبح بطيئًا وعرضة للخطأ وغير قابل للتطوير ويصعب اختباره. يوفر نظام البناء Soong المرونة المطلوبة لإصدارات Android.

لهذا السبب ، من المتوقع أن يتحول مطورو النظام الأساسي من Make واعتماد Soong في أقرب وقت ممكن. أرسل أسئلة إلى مجموعة Google التي تعمل بنظام android لتلقي الدعم.

ما هو Soong؟

تم تقديم نظام البناء Soong في Android 7.0 (Nougat) ليحل محل Make. إنها تستفيد من أداة استنساخ Kati GNU Make ومكوِّن نظام بناء Ninja لتسريع إصدارات Android.

راجع وصف Android Make Build System في مشروع Android Open Source Project (AOSP) للحصول على إرشادات عامة وإنشاء تغييرات في النظام لكتاب Android.mk للتعرف على التعديلات اللازمة للتكيف من Make إلى Soong.

راجع المدخلات المتعلقة بالبناء في المسرد للحصول على تعريفات للمصطلحات الأساسية وملفات Soong المرجعية للحصول على تفاصيل كاملة.

جعل المقارنة وسونغ

فيما يلي مقارنة بين إجراء التكوين مع قيام 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)

مثال Soong

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 الملفات المصدر المستخدمة لبناء الوحدة ، كقائمة من السلاسل. يمكنك الرجوع إلى إخراج الوحدات النمطية الأخرى التي تنتج ملفات مصدر ، مثل genrule أو filegroup ، باستخدام صيغة مرجع الوحدة النمطية ":<module-name>" .

للحصول على قائمة بأنواع الوحدات الصالحة وخصائصها ، راجع مرجع وحدات Soong .

أنواع

يتم كتابة المتغيرات والخصائص بشكل قوي ، حيث تستند المتغيرات ديناميكيًا إلى التعيين الأول ، ويتم تعيين الخصائص بشكل ثابت بواسطة نوع الوحدة النمطية. الأنواع المدعومة هي:

  • القيم المنطقية ( true أم false )
  • عدد صحيح ( int )
  • سلاسل ( "string" )
  • قوائم السلاسل ( ["string1", "string2"] )
  • الخرائط ( {key1: "value1", key2: ["value2"]} )

قد تحتوي الخرائط على قيم من أي نوع ، بما في ذلك الخرائط المتداخلة. قد تحتوي القوائم والخرائط على فواصل لاحقة بعد القيمة الأخيرة.

جلوبس

يمكن للخصائص التي تأخذ قائمة من الملفات ، مثل srcs ، أن تأخذ أنماطًا كروية. يمكن أن تحتوي أنماط الكرة الأرضية على أحرف البدل العادية * في UNIX ، على سبيل المثال *.java . يمكن أن تحتوي أنماط الكرة الأرضية أيضًا على ** حرف بدل واحد كعنصر مسار ، والذي يطابق صفرًا أو أكثر من عناصر المسار. على سبيل المثال ، يطابق 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 ++ // التعليقات.

العاملين

يمكن إلحاق السلاسل وقوائم السلاسل والخرائط باستخدام عامل التشغيل +. يمكن تلخيص الأعداد الصحيحة باستخدام عامل التشغيل + . يؤدي إلحاق خريطة إلى توحيد المفاتيح في كلتا الخريطتين ، وإلحاق قيم أي مفاتيح موجودة في كلتا الخريطتين.

الشرطية

لا يدعم 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_prebuilt_binary باسم foo عندما يكون هناك بالفعل cc_binary بالاسم نفسه. يمنح هذا المطورين المرونة لاختيار الإصدار المراد تضمينه في منتجهم النهائي. إذا كان تكوين البناء يحتوي على كلا الإصدارين ، فإن prefer العلامة المفضلة في تعريف الوحدة النمطية المُنشأة مسبقًا تملي الإصدار الذي له الأولوية. لاحظ أن بعض الوحدات النمطية التي تم إنشاؤها مسبقًا لها أسماء لا تبدأ android_app_import prebuilt

وحدات مساحة الاسم

حتى يتم تحويل Android بالكامل من Make إلى Soong ، يجب أن تحدد تهيئة المنتج قيمة PRODUCT_SOONG_NAMESPACES . يجب أن تكون قيمتها عبارة عن قائمة من مساحات الأسماء مفصولة بمسافات والتي يصدرها Soong إلى Make ليتم بناؤها بواسطة الأمر m . بعد اكتمال تحويل Android إلى 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. بخلاف ذلك ، يبحث Soong أولاً عن وحدة نمطية باسم D تم الإعلان عنها في مساحة الاسم N.
  3. إذا لم تكن هذه الوحدة موجودة ، يبحث Soong عن وحدة تسمى D في مساحات الأسماء I1 ، I2 ، I3 ...
  4. أخيرًا ، يبحث Soong في مساحة اسم الجذر.