प्लैटफ़ॉर्म

किसी समस्या की शिकायत करें सोर्स देखें Nightly · 7.4 . 7.3 · 7.2 · 7.1 · 7.0 · 6.5

Baज़ल, बिल्ड टूल के कई अलग-अलग वर्शन, जैसे कि लिंकर और कंपाइलर का इस्तेमाल करके, कई तरह के हार्डवेयर, ऑपरेटिंग सिस्टम, और सिस्टम कॉन्फ़िगरेशन पर कोड बना सकता है और उनकी जांच कर सकता है. इस जटिलता को मैनेज करने में मदद करने के लिए, Bazel में सीमाओं और प्लैटफ़ॉर्म का कॉन्सेप्ट है. कंस्ट्रेंट ऐसा डाइमेंशन होता है जिसमें बिल्ड या प्रोडक्शन एनवायरमेंट में अंतर हो सकता है. जैसे, सीपीयू का आर्किटेक्चर, जीपीयू का मौजूद न होना या उसका न होना या सिस्टम पर इंस्टॉल किए गए कंपाइलर का वर्शन. प्लैटफ़ॉर्म, इन पाबंदियों के लिए विकल्पों का एक नाम दिया गया कलेक्शन होता है. यह किसी एनवायरमेंट में उपलब्ध खास संसाधनों को दिखाता है.

एनवायरमेंट को एक प्लैटफ़ॉर्म के तौर पर मॉडल करने से, Baze को अपने-आप सही टूलचेन चुनने में मदद मिलती है. कॉन्फ़िगर किए जा सकने वाले एट्रिब्यूट लिखने के लिए, प्लैटफ़ॉर्म का इस्तेमाल config_setting नियम के साथ भी किया जा सकता है.

बेज़ल इन तीन भूमिकाओं को समझते हैं जो एक प्लैटफ़ॉर्म पूरा कर सकता है:

  • होस्ट - वह प्लैटफ़ॉर्म जिस पर Bazel खुद चलता है.
  • एक्सीक्यूशन - यह एक ऐसा प्लैटफ़ॉर्म है जिस पर बिल्ड टूल, बिल्ड ऐक्शन को लागू करते हैं, ताकि इंटरमीडिएट और फ़ाइनल आउटपुट तैयार किए जा सकें.
  • टारगेट - वह प्लैटफ़ॉर्म जिस पर फ़ाइनल आउटपुट सेव होता है और लागू होता है.

प्लैटफ़ॉर्म के हिसाब से, Basel के बिल्ड की इन स्थितियों को सपोर्ट किया जा सकता है:

  • सिंगल-प्लैटफ़ॉर्म बिल्ड (डिफ़ॉल्ट) - होस्ट, एक्सीक्यूशन, और टारगेट प्लैटफ़ॉर्म एक ही होते हैं. उदाहरण के लिए, Intel x64 सीपीयू पर चलने वाले Ubuntu पर, Linux के लिए बने किसी प्रोग्राम को बनाना.

  • क्रॉस-कंपाइलेशन बिल्ड - होस्ट और एक्सीक्यूशन प्लैटफ़ॉर्म एक ही होते हैं, लेकिन टारगेट प्लैटफ़ॉर्म अलग होता है. उदाहरण के लिए, MacBook Pro पर macOS पर चलने वाला iOS ऐप्लिकेशन बनाना.

  • मल्टी-प्लैटफ़ॉर्म बिल्ड - होस्ट, एक्ज़ीक्यूशन, और टारगेट प्लैटफ़ॉर्म सभी अलग-अलग होते हैं.

सीमाओं और प्लैटफ़ॉर्म तय करना

