एक्ज़ीक्यूशन ग्रुप

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

बैकग्राउंड

एक्ज़ीक्यूशन ग्रुप की मदद से, नियम बनाने वाला व्यक्ति कार्रवाइयों के सेट तय कर सकता है. हर सेट के लिए, एक्ज़ीक्यूशन प्लैटफ़ॉर्म अलग-अलग हो सकता है. एक से ज़्यादा प्लैटफ़ॉर्म पर कोड को अलग-अलग तरीके से एक्ज़ीक्यूट किया जा सकता है. उदाहरण के लिए, iOS ऐप्लिकेशन को रिमोट (Linux) वर्कर पर कंपाइल करना और फिर लोकल Mac वर्कर पर लिंक/कोड साइन करना.

कार्रवाइयों के ग्रुप तय करने की सुविधा से, कार्रवाइयों को तय करने के लिए ऐक्शन नियमों के इस्तेमाल को कम करने में भी मदद मिलती है. यह ज़रूरी नहीं है कि निमोनिक यूनीक हों. साथ ही, ये सिर्फ़ एक कार्रवाई के बारे में बता सकते हैं. यह खास तौर पर, किसी मेमोरी को ज़्यादा संसाधन असाइन करने और ज़्यादा प्रोसेसिंग की ज़रूरत वाली कार्रवाइयों को पूरा करने में मददगार होता है. जैसे, C++ बिल्ड में लिंक करना. ऐसा कम प्रोसेसिंग की ज़रूरत वाले टास्क के लिए ज़्यादा संसाधन असाइन किए बिना किया जाता है.

एक्ज़ीक्यूशन ग्रुप तय करना

नियम तय करते समय, नियम बनाने वाले लोग, एक्ज़ीक्यूशन ग्रुप का सेट डिक्लेयर कर सकते हैं. नियम बनाने वाला व्यक्ति, हर एक्ज़ीक्यूशन ग्रुप के लिए यह तय कर सकता है कि उस एक्ज़ीक्यूशन ग्रुप के लिए, एक्ज़ीक्यूशन प्लैटफ़ॉर्म चुनने के लिए क्या-क्या ज़रूरी है. जैसे, exec_compatible_with के ज़रिए कोई भी पाबंदी और toolchain के ज़रिए टूलचेन के टाइप.

# foo.bzl
my_rule = rule(
    _impl,
    exec_groups = {
        link: exec_group(
            exec_compatible_with = [ "@platforms//os:linux" ]
            toolchains = ["//foo:toolchain_type"],
        ),
        test: exec_group(
            toolchains = ["//foo_tools:toolchain_type"],
        ),
    },
    attrs = {
        "_compiler": attr.label(cfg = config.exec("link"))
    },
)

ऊपर दिए गए कोड स्निपेट में, यह देखा जा सकता है कि टूल की डिपेंडेंसी, cfg एट्रिब्यूट पैरामीटर और config मॉड्यूल का इस्तेमाल करके, किसी एक्ज़ेक ग्रुप के लिए ट्रांज़िशन भी तय कर सकती हैं. यह मॉड्यूल, exec फ़ंक्शन को दिखाता है. यह एक स्ट्रिंग पैरामीटर लेता है. यह उस एक्ज़ेक ग्रुप का नाम होता है जिसके लिए डिपेंडेंसी बनानी होती है.

नेटिव नियमों की तरह, test एक्ज़ीक्यूशन ग्रुप, Starlark टेस्ट के नियमों में डिफ़ॉल्ट रूप से मौजूद होता है.

एक्ज़ीक्यूशन ग्रुप इनहेरिटेंस

नया एक्ज़ीक्यूशन ग्रुप, अपनी सीमाएं और टूलचेन तय करने के साथ-साथ यह भी एलान कर सकता है कि उसे नियम के डिफ़ॉल्ट एक्ज़ीक्यूशन ग्रुप से इनहेरिट करना है. इसके लिए, उसे copy_from_rule = True पैरामीटर पास करना होगा. copy_from_rule को सही पर सेट करने के साथ-साथ exec_compatible_with या toolchains को पास करना एक गड़बड़ी है.

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

# foo.bzl
my_rule = rule(
    _impl,
    exec_groups = {
        copied: exec_group(
            copy_from_rule = True,
            # This will inherit exec_compatible_with and toolchains.
            # Setting them here directly would be an error, however.
        ),
    },
    toolchains = ["//foo_tools:toolchain_type"],
    exec_compatible_with = ["@platforms//os:linux"],
)

# BUILD

my_rule(
    name = "demo",
    exec_compatible_with = [":local_constraint"],
)

कॉन्फ़िगर किए गए टारगेट demo के लिए copied एक्ज़ीक्यूशन ग्रुप में ये सभी शामिल होंगे: - //fool_tools:toolchain_type - @platforms//os:linux - :local_constraint

