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