BUILD फ़ाइलों में, constraint_setting और constraint_value नियमों के हिसाब से, प्लैटफ़ॉर्म के विकल्प चुने जा सकते हैं. constraint_setting एक नया डाइमेंशन बनाता है, जबकि constraint_value किसी दिए गए डाइमेंशन के लिए एक नई वैल्यू बनाता है. साथ में, ये एक 'एनम' और उसकी संभावित वैल्यू को असरदार तरीके से तय करते हैं. उदाहरण के लिए, BUILD फ़ाइल का यह स्निपेट, सिस्टम के glibc वर्शन के लिए एक शर्त बताता है. इसमें दो संभावित वैल्यू दी गई हैं.

constraint_setting(name = "glibc_version")

constraint_value(
    name = "glibc_2_25",
    constraint_setting = ":glibc_version",
)

constraint_value(
    name = "glibc_2_26",
    constraint_setting = ":glibc_version",
)

वर्कस्पेस में अलग-अलग पैकेज में, कंस्ट्रेंट और उनकी वैल्यू के बारे में बताया जा सकता है. इनका रेफ़रंस लेबल से दिया जाता है और इन्हें दिखने के लिए, आम तौर पर लागू होने वाले कंट्रोल का इस्तेमाल किया जाता है. अगर विज्ञापन दिखने की सेटिंग की अनुमति है, तो आपके पास किसी मौजूदा पाबंदी की सेटिंग को बढ़ाने का विकल्प है. इसके लिए, आपको अपनी वैल्यू तय करनी होगी.

platform नियम से, एक नया प्लैटफ़ॉर्म शुरू होता है. इसमें, पाबंदी की वैल्यू के कुछ विकल्प होते हैं. यहां दिए गए उदाहरण में, linux_x86 नाम का प्लैटफ़ॉर्म बनाया गया है. साथ ही, यह भी बताया गया है कि यह किसी भी ऐसे एनवायरमेंट के बारे में बताता है जो x86_64 आर्किटेक्चर पर, 2.25 वर्शन के glibc के साथ Linux ऑपरेटिंग सिस्टम चलाता है. (Bazel में पहले से मौजूद पाबंदियों के बारे में ज़्यादा जानने के लिए, नीचे देखें.)

platform(
    name = "linux_x86",
    constraint_values = [
        "@platforms//os:linux",
        "@platforms//cpu:x86_64",
        ":glibc_2_25",
    ],
)

आम तौर पर काम की शर्तें और प्लैटफ़ॉर्म

नेटवर्क को एक जैसा बनाए रखने के लिए, Bazel टीम सबसे लोकप्रिय सीपीयू आर्किटेक्चर और ऑपरेटिंग सिस्टम के लिए, पाबंदी की परिभाषाओं के साथ एक रिपॉज़िटरी बनाए रखती है. ये सभी https://github.com/bazelbuild/platforms पर मौजूद हैं.

बेज़ल, इस खास प्लैटफ़ॉर्म की परिभाषा के साथ शिप करता है: @platforms//host (इसे @bazel_tools//tools:host_platform भी कहा जाता है). यह होस्ट प्लैटफ़ॉर्म की अपने-आप पहचानी गई वैल्यू है. यह उस प्लैटफ़ॉर्म के लिए अपने-आप पता लगाए गए प्लैटफ़ॉर्म के बारे में बताती है जिस पर Basel चल रहा है.

किसी बिल्ड के लिए प्लैटफ़ॉर्म तय करना

किसी बिल्ड के लिए होस्ट और टारगेट प्लैटफ़ॉर्म तय करने के लिए, यहां दिए गए कमांड-लाइन फ़्लैग का इस्तेमाल किया जा सकता है:

  • --host_platform - डिफ़ॉल्ट रूप से @bazel_tools//tools:host_platform होता है
    • इस टारगेट का दूसरा नाम @platforms//host है. यह टारगेट, एक रिपॉज़िट्री नियम के आधार पर काम करता है. यह नियम, होस्ट ओएस और सीपीयू का पता लगाता है और प्लैटफ़ॉर्म टारगेट को लिखता है.
    • @platforms//host:constraints.bzl भी है, जो HOST_CONSTRAINTS नाम का एक कलेक्शन दिखाता है. इसका इस्तेमाल, अन्य BUILD और Starlark फ़ाइलों में किया जा सकता है.
  • --platforms - होस्ट प्लैटफ़ॉर्म को डिफ़ॉल्ट रूप से सेट करता है
    • इसका मतलब है कि जब कोई दूसरा फ़्लैग सेट नहीं होता है, तो @platforms//host टारगेट प्लैटफ़ॉर्म होता है.
    • अगर --host_platform सेट है और --platforms नहीं है, तो --host_platform की वैल्यू, होस्ट और टारगेट प्लैटफ़ॉर्म, दोनों होती है.