एक्ज़ीक्यूशन ग्रुप ऐक्सेस करना

नियम लागू करने के दौरान, यह एलान किया जा सकता है कि कार्रवाइयां, किसी एक्ज़ीक्यूशन ग्रुप के एक्ज़ीक्यूशन प्लैटफ़ॉर्म पर चलनी चाहिए. इसके लिए, कार्रवाई जनरेट करने वाले तरीकों के exec_group पैरामीटर का इस्तेमाल करें. खास तौर पर, ctx.actions.run और ctx.actions.run_shell.

# foo.bzl
def _impl(ctx):
  ctx.actions.run(
     inputs = [ctx.attr._some_tool, ctx.srcs[0]]
     exec_group = "compile",
     # ...
  )

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

# foo.bzl
def _impl(ctx):
  foo_info = ctx.exec_groups["link"].toolchains["//foo:toolchain_type"].fooinfo
  ctx.actions.run(
     inputs = [foo_info, ctx.srcs[0]]
     exec_group = "link",
     # ...
  )

एक्ज़ीक्यूशन प्रॉपर्टी सेट करने के लिए, एक्ज़ीक्यूशन ग्रुप का इस्तेमाल करना

एक्ज़ीक्यूशन ग्रुप, exec_properties एट्रिब्यूट के साथ इंटिग्रेट किए जाते हैं. यह एट्रिब्यूट हर नियम में मौजूद होता है. इससे टारगेट राइटर, प्रॉपर्टी का एक स्ट्रिंग डिक्शनरी तय कर सकता है. इसके बाद, इसे एक्ज़ीक्यूशन मशीनरी को पास किया जाता है. उदाहरण के लिए, अगर आपको टारगेट के लिए कोई प्रॉपर्टी सेट करनी है, जैसे कि मेमोरी, और कुछ कार्रवाइयों को ज़्यादा मेमोरी देनी है, तो आपको exec_properties वाली एंट्री लिखनी होगी. इसमें execution-group-augmented कुंजी शामिल होती है. जैसे:

# BUILD
my_rule(
    name = 'my_target',
    exec_properties = {
        'mem': '12g',
        'link.mem': '16g'
    }
    
)

exec_group = "link" वाले सभी ऐक्शन, execProperties डिक्शनरी को {"mem": "16g"} के तौर पर देखेंगे. यहां दिखाया गया है कि एक्ज़ीक्यूशन ग्रुप लेवल की सेटिंग, टारगेट लेवल की सेटिंग को बदल देती हैं.

नेटिव नियमों के लिए एक्ज़ीक्यूशन ग्रुप

नेटिव नियमों के तहत तय की गई कार्रवाइयों के लिए, ये एक्ज़ीक्यूशन ग्रुप उपलब्ध हैं:

  • test: टेस्ट रनर की कार्रवाइयां.
  • cpp_link: C++ लिंकिंग ऐक्शन.

एग्ज़ेक प्रॉपर्टी सेट करने के लिए, एग्ज़ेक ग्रुप बनाना

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

# foo.bzl

# Creating an exec group with `copy_from_rule=True` is the same as explicitly
# setting the exec group's toolchains and constraints to the same values as the
# rule's respective parameters.
my_rule = rule(
    _impl,
    exec_compatible_with = ["@platforms//os:linux"],
    toolchains = ["//foo:toolchain_type"],
    exec_groups = {
        # The following two groups have the same toolchains and constraints:
        foo: exec_group(copy_from_rule = True),
        "bar": exec_group(
            exec_compatible_with = ["@platforms//os:linux"],
            toolchains = ["//foo:toolchain_type"],
        ),
    },
)

#

एक्ज़ीक्यूशन ग्रुप और प्लैटफ़ॉर्म एक्ज़ीक्यूशन प्रॉपर्टी

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

उदाहरण के लिए, मान लें कि C++ टेस्ट चलाने के लिए कुछ संसाधन उपलब्ध होने चाहिए, लेकिन कंपाइल करने और लिंक करने के लिए इसकी ज़रूरत नहीं है. इसे इस तरह से मॉडल किया जा सकता है:

constraint_setting(name = "resource")
constraint_value(name = "has_resource", constraint_setting = ":resource")

platform(
    name = "platform_with_resource",
    constraint_values = [":has_resource"],
    exec_properties = {
        "test.resource": "...",
    },
)

cc_test(
    name = "my_test",
    srcs = ["my_test.cc"],
    exec_compatible_with = [":has_resource"],
)

exec_properties पर सीधे तौर पर तय किए गए टारगेट, उन टारगेट से ज़्यादा अहम होते हैं जो एक्ज़ीक्यूशन प्लैटफ़ॉर्म से इनहेरिट किए जाते हैं.