مبنى مع منصات

يقدّم Bazel دعمًا متطوّرًا لوضع نماذج المنصات و سلاسل الأدوات. ويتطلب دمج هذه الأدوات في مشاريع حقيقية تعاونًا دقيقًا بين مالكي الرموز ومسؤولي القواعد وغيرهم من مطوّري البرامج على Bazel.

وتلخّص هذه الصفحة الغرض من المنصات، كما توضّح كيفية الإنشاء باستخدامها.

tl;dr: تتوفّر منصة Bazel'API وسلسلة الأدوات على الرغم من أنّها لن تعمل في أي مكان إلى أن يتم تعديل جميع قواعد اللغة وselect()s والمراجع القديمة الأخرى. وهذا العمل متواصل. وفي النهاية، ستستند جميع الإصدارات إلى النظام الأساسي. يُرجى الاطّلاع على التفاصيل أدناه لمعرفة أماكن تصاميمك.

للحصول على مزيد من المستندات الرسمية، يمكنك الاطّلاع على:

الخلفية

تم تقديم الأنظمة الأساسية وسلاسل الأدوات من أجل توحيد كيفية استهداف مشاريع البرامج للأجهزة المختلفة وتصميمها باستخدام أدوات اللغات المناسبة.

هذه إضافة حديثة نسبيًا إلى Bazel. وقد تم استلهام هذه الملاحظة من خلال الملاحظة التي تفيد بأنّ مسؤولي اللغة كانوا يفعلون ذلك من خلال طرق مخصّصة غير متوافقة. على سبيل المثال، تستخدم قواعد C++ --cpu و--crosstool_top لضبط وحدة معالجة مركزية (CPU) مستهدفة وسلسلة مفاتيح C++. ولا يُعتبر هذان النموذجان نموذجًا صحيحًا; وقد أدت محاولات سابقة إلى إجراء ذلك إلى إنشاء إصدارات غير سليمة وغير دقيقة. لا تتحكّم هذه العلامات أيضًا في تجميع لغة Java التي طوّرت واجهة خاصة بها باستخدام --java_toolchain.

تم تصميم Bazel للمشاريع الكبيرة المتعددة اللغات ومتعددة المنصات. ويتطلب هذا توفير المزيد من المبادئ، وهذه هي الغرض من واجهات برمجة التطبيقات الجديدة هذه.

النقل

لا تعمل واجهات برمجة التطبيقات للأنظمة الأساسية وسلسلة الأدوات إلا عندما تستخدمها المشاريع حقًا. وهذا ليس تبسيطًا لأن منطق قاعدة المشروع وسلاسل الأدوات والاعتماديات وselect() يجب أن تدعمها. يتطلب هذا تسلسلاً دقيقًا لنقل البيانات للحفاظ على عمل جميع المشاريع وملحقاتها بشكل صحيح.

على سبيل المثال، تتوافق قواعد Bazel's++C مع الأنظمة الأساسية. ولكن قواعد Apple لا تنص على ذلك. قد لا يكون مشروعك على C++ مهتمًا بمنتجات Apple. أما البعض الآخر، فقد يكون من غير الآمن الآن تفعيل الأنظمة الأساسية على مستوى جميع إصدارات C++ .

يوضّح الجزء المتبقي من هذه الصفحة تسلسل نقل البيانات هذا ومدى ملاءمة مشاريعك.

الهدف

تكتمل عملية نقل منصة Bazel' عند إنشاء جميع المشاريع باستخدام النموذج:

bazel build //:myproject --platforms=//:myplatform

وهذا يعني ما يلي:

  1. القواعد التي يستخدمها مشروعك يمكن أن تستنتج سلاسل أدوات صحيحة من //:myplatform.
  2. يمكن أن تعتمد تبعيات مشروعك على تبعيات"الأدوات"الصحيحة في //:myplatform.
  3. إما تدعم المشاريع بناءً على مشروعك //:myplatform أو يتوافق مشروعك مع واجهات برمجة التطبيقات القديمة (مثل --crosstool_top).
  4. //:myplatform المراجع [التعريفات الشائعة][بيان المنصة الشائعة]{: .external} لـ CPU وOS والمفاهيم العامة الأخرى التي توفّر التوافق التلقائي بين المشاريع.
  5. جميع المشاريع ذات الصلة' select()s تفهم خصائص الجهاز الضمنية من خلال //:myplatform.
  6. يتم تعريف //:myplatform في مكان واضح قابل لإعادة الاستخدام: في مشروعك، يمكنك إعادة النظر إذا كان النظام الأساسي فريدًا لمشروعك، وإلا يمكنك العثور على جميع المشاريع التي قد تستخدم هذه المنصة.

