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

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

बैकग्राउंड

एक्ज़ीक्यूशन ग्रुप, नियम बनाने वाले को कार्रवाइयों के सेट तय करने की अनुमति देता है. इनमें से हर एक के लिए, अलग-अलग प्रोग्राम चलाने का प्लैटफ़ॉर्म होता है. एक से ज़्यादा एक्ज़ीक्यूशन प्लैटफ़ॉर्म, कार्रवाइयों को अलग-अलग तरीके से पूरा करने की अनुमति दे सकते हैं. उदाहरण के लिए, किसी रिमोट (linux) वर्कर पर iOS ऐप्लिकेशन को कंपाइल करना और फिर लोकल 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 फ़ंक्शन दिखाता है, जो एक स्ट्रिंग पैरामीटर लेता है. यह उस 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 एट्रिब्यूट के साथ इंटिग्रेट किए जाते हैं. यह हर नियम पर मौजूद होता है. इसकी मदद से, टारगेट राइटर, प्रॉपर्टी की स्ट्रिंग डिस्क्रिप्टर तय कर पाता है और उसे एक्ज़ीक्यूट करने वाली मशीनरी को भेज पाता है. उदाहरण के लिए, अगर आपको टारगेट के लिए कुछ प्रॉपर्टी सेट करनी है, जैसे कि मेमोरी, और कुछ खास कार्रवाइयों के लिए ज़्यादा मेमोरी तय करना है, तो आपको एक्ज़ीक्यूशन-ग्रुप-augmented कुंजी के साथ exec_properties एंट्री लिखनी होगी. जैसे:

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

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

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

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

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

exec प्रॉपर्टी सेट करने के लिए exec ग्रुप बनाए जा रहे हैं

कभी-कभी आप खास कार्रवाइयों को अलग-अलग 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 को, एक्ज़ीक्यूट करने के प्लैटफ़ॉर्म से इनहेरिट किए गए exec_properties के मुकाबले प्राथमिकता दी जाती है.