काम न करने वाले टारगेट को स्किप किया जा रहा है

किसी खास टारगेट प्लैटफ़ॉर्म के लिए बिल्ड करते समय, अक्सर उन टारगेट को स्किप करना बेहतर होता है जो उस प्लैटफ़ॉर्म पर कभी काम नहीं करेंगे. उदाहरण के लिए, //... के साथ Linux मशीन पर बिल्ड करते समय, आपके Windows डिवाइस ड्राइवर से कई कंपाइलर गड़बड़ियां जनरेट हो सकती हैं. Bazel को यह बताने के लिए कि आपके कोड में टारगेट प्लैटफ़ॉर्म से जुड़ी कौनसी पाबंदियां हैं, target_compatible_with एट्रिब्यूट का इस्तेमाल करें.

इस एट्रिब्यूट का सबसे आसान इस्तेमाल, किसी टारगेट को सिर्फ़ एक प्लैटफ़ॉर्म पर सीमित करता है. सभी शर्तों को पूरा न करने वाले किसी भी प्लैटफ़ॉर्म के लिए टारगेट नहीं बनाया जाएगा. नीचे दिए गए उदाहरण में, win_driver_lib.cc को 64-बिट Windows पर इस्तेमाल करने की अनुमति नहीं है.

cc_library(
    name = "win_driver_lib",
    srcs = ["win_driver_lib.cc"],
    target_compatible_with = [
        "@platforms//cpu:x86_64",
        "@platforms//os:windows",
    ],
)

:win_driver_lib, सिर्फ़ 64-बिट वाली विंडो पर काम करता है और अन्य सभी डिवाइसों के साथ काम नहीं करता है. एक-दूसरे के साथ काम न करने की समस्या, एक से ज़्यादा डिवाइसों पर हो सकती है. ऐसे सभी टारगेट जिन्हें काम न करने वाले टारगेट पर ट्रांज़िटिव तरीके से निर्भर किया गया है उन्हें भी काम न करने वाला माना जाता है.

टारगेट कब स्किप किए जाते हैं?

अगर टारगेट को काम का नहीं माना जाता है, तो उन्हें स्किप कर दिया जाता है. साथ ही, उन्हें टारगेट पैटर्न एक्सपैंशन के हिस्से के तौर पर बिल्ड में शामिल किया जाता है. उदाहरण के लिए, नीचे दिए गए दो invocatio, टारगेट पैटर्न के एक्सपैंशन में मिले ऐसे सभी टारगेट को स्किप कर देते हैं जो काम नहीं करते.

$ bazel build --platforms=//:myplatform //...
$ bazel build --platforms=//:myplatform //:all

अगर कमांड लाइन पर --expand_test_suites के साथ test_suite को बताया गया है, तो test_suite के लिए बेमेल टेस्ट भी स्किप कर दिए जाते हैं. दूसरे शब्दों में, कमांड लाइन पर test_suite टारगेट, :all और ... की तरह काम करते हैं. --noexpand_test_suites का इस्तेमाल करने से, प्रॉपर्टी को बड़ा होने से रोका जा सकता है. साथ ही, काम न करने वाले टेस्ट वाले test_suite टारगेट भी काम नहीं करते हैं.

