Bazel, लिंकर और कंपाइलर जैसे बिल्ड टूल के कई वर्शन का इस्तेमाल करके कई तरह के हार्डवेयर, ऑपरेटिंग सिस्टम, और सिस्टम कॉन्फ़िगरेशन पर कोड बना सकता है और उसकी जांच कर सकता है. इस जटिलता को मैनेज करने के लिए, बेज़ेल ने सीमाओं और प्लैटफ़ॉर्म के कॉन्सेप्ट को चुना है. कंस्ट्रेंट, एक ऐसा डाइमेंशन होता है जिसमें बिल्ड या प्रोडक्शन एनवायरमेंट अलग-अलग हो सकते हैं. जैसे, सीपीयू का आर्किटेक्चर, जीपीयू का होना या न होना या सिस्टम से इंस्टॉल किए गए कंपाइलर का वर्शन. एक प्लैटफ़ॉर्म इन सीमाओं के लिए विकल्पों का एक नाम संग्रह है, जो कुछ परिवेशों में उपलब्ध खास संसाधनों को दिखाता है.
प्लैटफ़ॉर्म को मॉडल के तौर पर मॉडल करने से, Bazel को सही कार्रवाइयों के लिए, सही टूलचेन चुनने में मदद मिलती है. कॉन्फ़िगर करने लायक एट्रिब्यूट लिखने के लिए, प्लैटफ़ॉर्म का इस्तेमाल config_setting नियम के साथ भी किया जा सकता है.
Bazel इन तीन भूमिकाओं की पहचान करता है:
- होस्ट - वह प्लैटफ़ॉर्म जिस पर Bazel चलता है.
- एक्ज़ीक्यूशन - एक प्लैटफ़ॉर्म जिस पर बिल्ड टूल बीच के और आखिरी आउटपुट बनाने के लिए बिल्ड की कार्रवाइयां करते हैं.
- टारगेट - एक प्लैटफ़ॉर्म जिस पर आखिरी आउटपुट रहता है और एक्ज़ीक्यूट होता है.
Bazel इन प्लैटफ़ॉर्म के साथ काम करता है:
एक प्लैटफ़ॉर्म वाले बिल्ड (डिफ़ॉल्ट) - होस्ट, एक्ज़ीक्यूशन, और टारगेट प्लैटफ़ॉर्म एक जैसे होते हैं. उदाहरण के लिए, 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 आर्किटेक्चर पर Linux ऑपरेटिंग सिस्टम पर चलने वाले सभी एनवायरमेंट के बारे में जानकारी देता है. यह आर्किटेक्चर 2.25 वर्शन का glic वर्शन होता है. (B प्लान में पहले से मौजूद पाबंदियों के बारे में ज़्यादा जानकारी के लिए नीचे देखें.)
platform(
name = "linux_x86",
constraint_values = [
"@platforms//os:linux",
"@platforms//cpu:x86_64",
":glibc_2_25",
],
)
आम तौर पर, काम की कंस्ट्रेंट और प्लैटफ़ॉर्म
नेटवर्क को एक जैसा बनाए रखने के लिए, Bazel की टीम एक रिपॉज़िटरी बनाए रखती है, जिसमें सबसे लोकप्रिय सीपीयू आर्किटेक्चर और ऑपरेटिंग सिस्टम के लिए, तय सीमा का ध्यान रखा जाता है. ये सभी 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
एट्रिब्यूट का इस्तेमाल करके Bazel को बताएं कि आपके कोड में किस तरह के टारगेट प्लैटफ़ॉर्म की सीमाएं हैं.
इस एट्रिब्यूट का सबसे आसान इस्तेमाल, टारगेट को एक ही प्लैटफ़ॉर्म पर लागू नहीं करता.
टारगेट को ऐसे किसी भी प्लैटफ़ॉर्म के लिए नहीं बनाया जाएगा जो सभी शर्तों का पालन न करता हो. नीचे दिए गए उदाहरण में 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
अगर test_suite
के साथ काम न करने वाले टेस्ट
--expand_test_suites
के साथ कमांड लाइन पर तय किए गए हैं, तो को काम नहीं करता.
दूसरे शब्दों में, कमांड लाइन पर 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"],
}),
)
ऊपर दिए गए तरीके से समझा जा सकता है कि:
- macOS को टारगेट करते समय, टारगेट में कोई रुकावट नहीं होती.
- Linux को टारगेट करते समय, टारगेट की कोई सीमा नहीं होती.
- नहीं तो, टारगेट में
@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
समस्याएं जिनके बारे में जानकारी है
काम न करने वाले टारगेट किसको दिखेपाबंदियों को अनदेखा करते हैं.