एक्सीक्यूशन ग्रुप की मदद से, एक ही टारगेट में कई एक्सीक्यूशन प्लैटफ़ॉर्म इस्तेमाल किए जा सकते हैं. हर एक्ज़ीक्यूशन ग्रुप के पास अपनी टूलचेन डिपेंडेंसी होती हैं और वह अपना टूलचेन रिज़ॉल्यूशन करता है.
बैकग्राउंड
लागू करने के ग्रुप की मदद से, नियम बनाने वाला व्यक्ति कार्रवाइयों के सेट तय कर सकता है. हर सेट के लिए, लागू करने का अलग प्लैटफ़ॉर्म चुना जा सकता है. एक से ज़्यादा प्लैटफ़ॉर्म पर, कार्रवाई को अलग-अलग तरीके से चलाया जा सकता है. उदाहरण के लिए, किसी रिमोट (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
फ़ंक्शन होता है, जिसमें एक स्ट्रिंग पैरामीटर होता है. यह पैरामीटर, उस एक्सेक्यूट ग्रुप का नाम होता है जिसके लिए डिपेंडेंसी बनाई जानी चाहिए.
नेटिव नियमों की तरह ही, Starlark जांच के नियमों में test
एक्सीक्यूशन ग्रुप डिफ़ॉल्ट रूप से मौजूद होता है.
एक्सीक्यूशन ग्रुप ऐक्सेस करना
नियम लागू करने के दौरान, यह तय किया जा सकता है कि कार्रवाइयां, किसी एक्सीक्यूशन ग्रुप के एक्सीक्यूशन प्लैटफ़ॉर्म पर चलाई जाएं. ऐसा करने के लिए, कार्रवाई जनरेट करने के तरीकों के exec_group
param का इस्तेमाल करें. खास तौर पर, 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",
# ...
)
डिफ़ॉल्ट रन ग्रुप
ये एक्सीक्यूशन ग्रुप पहले से तय होते हैं:
test
: टेस्ट रनर की कार्रवाइयां, जो सभी टेस्ट नियमों पर उपलब्ध होती हैं.cpp_link
: C++ लिंक करने की कार्रवाइयां.
एक्सीक्यूशन प्रॉपर्टी सेट करने के लिए, एक्सीक्यूशन ग्रुप का इस्तेमाल करना
एक्सीक्यूशन ग्रुप, हर नियम पर मौजूद exec_properties
एट्रिब्यूट के साथ इंटिग्रेट होते हैं. इससे टारगेट लिखने वाले व्यक्ति को प्रॉपर्टी की एक स्ट्रिंग डायक्शन तय करने की अनुमति मिलती है. इसके बाद, इसे एक्सीक्यूशन मशीनरी को पास कर दिया जाता है. उदाहरण के लिए, अगर आपको टारगेट के लिए कोई प्रॉपर्टी, जैसे कि मेमोरी सेट करनी है और कुछ ऐक्शन को ज़्यादा मेमोरी देनी है, तो आपको एक exec_properties
एंट्री लिखनी होगी. इसमें, एक्सीक्यूशन ग्रुप की जानकारी देने वाली कुंजी का इस्तेमाल किया जाएगा. जैसे:
# BUILD
my_rule(
name = 'my_target',
exec_properties = {
'mem': '12g',
'link.mem': '16g'
}
…
)
exec_group = "link"
वाली सभी कार्रवाइयों में, exec प्रॉपर्टी की डिक्शनरी {"mem": "16g"}
के तौर पर दिखेगी. यहां देखें कि टारगेट-लेवल की सेटिंग को, एक्सीक्यूशन ग्रुप-लेवल की सेटिंग बदल देती हैं.
प्लैटफ़ॉर्म की पाबंदियां सेट करने के लिए, एक्सीक्यूशन ग्रुप का इस्तेमाल करना
एक्सीक्यूशन ग्रुप, हर नियम पर मौजूद exec_compatible_with
और exec_group_compatible_with
एट्रिब्यूट के साथ भी इंटिग्रेट होते हैं. साथ ही, टारगेट लिखने वाले व्यक्ति को अतिरिक्त शर्तें तय करने की अनुमति देते हैं. ये शर्तें, टारगेट की कार्रवाइयों के लिए चुने गए एक्सीक्यूशन प्लैटफ़ॉर्म के लिए ज़रूरी हैं.
उदाहरण के लिए, अगर नियम my_test
, डिफ़ॉल्ट और test
एक्सीक्यूशन ग्रुप के अलावा link
एक्सीक्यूशन ग्रुप को भी तय करता है, तो इन एट्रिब्यूट के इस तरह के इस्तेमाल से, ज़्यादा सीपीयू वाले प्लैटफ़ॉर्म पर डिफ़ॉल्ट एक्सीक्यूशन ग्रुप में ऐक्शन चलेंगे. साथ ही, Linux पर टेस्ट ऐक्शन और डिफ़ॉल्ट एक्सीक्यूशन प्लैटफ़ॉर्म पर लिंक ऐक्शन चलेगा:
# BUILD
constraint_setting(name = "cpu")
constraint_value(name = "high_cpu", constraint_setting = ":cpu")
platform(
name = "high_cpu_platform",
constraint_values = [":high_cpu"],
exec_properties = {
"cpu": "256",
},
)
my_test(
name = "my_test",
exec_compatible_with = ["//constraints:high_cpu"],
exec_group_compatible_with = {
"test": ["@platforms//os:linux"],
},
...
)
एक्सीक्यूशन ग्रुप और प्लैटफ़ॉर्म एक्सीक्यूशन प्रॉपर्टी
प्लैटफ़ॉर्म टारगेट पर, मनमुताबिक एक्सीक्यूशन ग्रुप के लिए exec_properties
तय किया जा सकता है. यह exec_properties
सेट करने के उस तरीके से अलग है जिसमें सीधे टारगेट पर सेट किया जाता है. इस तरीके में, ऐसे एक्सीक्यूशन ग्रुप की प्रॉपर्टी अस्वीकार कर दी जाती हैं जिनके बारे में जानकारी नहीं है. इसके बाद, टारगेट को एक्सीक्यूशन प्लैटफ़ॉर्म का exec_properties
इनहेरिट हो जाता है. यह exec_properties
, डिफ़ॉल्ट एक्सीक्यूशन ग्रुप और काम के अन्य एक्सीक्यूशन ग्रुप पर असर डालता है.
उदाहरण के लिए, मान लें कि exec प्लैटफ़ॉर्म पर टेस्ट चलाने के लिए, किसी रिसॉर्स के उपलब्ध होने की ज़रूरत है, लेकिन उसे कॉम्पाइल और लिंक करने के लिए ज़रूरी नहीं है. इसे इस तरह से मॉडल किया जा सकता है:
# BUILD
platform(
name = "exec_platform",
exec_properties = {
"test.resource": "...",
},
)
cc_test(
name = "my_test",
srcs = ["my_test.cc"],
)
exec_properties
सीधे टारगेट पर तय किए गए विकल्पों को, उन विकल्पों पर प्राथमिकता दी जाती है जो
एक्सीक्यूशन प्लैटफ़ॉर्म से इनहेरिट किए जाते हैं.