وستتم إزالة واجهات برمجة التطبيقات القديمة فور تحقيق هذا الهدف. ستكون هذه هي الطريقة العادية للمشاريع هي اختيار الأنظمة الأساسية وسلاسل الأدوات.

هل يجب استخدام المنصات؟

إذا أردت فقط إنشاء مشروع أو تجميعه، يجب اتّباع المستندات الرسمية للمشروع.

إذا كنت تملك مشروعًا أو لغة أو أداة لحفظ سلسلة الأدوات، ستحتاج في النهاية إلى إتاحة واجهات برمجة التطبيقات الجديدة. تعتمد إمكانية الانتظار إلى أن تكتمل عملية نقل البيانات العالمية أو تفعيل الميزة في وقت مبكر على القيمة المحدّدة لاحتياجاتك من حيث التكلفة / التكلفة:

القيمة

  • يمكنك select() أو اختيار سلاسل أدوات على الخصائص المحدّدة التي تهمّك، بدلاً من استخدام علامات غير ثابتة، مثل --cpu. على سبيل المثال، يمكن أن تتوافق العديد من وحدات المعالجة المركزية (CPU) مع مجموعة التعليمات نفسها.
  • مزيد من المعلومات عن الإصدارات إذا استخدمت select() مع --cpu في المثال أعلاه، إذا أضفت وحدة معالجة مركزية جديدة متوافقة مع مجموعة التعليمات نفسها، يتعذّر على select() التعرّف على وحدة المعالجة المركزية الجديدة. ومع ذلك، تظلّ select() على الأنظمة الأساسية دقيقة.
  • توفير تجربة استخدام أسهل تفهم جميع المشاريع: --platforms=//:myplatform. لا حاجة إلى علامات متعددة ذات اللغات في سطر الأوامر.
  • تصميم أكثر بساطة للغة. تتشارك جميع اللغات واجهة برمجة تطبيقات مشتركة لتحديد سلاسل الأدوات، واستخدام سلاسل الأدوات، واختيار سلسلة الأدوات المناسبة للنظام الأساسي.
  • يمكن تخطّي الأهداف في مرحلة الإصدار والاختبار إذا لم تكن متوافقة مع النظام الأساسي المستهدف.

التكاليف

  • بالنسبة إلى المشاريع التابعة التي لا تتوافق مع الأنظمة الأساسية، والتي لا تدعمها بعد، قد لا تعمل تلقائيًا مع مشاريعك.
  • قد يتطلب جعلها تعمل صيانة مؤقتة إضافية.
  • يتطلب التواجد المشترك لواجهات برمجة التطبيقات الجديدة والقديمة توجيه المستخدم بدقة أكبر لتجنب حدوث ارتباك.
  • لا تزال التعريفات الأساسية للخصائص الشائعة مثل OS وCPU تتطوّر وقد تتطلّب مساهمات مبدئية إضافية.
  • لا تزال التعريفات الأساسية لسلاسل الأدوات بلغات معيّنة تتطوّر وقد تتطلّب مساهمات مبدئية إضافية.

مراجعة واجهة برمجة التطبيقات

platform هي مجموعة من constraint_value الأهداف:

platform(
    name = "myplatform",
    constraint_values = [
        "@platforms//os:linux",
        "@platforms//cpu:arm",
    ],
)

constraint_value هي موقع للآلة. يتم تجميع قيم السمة "kin;&quot نفسها ضمن constraint_setting مشتركة:

constraint_setting(name = "os")
constraint_value(
    name = "linux",
    constraint_setting = ":os",
)
constraint_value(
    name = "mac",
    constraint_setting = ":os",
)

toolchain هي قاعدة Starlark. تحدّد سماتها أدوات اللغة (مثل compiler = "//mytoolchain:custom_gcc"). يمرّر مقدّمو الخدمة هذه المعلومات إلى القواعد التي يجب إنشاؤها باستخدام هذه الأدوات.

