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