टूलचेन

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

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

वजह

आइए, सबसे पहले उन समस्या टूलचेन पर नज़र डालते हैं जिन्हें हल करने के लिए बनाया गया है. मान लीजिए कि "bar" का समर्थन करने के लिए नियम लिख रहे हों प्रोग्रामिंग भाषा है. आपका 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.toolchains के तहत इस डिपेंडेंसी को ऐक्सेस करता है कुंजी के रूप में टूलचेन टाइप का इस्तेमाल करके, ctx.attr के बजाय टूलचेन टाइप का इस्तेमाल करें.

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

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

टूलचेन के साथ रजिस्टर करना और बनाना

इस स्थिति में, सभी बिल्डिंग ब्लॉक इकट्ठा हो जाते हैं. आपको बस एक बनाना होता है बेज़ल की समस्या हल करने की प्रोसेस के लिए उपलब्ध टूलचेन. ऐसा करने के लिए इसका इस्तेमाल करके MODULE.bazel फ़ाइल में टूलचेन को रजिस्टर किया जा सकता है 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",
    # or even
    # "//bar_tools/...",
)

टूलचेन रजिस्टर करने के लिए, टारगेट पैटर्न का इस्तेमाल करते समय, वह क्रम जिसमें अलग-अलग टूलचेन का रजिस्ट्रेशन इन नियमों के आधार पर किया जाता है:

  • किसी पैकेज के सबपैकेज में परिभाषित टूलचेन को पैकेज में बताए गए टूल चेन.
  • पैकेज के अंदर, टूलचेन को इस शब्दकोश में रजिस्टर किया जाता है कि उनका नाम लिखें.

अब जब आप टूलचेन टाइप पर निर्भर कोई टारगेट बनाते हैं, तो आपको टूलचेन को टारगेट और उसे लागू करने वाले प्लैटफ़ॉर्म के आधार पर चुना जाएगा.

# 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

Basel को दिखेगा कि //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.

टूलचेन रिज़ॉल्यूशन

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

उपलब्ध निष्पादन प्लैटफ़ॉर्म और टूलचेन इसके ज़रिए बाहरी डिपेंडेंसी ग्राफ़ register_execution_platforms और register_toolchains कॉल इतने समय में होंगे MODULE.bazel फ़ाइलें. इसके अलावा, प्रोग्राम चलाने के लिए अन्य प्लैटफ़ॉर्म और टूलचेन का भी इस्तेमाल किया जा सकता है कमांड लाइन के ज़रिए --extra_execution_platforms और --extra_toolchains. होस्ट प्लैटफ़ॉर्म, उपलब्ध एक्ज़ीक्यूशन प्लैटफ़ॉर्म के तौर पर अपने-आप शामिल हो जाता है. उपलब्ध प्लैटफ़ॉर्म और टूलचेन को डिटरमिनिज़्म के लिए ऑर्डर की गई सूचियों के तौर पर ट्रैक किया जाता है. प्राथमिकता पर सूची में मौजूद पहले के आइटम को प्राथमिकता दें.

प्राथमिकता के क्रम में, उपलब्ध टूलचेन का सेट इनसे बनाया जाता है: --extra_toolchains और register_toolchains:

  1. --extra_toolchains का इस्तेमाल करके रजिस्टर किए गए टूलचेन पहले जोड़े जाते हैं. (इसके अंदर इनमें से आखिरी टूलचेन को सबसे ज़्यादा प्राथमिकता दी जाती है.)
  2. ट्रांज़िटिव एक्सटर्नल में register_toolchains का इस्तेमाल करके रजिस्टर किए गए टूलचेन डिपेंडेंसी ग्राफ़, नीचे दिए गए क्रम में हो: (इनमें पहले बताए गए टूलचेन को सबसे ज़्यादा प्राथमिकता दी जाती है.)
    1. रूट मॉड्यूल की मदद से रजिस्टर किए गए टूलचेन (जैसे, MODULE.bazel फ़ाइल फ़ोल्डर रूट);
    2. उपयोगकर्ता की WORKSPACE फ़ाइल में रजिस्टर किए गए टूलचेन. इसमें वे सभी टूल भी शामिल हैं जो उपयोगकर्ता की किसी भी फ़ाइल में रजिस्टर होते हैं मैक्रोज़ वहाँ से शुरू हुए;
    3. नॉन-रूट मॉड्यूल की मदद से रजिस्टर किए गए टूलचेन (जैसे, इन डिपेंडेंसी के हिसाब से) रूट मॉड्यूल, उनकी डिपेंडेंसी वगैरह;
    4. "वर्कस्पेस सफ़िक्स" में रजिस्टर किए गए टूलचेन; इसका इस्तेमाल सिर्फ़ यह कर सकता है: बेज़ल इंस्टॉलेशन के साथ बंडल किए गए कुछ खास स्थानीय नियम.

ध्यान दें: सूडो-टारगेट, जैसे कि :all, :*, और /... को बेज़ल के पैकेज के हिसाब से ऑर्डर किया गया है लोडिंग मैकेनिज़्म, जो लेक्सिकोग्राफ़िक ऑर्डरिंग का इस्तेमाल करता है.

समस्या को हल करने का तरीका यहां बताया गया है.

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

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

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

  3. किसी भी टूलचेन को हटाने के लिए, उपलब्ध टूलचेन की सूची को फ़िल्टर किया जाता है target_settings को तय कर रहा है जो मौजूदा कॉन्फ़िगरेशन से मेल नहीं खाता.

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

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

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

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

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

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

अगर किसी मौजूदा नियम में टूलचेन सपोर्ट जोड़ा जा रहा है, तो --toolchain_resolution_debug=regex फ़्लैग. टूलचेन रिज़ॉल्यूशन के दौरान, फ़्लैग इस फ़ंक्शन से, ऐसे टूलचेन टाइप या टारगेट नामों के लिए ज़्यादा शब्दों में जानकारी देने वाला आउटपुट मिलता है जो रेगुलर एक्सप्रेशन वैरिएबल से मैच करते हैं. आपने लोगों तक पहुंचाया मुफ़्त में सभी जानकारी देने के लिए, .* का इस्तेमाल कर सकता है. Basel, इसकी टूलचेन के नाम जनरेट करेगी जांच करता है और स्किप करता है.

अगर आपको देखना है कि कौनसी 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