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