प्लैटफ़ॉर्म

संग्रह की मदद से व्यवस्थित रहें अपनी प्राथमिकताओं के आधार पर, कॉन्टेंट को सेव करें और कैटगरी में बांटें.
समस्या की शिकायत करें स्रोत देखें

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

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

बैज़ेल, प्लैटफ़ॉर्म से जुड़ी तीन खास भूमिकाओं को जानते हैं:

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

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

  • एक प्लैटफ़ॉर्म वाले बिल्ड (डिफ़ॉल्ट) - होस्ट, एक्ज़ीक्यूशन, और टारगेट किए गए प्लैटफ़ॉर्म एक जैसे होते हैं. उदाहरण के लिए, Intel x64 CPU पर चल रहे 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 नाम का एक प्लैटफ़ॉर्म बनता है. वह बताता है कि यह ऐसे किसी भी एनवायरमेंट के बारे में बताता है जो Linux ऑपरेटिंग सिस्टम पर, x86_64 आर्किटेक्चर के 2.25 वर्शन के वर्शन के साथ चलता है. (Bzel के पहले से मौजूद कंस्ट्रेंट के बारे में ज़्यादा जानने के लिए नीचे देखें.)

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

आम तौर पर काम आने वाले कंस्ट्रेंट और प्लैटफ़ॉर्म

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

Bazel शिप करने के लिए, इन खास प्लैटफ़ॉर्म का इस्तेमाल किया गया है: @local_config_platform//:host. यह अपने-आप पहचानी गई होस्ट प्लैटफ़ॉर्म वैल्यू है - Bazel के चलने वाले सिस्टम के लिए अपने-आप पता लगाए गए प्लैटफ़ॉर्म का प्रतिनिधित्व करता है.

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

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

  • --host_platform - डिफ़ॉल्ट तौर पर @bazel_tools//platforms:host_platform
  • --platforms - डिफ़ॉल्ट तौर पर @bazel_tools//platforms:target_platform

काम न करने वाले टारगेट को छोड़ना

किसी खास टारगेट प्लैटफ़ॉर्म को बनाने के दौरान, अक्सर उन लक्ष्यों को छोड़कर आगे बढ़ना चाहिए जो उस प्लैटफ़ॉर्म पर कभी काम नहीं करते. उदाहरण के लिए, //... के साथ Linux मशीन बनाते समय, आपके Windows डिवाइस ड्राइवर को कई कंपाइलर गड़बड़ियां जनरेट हो सकती हैं. 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-बिट Windows वाले कंप्यूटर के साथ काम करने वाला है और बाकी सभी के साथ काम नहीं करता है. साथ काम नहीं करता. कोई भी ऐसा टारगेट जो कुछ समय के लिए किसी काम न करने वाले टारगेट पर निर्भर करता है उसे खुद काम नहीं करने वाला माना जाता है.

टारगेट कब छोड़े जाते हैं?

टारगेट के काम न करने पर, उन्हें छोड़ दिया जाता है. उदाहरण के लिए, नीचे दिए गए दो शुरू करने पर, टारगेट पैटर्न एक्सपैंशन में मिलने वाले किसी भी काम के टारगेट को छोड़ दिया जाता है.

$ 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

ज़्यादा एक्सप्रेसिव कंस्ट्रेंट

कंस्ट्रेंट को और आसानी से बताने के लिए, @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

समस्याएं जिनके बारे में जानकारी है

काम न करने वाले टारगेट दिखने की पाबंदियों पर ध्यान नहीं देते हैं.