گروه های اجرایی

گروه‌های اجرایی اجازه می‌دهند چندین پلتفرم اجرایی در یک هدف واحد وجود داشته باشند. هر گروه اجرایی وابستگی های زنجیره ابزار خاص خود را دارد و رزولوشن زنجیره ابزار خود را انجام می دهد.

زمینه

گروه‌های اجرایی به نویسنده قانون اجازه می‌دهند مجموعه‌ای از اقدامات را تعریف کند که هر کدام دارای یک پلت فرم اجرای بالقوه متفاوت هستند. پلتفرم‌های اجرای چندگانه می‌توانند به اجرای متفاوت اجازه دهند، به عنوان مثال، کامپایل یک برنامه iOS در یک کارگر راه دور (لینوکس) و سپس پیوند دادن/امضای کد در یک کاربر محلی مک.

توانایی تعریف گروه‌هایی از کنش‌ها همچنین به کاهش استفاده از حافظه‌های اکشن به‌عنوان یک پروکسی برای تعیین کنش‌ها کمک می‌کند. Mnemonics تضمین نمی شود که منحصر به فرد باشد و فقط می تواند به یک عمل اشاره کند. این به ویژه در تخصیص منابع اضافی به حافظه خاص و پردازش اقدامات فشرده مانند پیوند در ساخت‌های ++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"))
    },
)

در قطعه کد بالا، می بینید که وابستگی های ابزار همچنین می توانند انتقال را برای یک گروه exec با استفاده از پارامتر ویژگی cfg و ماژول config مشخص کنند. ماژول یک تابع exec را نشان می دهد که یک پارامتر رشته واحد را می گیرد که نام گروه exec است که وابستگی باید برای آن ساخته شود.

همانند قوانین بومی، گروه اجرای test به طور پیش فرض در قوانین تست Starlark وجود دارد.

ارث گروهی اجرا

علاوه بر تعریف محدودیت‌ها و زنجیره‌های ابزار خود، یک گروه اجرایی جدید می‌تواند اعلام کند که می‌خواهد از گروه اجرای پیش‌فرض قانون ارث ببرد، با عبور از پارامتر copy_from_rule = True . تنظیم copy_from_rule روی true و همچنین ارسال 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"],
)

گروه اجرای copied برای demo هدف پیکربندی شده شامل همه موارد زیر خواهد بود: - //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

گاهی اوقات می‌خواهید از یک گروه exec برای دادن ویژگی‌های exec متفاوت به اقدامات خاص استفاده کنید، اما در واقع زنجیره‌های ابزار یا محدودیت‌هایی متفاوت از قانون نمی‌خواهید. برای این شرایط، می توانید با استفاده از پارامتر copy_from_rule ، گروه های exec ایجاد کنید:

# 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 پلتفرم اجرایی را به ارث می برند که بر گروه اجرای پیش فرض و سایر گروه های اجرایی مرتبط تأثیر می گذارد.

به عنوان مثال، فرض کنید اجرای یک تست ++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 که مستقیماً بر روی اهداف تعریف می شوند، بر آنهایی که از پلتفرم اجرا به ارث رسیده اند، اولویت دارند.