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