इस पेज पर टूलचेन फ़्रेमवर्क के बारे में बताया गया है. यह फ़्रेमवर्क, नियम बनाने वाले लोगों के लिए प्लैटफ़ॉर्म के हिसाब से उपलब्ध टूल की मदद से, उनके नियमों का तर्क तय करने का तरीका है. जारी रखने से पहले, यह सुझाव दिया जाता है कि आप नियम और प्लैटफ़ॉर्म पेज पढ़ लें. इस पेज पर बताया गया है कि टूलचेन की ज़रूरत क्यों है, टूल को कैसे तय करें, और उसका इस्तेमाल कैसे करें. साथ ही, यह भी जानें कि बेज़ल प्लैटफ़ॉर्म की पाबंदियों के आधार पर सही टूलचेन का चुनाव कैसे करता है.
वजह
आइए सबसे पहले उन समस्या हल करने वाले टूल पर बात करें जिन्हें हल करने के लिए डिज़ाइन किया गया है. मान लें कि
आप "बार" प्रोग्रामिंग भाषा का समर्थन करने के लिए नियम लिख रहे हैं. आपका bar_binary
नियम, barc
कंपाइलर का इस्तेमाल करके *.bar
फ़ाइलें कंपाइल करेगा. यह ऐसा टूल है जो आपके फ़ाइल फ़ोल्डर में
दूसरे टारगेट के तौर पर बनाया गया है. bar_binary
टारगेट लिखने वाले उपयोगकर्ताओं को कंपाइलर पर डिपेंडेंसी के बारे में नहीं बताना चाहिए. इसलिए, इसे नियम की परिभाषा में निजी एट्रिब्यूट के तौर पर जोड़ें.
bar_binary = rule(
implementation = _bar_binary_impl,
attrs = {
"srcs": attr.label_list(allow_files = True),
...
"_compiler": attr.label(
default = "//bar_tools:barc_linux", # the compiler running on linux
providers = [BarcInfo],
),
},
)
//bar_tools:barc_linux
अब हर bar_binary
टारगेट के लिए एक डिपेंडेंसी है. इसलिए, इसे किसी भी bar_binary
टारगेट से पहले बनाया जाएगा. इसे किसी भी दूसरे एट्रिब्यूट की तरह, नियम लागू करने वाले फ़ंक्शन से ऐक्सेस किया जा सकता है:
BarcInfo = provider(
doc = "Information about how to invoke the barc compiler.",
# In the real world, compiler_path and system_lib might hold File objects,
# but for simplicity they are strings for this example. arch_flags is a list
# of strings.
fields = ["compiler_path", "system_lib", "arch_flags"],
)
def _bar_binary_impl(ctx):
...
info = ctx.attr._compiler[BarcInfo]
command = "%s -l %s %s" % (
info.compiler_path,
info.system_lib,
" ".join(info.arch_flags),
)
...
यहां समस्या यह है कि कंपाइलर का लेबल bar_binary
में हार्डकोड कर दिया गया है. हालांकि,
अलग-अलग टारगेट को इस बात के आधार पर अलग-अलग कंपाइल करने की ज़रूरत हो सकती है कि
वे किस प्लैटफ़ॉर्म के लिए बनाए जा रहे हैं और किस प्लैटफ़ॉर्म पर बनाए जा रहे हैं -- इसे
टारगेट प्लैटफ़ॉर्म और प्लानिंग प्लैटफ़ॉर्म कहते हैं. इसके अलावा, ज़रूरी नहीं है कि नियम
लेखक को सभी उपलब्ध टूल और प्लैटफ़ॉर्म के बारे में पता हो, इसलिए इसे नियम की परिभाषा में हार्डकोड नहीं किया जा सकता.
ज़रूरत से कम समाधान यह होगा कि _compiler
एट्रिब्यूट को निजी बनाया जाए. फिर अलग-अलग प्लैटफ़ॉर्म को एक या
एक प्लैटफ़ॉर्म बनाने के लिए हार्डकोड किया जा सकता है.
bar_binary(
name = "myprog_on_linux",
srcs = ["mysrc.bar"],
compiler = "//bar_tools:barc_linux",
)
bar_binary(
name = "myprog_on_windows",
srcs = ["mysrc.bar"],
compiler = "//bar_tools:barc_windows",
)
इस प्लैटफ़ॉर्म को बेहतर बनाने के लिए, select
का इस्तेमाल करें और प्लैटफ़ॉर्म के हिसाब से compiler
चुनें.
config_setting(
name = "on_linux",
constraint_values = [
"@platforms//os:linux",
],
)
config_setting(
name = "on_windows",
constraint_values = [
"@platforms//os:windows",
],
)
bar_binary(
name = "myprog",
srcs = ["mysrc.bar"],
compiler = select({
":on_linux": "//bar_tools:barc_linux",
":on_windows": "//bar_tools:barc_windows",
}),
)
हालांकि, यह मुश्किल है और हर bar_binary
उपयोगकर्ता से थोड़ा पूछने की ज़रूरत है.
अगर पूरे फ़ाइल फ़ोल्डर में इस स्टाइल का लगातार इस्तेमाल नहीं किया गया है, तो एक ही प्लैटफ़ॉर्म पर कई ऐसे काम होते हैं जो एक ही जगह पर ठीक से काम करते हैं. हालांकि, एक से ज़्यादा प्लैटफ़ॉर्म पर इस्तेमाल करने पर ये स्टाइल काम नहीं करते. यह मौजूदा नियमों या टारगेट में बदलाव किए बिना, नए प्लैटफ़ॉर्म और कंपाइलर के लिए सहायता जोड़ने से जुड़ी समस्या को भी हल नहीं करता.
टूलचेन फ़्रेमवर्क, निर्देश का एक अतिरिक्त स्तर जोड़कर इस समस्या का समाधान करता है. ज़रूरी तौर पर यह बताया गया हो कि टारगेट (टूलचेन टाइप) के किसी फ़ैमिली ग्रुप के कुछ सदस्य के पास, आपके नियम का ऐब्सट्रैक्ट डिपेंडेंसी है. इसके अलावा, बेज़ल लागू होने वाले प्लैटफ़ॉर्म की सीमाओं के आधार पर, इसे अपने-आप एक खास टारगेट (टूलचेन) पर हल कर देता है. नियम के लेखक और टारगेट लेखक को उपलब्ध प्लैटफ़ॉर्म और टूल चेन के पूरे सेट की जानकारी नहीं होनी चाहिए.
लिखने के नियम, जो टूल चेन का इस्तेमाल करते हैं
टूलचेन फ़्रेमवर्क के तहत, नियम होने के बजाय वे सीधे टूल पर निर्भर होते हैं, इसके बजाय वे टूलचेन टाइप पर निर्भर होते हैं. टूलचेन टाइप एक आसान टारगेट है. यह टूल की ऐसी क्लास को दिखाता है जो अलग-अलग प्लैटफ़ॉर्म के लिए एक ही भूमिका निभाती है. उदाहरण के लिए, बार बार कंपाइलर को दिखाने वाले टाइप का एलान किया जा सकता है:
# By convention, toolchain_type targets are named "toolchain_type" and
# distinguished by their package path. So the full path for this would be
# //bar_tools:toolchain_type.
toolchain_type(name = "toolchain_type")
पिछले सेक्शन में नियमों की परिभाषा में बदलाव किया गया है. इसलिए, कंपाइलर को एट्रिब्यूट के तौर पर जोड़ने के बजाय, यह एलान करता है कि यह //bar_tools:toolchain_type
टूलचेन का इस्तेमाल करता है.
bar_binary = rule(
implementation = _bar_binary_impl,
attrs = {
"srcs": attr.label_list(allow_files = True),
...
# No `_compiler` attribute anymore.
},
toolchains = ["//bar_tools:toolchain_type"],
)
लागू करने का फ़ंक्शन अब टूल के प्रकार के तौर पर ctx.attr
के बजाय, ctx.toolchains
के तहत इस डिपेंडेंसी को ऐक्सेस करता है.
def _bar_binary_impl(ctx):
...
info = ctx.toolchains["//bar_tools:toolchain_type"].barcinfo
# The rest is unchanged.
command = "%s -l %s %s" % (
info.compiler_path,
info.system_lib,
" ".join(info.arch_flags),
)
...
ctx.toolchains["//bar_tools:toolchain_type"]
किसी भी लक्ष्य बैज़ल ने टूलचेन निर्भरता का समाधान
ToolchainInfo
कंपनी
से किया. ToolchainInfo
ऑब्जेक्ट के फ़ील्ड, मूल टूल के नियम से सेट होते हैं. अगले सेक्शन में, इस नियम को इस तरह से दिखाया गया है कि BarcInfo
ऑब्जेक्ट को रैप करने वाला barcinfo
फ़ील्ड मौजूद हो.
टारगेट के लिए टूलचेन का समाधान करने के लिए, बेज़ल की प्रोसेस
नीचे दी गई है. असल में, समाधान किया गया टूलचेन टारगेट असल में, bar_binary
टारगेट पर निर्भर करता है, न कि कैंडिडेट टूलचेन के लिए.
ज़रूरी और वैकल्पिक टूलचेन
डिफ़ॉल्ट रूप से, जब कोई नियम सिर्फ़ लेबल के ज़रिए टूलचेन प्रकार की निर्भरता दिखाता है (जैसा कि ऊपर दिखाया गया है), तो टूलचेन प्रकार को ज़रूरी माना जाता है. अगर बैज़ेल किसी ज़रूरी टूलचेन टाइप के लिए, मिलता-जुलता टूलचेन नहीं मिल पाता है (नीचे टूलचेन रिज़ॉल्यूशन देखें) तो यह एक गड़बड़ी है और विश्लेषण रुक जाता है.
इसके बजाय, नीचे दिए गए तरीके से वैकल्पिक टूलचेन प्रकार का एलान करना संभव है:
bar_binary = rule(
...
toolchains = [
config_common.toolchain_type("//bar_tools:toolchain_type", mandatory = False),
],
)
जब वैकल्पिक टूलचेन टाइप से जुड़ी समस्या को हल नहीं किया जा सकता, तब विश्लेषण जारी रहता है
और ctx.toolchains["//bar_tools:toolchain_type"]
का नतीजा None
होता है.
config_common.toolchain_type
फ़ंक्शन डिफ़ॉल्ट रूप से ज़रूरी होता है.
इन फ़ॉर्म का इस्तेमाल किया जा सकता है:
- ज़रूरी टूलचेन टाइप:
toolchains = ["//bar_tools:toolchain_type"]
toolchains = [config_common.toolchain_type("//bar_tools:toolchain_type")]
toolchains = [config_common.toolchain_type("//bar_tools:toolchain_type", mandatory = True)]
- वैकल्पिक टूलचेन टाइप:
toolchains = [config_common.toolchain_type("//bar_tools:toolchain_type", mandatory = False)]
bar_binary = rule(
...
toolchains = [
"//foo_tools:toolchain_type",
config_common.toolchain_type("//bar_tools:toolchain_type", mandatory = False),
],
)
आप एक ही नियम में फ़ॉर्म मिला सकते हैं और उनका मिलान भी कर सकते हैं. हालांकि, अगर एक ही टूलचेन प्रकार को एक से ज़्यादा बार सूचीबद्ध किया गया है, तो यह सबसे सख्त वर्शन को ही लेगा, ज़रूरी होने की तुलना में ज़्यादा सख्त.
लिखने के अलग-अलग पहलू जो टूलचेन का इस्तेमाल करते हैं
आसपेक्ट के पास, एक जैसे टूलचेन एपीआई का ऐक्सेस उन नियमों के मुताबिक होता है जो:
bar_aspect = aspect(
implementation = _bar_aspect_impl,
attrs = {},
toolchains = ['//bar_tools:toolchain_type'],
)
def _bar_aspect_impl(target, ctx):
toolchain = ctx.toolchains['//bar_tools:toolchain_type']
# Use the toolchain provider like in a rule.
return []
टूलचेन को परिभाषित करना
किसी टूलचेन प्रकार के लिए कुछ टूलचेन तय करने के लिए, आपको तीन चीज़ों की ज़रूरत होगी:
टूल या टूल सुइट किस तरह का है, यह दिखाने वाला भाषा से जुड़ा नियम. कन्वेंशन के मुताबिक, इस नियम के नाम के आगे "_toolchain" लगा है.
- ध्यान दें:
\_toolchain
नियम बनाने की कोई कार्रवाई नहीं की जा सकती. बल्कि, यह अन्य नियमों से आर्टफ़ैक्ट इकट्ठा करता है और उन्हें उस नियम पर भेजता है जो टूलचेन का इस्तेमाल करता है. यह नियम बिल्ड की सभी कार्रवाइयों के लिए ज़िम्मेदार है.
- ध्यान दें:
इस तरह के नियम के कई टारगेट, अलग-अलग प्लैटफ़ॉर्म के लिए टूल या टूल सुइट के वर्शन दिखाते हैं.
इस तरह के हर टारगेट के लिए, सामान्य
toolchain
नियम का एक असोसिएट टारगेट, ताकि टूलचेन फ़्रेमवर्क में इस्तेमाल किया गया मेटाडेटा दिया जा सके.toolchain
इस टारगेट का मतलब इस टूलचेन से जुड़ेtoolchain_type
से भी है. इसका मतलब है कि दिया गया_toolchain
नियम किसी भीtoolchain_type
से जुड़ा हो सकता है. साथ ही, इसtoolchain
नियम का इस्तेमाल करने वाले सिर्फ़_toolchain
इंस्टेंस में यह बताया जाता है कि नियमtoolchain_type
से जुड़ा है.
हमारे रनिंग उदाहरण के लिए, यहां bar_toolchain
नियम की परिभाषा दी गई है. हमारे
उदाहरण में सिर्फ़ कंपाइलर है. हालांकि, लिंक करने वाले किसी दूसरे टूल को भी
इसके नीचे ग्रुप किया जा सकता है.
def _bar_toolchain_impl(ctx):
toolchain_info = platform_common.ToolchainInfo(
barcinfo = BarcInfo(
compiler_path = ctx.attr.compiler_path,
system_lib = ctx.attr.system_lib,
arch_flags = ctx.attr.arch_flags,
),
)
return [toolchain_info]
bar_toolchain = rule(
implementation = _bar_toolchain_impl,
attrs = {
"compiler_path": attr.string(),
"system_lib": attr.string(),
"arch_flags": attr.string_list(),
},
)
नियम को ToolchainInfo
प्रोवाइडर को दिखाना चाहिए, जो इस्तेमाल करने वाले नियम को ctx.toolchains
और टूलचेन टाइप का लेबल इस्तेमाल करके वापस हासिल करता है. struct
की तरह, ToolchainInfo
भी आर्बिट्ररी फ़ील्ड-वैल्यू पेयर को होल्ड कर सकते हैं. ToolchainInfo
में जोड़े गए फ़ील्ड के बारे में खास तौर पर टूलचेन प्रकार में बताया जाना चाहिए. इस उदाहरण में, दिए गए स्कीमा को फिर से इस्तेमाल करने के लिए, वैल्यू को BarcInfo
ऑब्जेक्ट में रैप किया गया है. पुष्टि करने और कोड को दोबारा इस्तेमाल करने के लिए, यह स्टाइल मददगार हो सकती है.
अब आप खास barc
कंपाइलर के लिए टारगेट तय कर सकते हैं.
bar_toolchain(
name = "barc_linux",
arch_flags = [
"--arch=Linux",
"--debug_everything",
],
compiler_path = "/path/to/barc/on/linux",
system_lib = "/usr/lib/libbarc.so",
)
bar_toolchain(
name = "barc_windows",
arch_flags = [
"--arch=Windows",
# Different flags, no debug support on windows.
],
compiler_path = "C:\\path\\on\\windows\\barc.exe",
system_lib = "C:\\path\\on\\windows\\barclib.dll",
)
आखिर में, दो bar_toolchain
टारगेट के लिए toolchain
परिभाषाएं बनाई जाती हैं.
ये परिभाषाएं, खास भाषा के टारगेट को टूलचेन टाइप से जोड़ती हैं.
इससे कंटेंपररी से जुड़ी जानकारी मिलती है, जिससे बेज़ल को किसी प्लैटफ़ॉर्म के लिए सही टूल की जानकारी मिलती है.
toolchain(
name = "barc_linux_toolchain",
exec_compatible_with = [
"@platforms//os:linux",
"@platforms//cpu:x86_64",
],
target_compatible_with = [
"@platforms//os:linux",
"@platforms//cpu:x86_64",
],
toolchain = ":barc_linux",
toolchain_type = ":toolchain_type",
)
toolchain(
name = "barc_windows_toolchain",
exec_compatible_with = [
"@platforms//os:windows",
"@platforms//cpu:x86_64",
],
target_compatible_with = [
"@platforms//os:windows",
"@platforms//cpu:x86_64",
],
toolchain = ":barc_windows",
toolchain_type = ":toolchain_type",
)
ऊपर दिए गए मिलते-जुलते पाथ सिंटैक्स का इस्तेमाल करने से पता चलता है कि ये परिभाषाएं एक ही पैकेज में हैं.
हालांकि, यह ज़रूरी नहीं है कि टूलचेन टाइप, भाषा के हिसाब से
टूलचेन टारगेट, और toolchain
के डेफ़िनिशन टारगेट को अलग-अलग पैकेज में न रखा जाए.
असल ज़िंदगी के उदाहरण के लिए
go_toolchain
देखें.
टूलचेन और कॉन्फ़िगरेशन
नियम के लेखकों के लिए एक अहम सवाल यह है कि जब bar_toolchain
टारगेट का विश्लेषण
किया जाता है, तो यह क्या कॉन्फ़िगरेशन दिखता है, और डिपेंडेंसी के लिए किस ट्रांज़िशन का इस्तेमाल किया जाना चाहिए? ऊपर दिया गया उदाहरण स्ट्रिंग एट्रिब्यूट का इस्तेमाल करता है, लेकिन
एक ज़्यादा जटिल टूलचेन के लिए क्या होगा जो Bazel डेटा स्टोर करने की जगह में
दूसरे टारगेट पर निर्भर करता है?
आइए, bar_toolchain
के ज़्यादा जटिल वर्शन को देखते हैं:
def _bar_toolchain_impl(ctx):
# The implementation is mostly the same as above, so skipping.
pass
bar_toolchain = rule(
implementation = _bar_toolchain_impl,
attrs = {
"compiler": attr.label(
executable = True,
mandatory = True,
cfg = "exec",
),
"system_lib": attr.label(
mandatory = True,
cfg = "target",
),
"arch_flags": attr.string_list(),
},
)
स्टैंडर्ड नियम की तरह ही attr.label
का इस्तेमाल भी होता है,
लेकिन cfg
पैरामीटर का मतलब थोड़ा अलग होता है.
किसी टारगेट को "अभिभावक" (जिसे "पैरेंट" कहा जाता है) से निर्भर होकर, टूलचेन रिज़ॉल्यूशन के ज़रिए किसी टूलचेन से
"टूलचेन" ट्रांज़िशन को एक खास कॉन्फ़िगरेशन ट्रांज़िशन का इस्तेमाल करता है. टूलचेन ट्रांज़िशन से कॉन्फ़िगरेशन एक ही रहता है. हालांकि,
इसका मतलब है कि एक्ज़ीक्यूशन प्लैटफ़ॉर्म को पैरंट के लिए लागू किए गए टूलचेन के लिए एक जैसा ही माना जाता है (या फिर, टूलचेन के लिए टूलचेन समाधान को किसी भी एक्ज़ीक्यूशन प्लैटफ़ॉर्म को चुना जा सकता है
और ज़रूरी नहीं है कि यह पैरंट के लिए ही हो). इससे
टूलचेन की सभी exec
डिपेंडेंसी,
माता-पिता की बिल्ड कार्रवाइयों के लिए भी एक्ज़ीक्यूटेबल हो जाती हैं. कोई भी टूलचेन डिपेंडेंसी जो cfg =
"target"
का इस्तेमाल करती है (या cfg
नहीं बताती, क्योंकि "टारगेट" डिफ़ॉल्ट है), उसी पैरंट प्लैटफ़ॉर्म के लिए बनाई जाती है. यह टूलचेन नियमों को लाइब्रेरी (ऊपर दी गई system_lib
विशेषता) और टूल (compiler
एट्रिब्यूट) दोनों को उन नियमों में शामिल करने की अनुमति देता है जिनकी ज़रूरत उन्हें होती है. सिस्टम लाइब्रेरी फ़ाइनल आर्टफ़ैक्ट से लिंक होती हैं, इसलिए इन्हें उसी प्लैटफ़ॉर्म के लिए बनाया जाना चाहिए, जबकि कंपाइलर बिल्ड के दौरान शुरू किया गया टूल होता है और उसे एक्ज़ीक्यूशन प्लैटफ़ॉर्म पर चलाने की अनुमति होती है.
टूलचेन की मदद से रजिस्टर करना और बनाना
यहां सभी बिल्डिंग ब्लॉक असेंबल किए जाते हैं. इसके बाद, आपको बस बेज़ल के रिज़ॉल्यूशन की प्रोसेस के लिए टूलचेन उपलब्ध कराने होंगे. इसके लिए,
register_toolchains()
का इस्तेमाल करके WORKSPACE
फ़ाइल में या
--extra_toolchains
फ़्लैग का इस्तेमाल करके, कमांड लाइन पर टूलचेन लेबल पास करके, टूलचेन को रजिस्टर किया जाता है.
register_toolchains(
"//bar_tools:barc_linux_toolchain",
"//bar_tools:barc_windows_toolchain",
# Target patterns are also permitted, so you could have also written:
# "//bar_tools:all",
)
अब जब आप किसी टूलचेन प्रकार पर निर्भर कोई लक्ष्य बनाते हैं, तो लक्ष्य और निष्पादन प्लेटफ़ॉर्म के आधार पर एक उपयुक्त टूलचेन चुना जाएगा.
# my_pkg/BUILD
platform(
name = "my_target_platform",
constraint_values = [
"@platforms//os:linux",
],
)
bar_binary(
name = "my_bar_binary",
...
)
bazel build //my_pkg:my_bar_binary --platforms=//my_pkg:my_target_platform
बेज़ल को पता चलेगा कि //my_pkg:my_bar_binary
एक ऐसे प्लैटफ़ॉर्म के साथ बनाया जा रहा है जिसमें @platforms//os:linux
है. इसलिए, यह //bar_tools:barc_linux_toolchain
के //bar_tools:toolchain_type
रेफ़रंस को रिज़ॉल्व करता है.
इससे इमारत //bar_tools:barc_linux
बन जाएगी, लेकिन //bar_tools:barc_windows
नहीं.
टूलचेन रिज़ॉल्यूशन
टूलचेन का इस्तेमाल करने वाले हर टारगेट के लिए, बैज़ेल की टूलचेन प्रक्रिया, टारगेट की कंक्रीट टूलचेन डिपेंडेंसी तय करती है. इस प्रक्रिया में, ज़रूरी टूलचेन टाइप का सेट, टारगेट प्लैटफ़ॉर्म, उपलब्ध एक्ज़ीक्यूशन प्लैटफ़ॉर्म की सूची, और उपलब्ध टूलचेन की सूची दी जाती है. इसके आउटपुट, हर टूलचेन टाइप के लिए एक चुना गया टूलचेन है. साथ ही, मौजूदा टारगेट के लिए एक चुना गया एक्ज़ीक्यूशन प्लैटफ़ॉर्म है.
एक्ज़ीक्यूशन के लिए उपलब्ध प्लैटफ़ॉर्म और टूल चेन, WORKSPACE
फ़ाइल से इकट्ठा किए जाते हैं. इसके लिए, register_execution_platforms
औरregister_toolchains
का इस्तेमाल किया जाता है.
एक्ज़ीक्यूशन के लिए अतिरिक्त प्लैटफ़ॉर्म और टूल चेन भी --extra_execution_platforms
और--extra_toolchains
के ज़रिए कमांड लाइन पर दी जा सकती हैं.
होस्ट प्लैटफ़ॉर्म अपने-आप, एक्ज़ीक्यूशन के उपलब्ध प्लैटफ़ॉर्म के तौर पर शामिल हो जाता है.
उपलब्ध प्लैटफ़ॉर्म और टूलचेन को डेटरमिनिज़्म की क्रम में दी गई सूचियों के रूप में ट्रैक किया जाता है.
साथ ही, इसमें सूची में पहले के आइटम को भी प्राथमिकता दी जाती है.
समस्या हल करने के तरीके यहां दिए गए हैं.
किसी
target_compatible_with
याexec_compatible_with
क्लॉज़ का मिलान किसी प्लैटफ़ॉर्म से मिलता-जुलता है, अगर सूची में मौजूद हरconstraint_value
के लिए, प्लैटफ़ॉर्म को वहconstraint_value
भी दिया गया हो (पूरी तरह से या डिफ़ॉल्ट के तौर पर).अगर प्लैटफ़ॉर्म में
constraint_setting
केconstraint_value
की जानकारी दी गई है, जो क्लॉज़ में नहीं दी गई है, तो मिलान करने पर कोई असर नहीं पड़ेगा.अगर बनाया जा रहा टारगेट,
exec_compatible_with
एट्रिब्यूट बताता है (या इसके नियम की परिभाषा में,exec_compatible_with
आर्ग्युमेंट बताया गया है), तो एक्ज़ीक्यूशन से जुड़ी शर्तों से मेल न खाने वाले किसी एक एग्ज़िट को हटाने के लिए, उपलब्ध एक्ज़ीक्यूशन प्लैटफ़ॉर्म की सूची फ़िल्टर की जाती है.हर एक एक्ज़ीक्यूशन प्लैटफ़ॉर्म के लिए, आप हर टूलचेन टाइप को पहले उपलब्ध टूलचेन से जोड़ते हैं. अगर कोई ऐसा हो, तो वह इस एक्ज़ीक्यूशन प्लैटफ़ॉर्म और टारगेट प्लैटफ़ॉर्म के साथ काम करता है.
एक्ज़ीक्यूशन प्लैटफ़ॉर्म, जो किसी एक तरह के टूलचेन के लिए, इस्तेमाल किए जा सकने वाले ज़रूरी टूलचेन नहीं ढूंढ पाता, उसे हटा दिया जाता है. बाकी प्लैटफ़ॉर्म में से, पहला प्लैटफ़ॉर्म, टारगेट को लागू करने वाला मौजूदा प्लैटफ़ॉर्म बन जाता है. साथ ही, इससे जुड़े टूलचेन (अगर कोई हो) टारगेट की निर्भरता बन जाते हैं.
चुने गए एक्ज़ीक्यूशन प्लैटफ़ॉर्म का इस्तेमाल टारगेट जनरेट की जाने वाली सभी कार्रवाइयां चलाने के लिए किया जाता है.
ऐसे मामलों में जहां एक ही टारगेट को एक ही बिल्ड में कई कॉन्फ़िगरेशन (जैसे कि अलग-अलग सीपीयू के लिए) में बनाया जा सकता हो, वहीं रिज़ॉल्यूशन प्रोसेस, टारगेट के हर वर्शन पर अलग-अलग लागू की जाती है.
अगर नियम में एक्ज़ीक्यूशन ग्रुप का इस्तेमाल होता है, तो एक्ज़ीक्यूशन के लिए हर ग्रुप अलग-अलग टूलचेन समाधान चलाता है. साथ ही, हर ग्रुप में एक्ज़ीक्यूशन प्लैटफ़ॉर्म और टूलचेन मौजूद होते हैं.
डीबग करने वाले टूलचेन
अगर आप किसी मौजूदा नियम में टूलचेन सहायता जोड़ रहे हैं, तो --toolchain_resolution_debug=regex
फ़्लैग का इस्तेमाल करें. टूलचेन रिज़ॉल्यूशन के दौरान, फ़्लैग
रेगुलर एक्सप्रेशन वैरिएबल से मेल खाने वाले टूलचेन प्रकारों या टारगेट नामों के लिए वर्बोस आउटपुट देता है. पूरी जानकारी देने के लिए
.*
का इस्तेमाल किया जा सकता है. बैज़ेल, रिज़ॉल्यूशन की प्रोसेस के दौरान जिन टूलचेन को चेक करता है और जिन्हें स्किप करता है, उनके नाम देगा.
अगर आपको देखना है कि कौनसी cquery
डिपेंडेंसी, टूलचेन रिज़ॉल्यूशन पर आधारित हैं, तो cquery
के --transitions
फ़्लैग का इस्तेमाल करें:
# Find all direct dependencies of //cc:my_cc_lib. This includes explicitly
# declared dependencies, implicit dependencies, and toolchain dependencies.
$ bazel cquery 'deps(//cc:my_cc_lib, 1)'
//cc:my_cc_lib (96d6638)
@bazel_tools//tools/cpp:toolchain (96d6638)
@bazel_tools//tools/def_parser:def_parser (HOST)
//cc:my_cc_dep (96d6638)
@local_config_platform//:host (96d6638)
@bazel_tools//tools/cpp:toolchain_type (96d6638)
//:default_host_platform (96d6638)
@local_config_cc//:cc-compiler-k8 (HOST)
//cc:my_cc_lib.cc (null)
@bazel_tools//tools/cpp:grep-includes (HOST)
# Which of these are from toolchain resolution?
$ bazel cquery 'deps(//cc:my_cc_lib, 1)' --transitions=lite | grep "toolchain dependency"
[toolchain dependency]#@local_config_cc//:cc-compiler-k8#HostTransition -> b6df211