BazelCon 2022, 16 नवंबर से 17 नवंबर तक न्यूयॉर्क में और ऑनलाइन उपलब्ध है.
आज ही रजिस्टर करें!

टूलचेन

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

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

ऐसा करने की वजह

आइए, सबसे पहले उन समस्या के टूल पर नज़र डालें जिन्हें ठीक करने के लिए डिज़ाइन किया गया है. मान लीजिए कि आप "बार" प्रोग्रामिंग भाषा के समर्थन के लिए नियम लिख रहे हैं. हमाराbar_binary नियम कंपाइल होगा*.bar कोbarc कंपाइलर, एक ऐसा टूल जो आपके फ़ाइल फ़ोल्डर में दूसरे टारगेट के तौर पर बनाया गया है. हालांकि, 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 []

तय करने वाले टूल

किसी खास तरह के टूलचेन के बारे में बताने के लिए, आपको तीन चीज़ों की ज़रूरत होती है:

  1. भाषा के हिसाब से बना नियम, जो टूल या टूल सुइट के प्रकार को दिखाता है. कन्वेंशन के हिसाब से, इस नियम के नाम के साथ "_toolchain" जुड़ा है.

    1. ध्यान दें: \_toolchain नियम बनाने के लिए कोई कार्रवाई नहीं कर सकता. बल्कि, यह दूसरे नियमों से कलाकृतियां इकट्ठा करता है और उन्हें उस नियम पर भेज देता है जो टूलचेन का इस्तेमाल करता है. यह नियम सभी बिल्ड कार्रवाइयां बनाने के लिए ज़िम्मेदार है.
  2. इस तरह के नियम के कई टारगेट, अलग-अलग प्लैटफ़ॉर्म के लिए टूल या टूल सुइट के वर्शन दिखाते हैं.

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

आइए, 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 एट्रिब्यूट) दोनों को उन बिल्ड नियमों में शामिल कर पाता है जिनकी ज़रूरत उन्हें होती है. सिस्टम लाइब्रेरी को आखिरी आर्टफ़ैक्ट से लिंक किया गया है. इसलिए, इन्हें एक ही प्लैटफ़ॉर्म के लिए बनाया जाना चाहिए. वहीं, कंपाइलर टूल को बनाने के दौरान इस्तेमाल किया जाता है और इसे इस्तेमाल करके एक्ज़ीक्यूशन प्लैटफ़ॉर्म.

टूलचेन के साथ पंजीकृत करना और बनाना

फ़िलहाल, सभी बिल्डिंग ब्लॉक तैयार किए गए हैं. साथ ही, आपको टूल के लिए सिर्फ़ बेज़ेल की रिज़ॉल्यूशन प्रोसेस को उपलब्ध कराना है. ऐसा करने के लिए, टूलचेन पर रजिस्टर किया जाता हैWORKSPACE फ़ाइल का इस्तेमाल करके register_toolchains() या सीधे तौर पर--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 के ज़रिए कमांड लाइन पर दी जा सकती है. होस्ट प्लैटफ़ॉर्म को एक्ज़ीक्यूशन के लिए उपलब्ध प्लैटफ़ॉर्म के तौर पर अपने-आप शामिल किया जाता है. उपलब्ध प्लैटफ़ॉर्म और टूलचेन को तय की गई क्रम सूची के रूप में ट्रैक किया जाता है. इसमें सूची में पहले के आइटम को प्राथमिकता दी जाती है.

समस्या को ठीक करने के तरीके यहां दिए गए हैं.

  1. target_compatible_with या exec_compatible_with क्लॉज़ किसी प्लैटफ़ॉर्म से मेल खाता है, अगर सूची में मौजूद हर constraint_value के लिए, उस प्लैटफ़ॉर्म से वह constraint_value (या तो) मिला हो साफ़ तौर पर या डिफ़ॉल्ट के तौर पर).

    अगर प्लैटफ़ॉर्म में constraint_setting के constraint_value हैं, जिन्हें क्लॉज़ में नहीं बताया गया है, तो मिलान पर इनका कोई असर नहीं पड़ता.

  2. अगर बनाया जा रहा टारगेट, बताता है कि exec_compatible_with एट्रिब्यूट (या इसकी नियम परिभाषा exec_compatible_with आर्ग्युमेंट ), उपलब्ध एक्ज़ीक्यूशन प्लैटफ़ॉर्म की सूची को फ़िल्टर करके, एक्ज़ीक्यूशन कंस्ट्रेंट से मेल नहीं खाने वाले किसी भी फ़िल्टर को हटाया जाता है.

  3. हर एक उपलब्ध एक्ज़ीक्यूशन प्लैटफ़ॉर्म के लिए, आप हर तरह के टूलचेन को, पहले उपलब्ध टूलचेन से जोड़ देते हैं, अगर कोई प्लैटफ़ॉर्म एक्ज़ीक्यूशन प्लैटफ़ॉर्म और टारगेट प्लैटफ़ॉर्म के साथ काम करता हो.

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

चुने गए एक्ज़ीक्यूशन प्लैटफ़ॉर्म का इस्तेमाल उन सभी कार्रवाइयों को चलाने के लिए किया जाता है जिन्हें टारगेट जनरेट करता है.

उन मामलों में जहां एक ही टारगेट को एक ही बिल्ड में कई कॉन्फ़िगरेशन में (जैसे कि अलग-अलग सीपीयू के लिए) बनाया जा सकता है, वहां समाधान की प्रक्रिया टारगेट के हर वर्शन पर अलग से लागू की जाती है.

अगर नियम प्लान के मुताबिक काम करने वाले ग्रुप का इस्तेमाल करता है, तो हर एक प्रोग्राम एक्ज़ीक्यूशन रिज़ॉल्यूशन को अलग-अलग लागू करता है. साथ ही, हर नियम का एक्ज़ीक्यूशन प्लैटफ़ॉर्म और टूलचेन होता है.

डीबग करने वाले टूलचेन

अगर किसी मौजूदा नियम में टूलचेन सहायता जोड़ी जा रही है, तो --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