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

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

बैकग्राउंड

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

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

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

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

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

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

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

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

नेटिव नियमों के लिए, लागू करने वाले ग्रुप

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

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

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

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