कमांड-लाइन पर काम न करने वाले टारगेट को साफ़ तौर पर बताने पर, गड़बड़ी का मैसेज दिखता है और बिल्ड नहीं होता.

$ bazel build --platforms=//:myplatform //:target_incompatible_with_myplatform
...
ERROR: Target //:target_incompatible_with_myplatform is incompatible and cannot be built, but was explicitly requested.
...
FAILED: Build did NOT complete successfully

अगर --skip_incompatible_explicit_targets चालू है, तो काम न करने वाले साफ़ तौर पर बताए गए टारगेट को चुपचाप छोड़ दिया जाता है.

ज़्यादा जानकारी देने वाली पाबंदियां

शर्तें तय करने में ज़्यादा आसानी के लिए, @platforms//:incompatible constraint_value का इस्तेमाल करें, जो कोई भी प्लैटफ़ॉर्म पूरा नहीं करता.

ज़्यादा जटिल पाबंदियां बताने के लिए, select() के साथ @platforms//:incompatible का इस्तेमाल करें. जैसे, बेसिक OR लॉजिक को लागू करने के लिए इसका इस्तेमाल करें. यहां दी गई लाइब्रेरी, macOS और Linux के साथ काम करती है, लेकिन किसी दूसरे प्लैटफ़ॉर्म के साथ नहीं.

cc_library(
    name = "unixish_lib",
    srcs = ["unixish_lib.cc"],
    target_compatible_with = select({
        "@platforms//os:osx": [],
        "@platforms//os:linux": [],
        "//conditions:default": ["@platforms//:incompatible"],
    }),
)

ऊपर दिए गए शब्दों का मतलब इस तरह समझा जा सकता है:

  1. macOS को टारगेट करते समय, टारगेट पर कोई पाबंदी नहीं होती.
  2. Linux को टारगेट करते समय, टारगेट पर कोई पाबंदी नहीं होती.
  3. ऐसा नहीं होने पर, टारगेट में @platforms//:incompatible कंस्ट्रेंट है. @platforms//:incompatible किसी भी प्लैटफ़ॉर्म का हिस्सा नहीं है. इसलिए, इसे टारगेट के साथ काम नहीं करता है.

अपनी सीमाओं को पढ़ने में आसान बनाने के लिए, skylib के selects.with_or() का इस्तेमाल करें.

इनवर्स कंपैटबिलिटी को भी इसी तरह दिखाया जा सकता है. यहां दिए गए उदाहरण में, एक ऐसी लाइब्रेरी के बारे में बताया गया है जो ARM के अलावा सभी प्लैटफ़ॉर्म के साथ काम करती है.

cc_library(
    name = "non_arm_lib",
    srcs = ["non_arm_lib.cc"],
    target_compatible_with = select({
        "@platforms//cpu:arm": ["@platforms//:incompatible"],
        "//conditions:default": [],
    }),
)

bazel cquery का इस्तेमाल करके, काम न करने वाले टारगेट का पता लगाना

काम न करने वाले टारगेट और काम न करने वाले टारगेट के बीच फ़र्क़ करने के लिए, bazel cquery के Starlark आउटपुट फ़ॉर्मैट में IncompatiblePlatformProvider का इस्तेमाल किया जा सकता है.

इसका इस्तेमाल करके, ऐसे टारगेट को फ़िल्टर किया जा सकता है जो काम नहीं करते. नीचे दिए गए उदाहरण में, सिर्फ़ उन टारगेट के लेबल प्रिंट होंगे जो साथ काम करते हैं. काम न करने वाले टारगेट को प्रिंट नहीं किया जाता.

$ cat example.cquery

def format(target):
  if "IncompatiblePlatformProvider" not in providers(target):
    return target.label
  return ""


$ bazel cquery //... --output=starlark --starlark:file=example.cquery

आम समस्याएं

काम न करने वाले टारगेट, प्रॉडक्ट दिखने से जुड़ी पाबंदियों को अनदेखा करते हैं.