تشير أدوات الأدوات إلى constraint_values الأجهزة التي يمكنها target (target_compatible_with = ["@platforms//os:linux"]) وآلاتها تشغيلها (exec_compatible_with = ["@platforms//os:mac"]).

عند إنشاء $ bazel build //:myproject --platforms=//:myplatform، يختار Bazel سلسلة أدوات تلقائيًا يمكن تشغيلها على جهاز الإنشاء وتصميم برامج ثنائية لـ //:myplatform. وتُعرَف هذه العملية باسم دقة سلسلة الأدوات.

يمكن تسجيل مجموعة سلاسل الأدوات المتاحة في WORKSPACE باستخدام register_toolchains أو في سطر الأوامر باستخدام --extra_toolchains.

يمكنك الاطّلاع على مزيد من التفاصيل هنا.

الحالة

تختلف إتاحة النظام الأساسي الحالي من لغة إلى أخرى. يتم نقل جميع قواعد Bazel الرئيسية إلى المنصات. ولكن هذه العملية ستستغرق بعض الوقت. ويعود ذلك إلى ثلاثة أسباب رئيسية:

  1. يجب تعديل منطق القاعدة للحصول على معلومات الأداة من واجهة برمجة تطبيقات مجموعة الأدوات الجديدة (ctx.toolchains) وإيقاف قراءة الإعدادات القديمة مثل --cpu و--crosstool_top. وهذا أمر بسيط نسبيًا.

  2. على مشرفي سلسلة الأدوات تحديد سلاسل الأدوات والسماح للمستخدمين بالوصول إليها (في مستودعات GitHub وWORKSPACE إدخالات). وهذا أمر بسيط من الناحية الفنية، ولكن يجب تنظيمه بذكاء للحفاظ على تجربة المستخدم سهلة.

    وتُعدّ تعريفات النظام الأساسي ضرورية أيضًا (ما لم تُنشئ اللعبة على جهاز Bazel نفسه). وبشكل عام، يجب أن تحدد المشاريع الأنظمة الأساسية الخاصة بها.

  3. يجب نقل المشاريع الحالية. select() كما يجب نقل عمليات النقل. هذا هو التحدي الأكبر. يشكّل هذا الأمر تحديًا على وجه الخصوص للمشاريع المتعددة اللغات (التي قد تفشل في حال جميع اللغات't قراءة --platforms).

إذا كنت تصمّم مجموعة قواعد جديدة، يجب عليك دعم الأنظمة الأساسية من البداية. ويؤدي ذلك تلقائيًا إلى توافق قواعدك مع القواعد والمشاريع الأخرى، مع زيادة القيمة بما أن واجهة برمجة التطبيقات لمنصّة المنصة أصبحت أكثر شمولاً.

خصائص المنصة الشائعة

يجب الإعلان عن خصائص النظام الأساسي، مثل OS وCPU، التي تكون شائعة في جميع المشاريع، في مكان عادي ومركزي. وهذا يشجّع على التوافق بين المشاريع ومختلف اللغات.

على سبيل المثال، إذا كان MyApp يحتوي على select() على constraint_value @myapp//cpus:arm وsomeCommonLib يحتوي على select() على @commonlib//constraints:arm، سيؤدي ذلك إلى تشغيل أوضاع "arm" والمعايير ذات التوافق غير المتوافقة.

يتم الإعلان عن السمات الشائعة على مستوى العالم في إصدار @platforms (لذا يكون التصنيف الأساسي للمثال أعلاه هو @platforms//cpu:arm). ويجب الإعلان عن السمات الشائعة باللغة في نسخ اللغات المقابلة لها.

الأنظمة الأساسية التلقائية

وبشكل عام، على مالكي المشاريع تحديد المنصات الصريحة لوصف أنواع الأجهزة التي يريدون إنشاءها. ويتم تشغيلها بعد ذلك باستخدام --platforms.

في حال عدم ضبط --platforms، سيتم تلقائيًا ضبط Bazel على platform الذي يمثّل آلة البناء المحلية. يتم إنشاء هذا الاسم تلقائيًا في @local_config_platform//:host لذا لا حاجة إلى تعريفه صراحةً. وتربط هذه السمة الجهازَين المحليَين OS وCPU مع تضمين constraint_value في @platforms.

C++‎

تستخدم قواعد Bazel'++ الأنظمة الأساسية لاختيار سلاسل الأدوات عند ضبط --incompatible_enable_cc_toolchain_resolution (#7260).

وهذا يعني أنه يمكنك ضبط مشروع C++ باستخدام:

bazel build //:my_cpp_project --platforms=//:myplatform

بدلاً من الإصدار القديم:

bazel build //:my_cpp_project` --cpu=... --crosstool_top=...  --compiler=...

إذا كان مشروعك يعتمد على إصدار C++ فقط ولا يعتمد على مشاريع غير C++ ، يمكنك استخدام المنصات بأمان طالما أن select وعمليات النقل متوافقة. يمكنك الاطّلاع على #7260 و ضبط سلاسل أدوات C++ لمزيد من الإرشادات.

ولا يتم تفعيل هذا الوضع تلقائيًا. ويعود السبب في ذلك إلى أنّ مشاريع Apple لا تزال تنشئ ارتباطات C++ باستخدام --cpu و--crosstool_top (مثال). يعتمد ذلك على قواعد Apple في نقل البيانات إلى الأنظمة الأساسية.

Java

تستخدم قواعد Bazel’s Java المنصات.

وهذا يحل محل العلامات القديمة --java_toolchain و--host_java_toolchain و--javabase و--host_javabase.

للتعرُّف على كيفية استخدام علامات الضبط، راجِع دليل Bazel and Java. للحصول على معلومات إضافية، يمكنك الاطلاع على مستند التصميم.

إذا كنت لا تزال تستخدم علامات قديمة، اتّبِع عملية نقل البيانات في المشكلة #7849.

Android

تستخدم قواعد Android في Bazel منصّات اختيار سلاسل الأدوات عند إعداد --incompatible_enable_android_toolchain_resolution.

ولا يتم تفعيل هذه الميزة تلقائيًا. ولكن النقل سيتم قريبًا.

Apple

قواعد Bazel' لا تتوافق بعد مع الأنظمة الأساسية لاختيار سلاسل أدوات Apple.

ولا تتوافق هذه الأنظمة أيضًا مع تبعيات C++ التي تم تفعيلها على النظام الأساسي لأنها تستخدم --crosstool_top القديم لضبط سلسلة أدوات C++. وإلى أن يتم نقل هذه البيانات، يمكنك مزج مشاريع Apple مع C++ تم تفعيل الميزة على محرك بحثها مع عمليات ربط المنصات (مثال).

لغات أخرى

إذا كنت تصمّم قواعد للغة جديدة، استخدِم المنصّات لاختيار سلاسل لغتك. يمكنك الاطّلاع على مستندات سلاسل الأدوات للحصول على جولة تفصيلية جيدة.

select()

يمكن للمشاريع select() في constraint_value الاستهدافات وليس في الأنظمة الأساسية الكاملة. والهدف من ذلك هو توفير إمكانية التوافق مع select() على أوسع نطاق ممكن من الأجهزة. يجب أن تتوافق المكتبة التي تتضمّن مصادر ARM مع جميع الأجهزة التي تعمل بنظام التشغيل ARM ما لم يكن هناك سبب محدد أكثر.

لاختيار constraint_value أو أكثر، استخدِم:

config_setting(
    name = "is_arm",
    constraint_values = [
        "@platforms//cpu:arm",
    ],
)

يعادل ذلك الاختيار التقليدي على --cpu:

config_setting(
    name = "is_arm",
    values = {
        "cpu": "arm",
    },
)

يمكنك الاطّلاع على المزيد من التفاصيل هنا.

select على --cpu و--crosstool_top وما إلى ذلك، لا يفهمون --platforms. عند نقل بيانات مشروعك إلى الأنظمة الأساسية، يجب عليك تحويلها إلى constraint_values أو استخدام عمليات ربط النظام الأساسي لإتاحة كلا النمطين من خلال فترة نقل البيانات.

الانتقالات

تعمل عمليات النقل من Starlars على الإبلاغ عن أجزاء من الرسم البياني للإصدار. إذا كان مشروعك يستخدم عملية انتقال تضبط --cpu أو --crossstool_top أو علامات قديمة أخرى، لن تظهر هذه القواعد للقواعد الواردة في --platforms.

عند نقل بيانات مشروعك إلى الأنظمة الأساسية، عليك إما تغيير التغييرات، مثل return { "//command_line_option:cpu": "arm" } إلى return { "//command_line_option:platforms": "//:my_arm_platform" } أو استخدام عمليات ربط الأنظمة الأساسية لإتاحة كلا النمطَين من خلال نافذة نقل البيانات.

كيفية استخدام المنصّات اليوم

إذا أردت إنشاء مشروع أو تجميعه بشكل متبادل، يجب اتّباع المستندات الرسمية للمشروع. يعتمد الأمر على مشرفي اللغة ومشاريعه لتحديد كيفية الدمج مع المنصات، والقيمة التي يقدّمها.

إذا كنت تملك مشروعًا أو لغة أو أداة لسلسلة الأدوات وكان الإصدار الخاص بك لا يستخدم المنصات تلقائيًا، لديك ثلاثة خيارات (بالإضافة إلى انتظار نقل البيانات على مستوى العالم):

  1. اعرِض علامات الاقتباس على منصات "use;quot .; ، واختَر لغات المشروع (إذا كانت متوفّرة) وأجب عن أي اختبارات تحتاج إليها لمعرفة ما إذا كانت المشاريع التي تهمّك تنطبق على عملك.

  2. إذا كانت المشاريع التي تهمّك لا تزال تستند إلى علامات قديمة، مثل --cpu و--crosstool_top، يمكنك استخدامها مع --platforms:

    bazel build //:my_mixed_project --platforms==//:myplatform --cpu=... --crosstool_top=...
    

    وهذا يتطلب تكلفة صيانة (يجب التأكد من تطابق الإعدادات). ومن المفترض أن ينجح هذا الإجراء في حال عدم وجود انتقالات المرتقبة.

  3. اكتب عمليات ربط الأنظمة الأساسية لإتاحة استخدام كلا النمطين من خلال ضبط إعدادات نمط --cpu على الأنظمة الأساسية المقابلة والعكس صحيح.

تعيينات النظام الأساسي

عمليات ربط الأنظمة الأساسية هي واجهة برمجة تطبيقات مؤقتة تتيح عمل المنطق القائم على النظام الأساسي والقديم على الإصدار نفسه من خلال فترة الإيقاف الأخير.

إنّ تعيين النظام الأساسي عبارة عن خريطة لـ platform() لمجموعة من العلامات المتوافقة أو العكس. مثلاً:

platforms:
  # Maps "--platforms=//platforms:ios" to "--cpu=ios_x86_64 --apple_platform_type=ios".
  //platforms:ios
    --cpu=ios_x86_64
    --apple_platform_type=ios

flags:
  # Maps "--cpu=ios_x86_64 --apple_platform_type=ios" to "--platforms=//platforms:ios".
  --cpu=ios_x86_64
  --apple_platform_type=ios
    //platforms:ios

  # Maps "--cpu=darwin --apple_platform_type=macos" to "//platform:macos".
  --cpu=darwin
  --apple_platform_type=macos
    //platforms:macos

يستخدم Bazel هذا لضمان تطبيق جميع الإعدادات، سواء المستندة إلى المنصة أو القديمة، باستمرار في جميع أنحاء الإصدار، بما في ذلك من خلال عمليات النقل.

يقرأ Bazel عمليات الربط تلقائيًا من ملف platform_mappings في جذر مساحة العمل. يمكنك أيضًا ضبط --platform_mappings=//:my_custom_mapping.

يمكنك الاطّلاع هنا على التفاصيل الكاملة.

أسئلة

للحصول على الدعم والأسئلة العامة حول المخطط الزمني لعملية النقل، يُرجى التواصل مع bazel-مناقشة@googlegroups.com أو مالكي القواعد المناسبة.

للاطّلاع على مناقشات حول تصميم واجهات برمجة التطبيقات للأنظمة الأساسية/الأدوات وتطورها، يمكنك التواصل مع bazel-dev@googlegroups.com.

راجع أيضًا