Nhóm thực thi

Nhóm thực thi cho phép có nhiều nền tảng thực thi trong một mục tiêu duy nhất. Mỗi nhóm thực thi có các phần phụ thuộc chuỗi công cụ riêng và thực hiện việc phân giải chuỗi công cụ riêng.

Thông tin khái quát

Nhóm thực thi cho phép tác giả quy tắc xác định các tập hợp hành động, mỗi tập hợp có một nền tảng thực thi có khả năng khác nhau. Nhiều nền tảng thực thi có thể cho phép các hành động thực thi theo cách khác nhau, chẳng hạn như biên dịch một ứng dụng iOS trên một trình thực thi từ xa (Linux), sau đó liên kết/ký mã trên một trình thực thi Mac cục bộ.

Việc có thể xác định các nhóm hành động cũng giúp giảm bớt việc sử dụng các từ gợi nhớ hành động làm proxy để chỉ định hành động. Các từ gợi nhớ không được đảm bảo là duy nhất và chỉ có thể tham chiếu đến một hành động duy nhất. Điều này đặc biệt hữu ích trong việc phân bổ thêm tài nguyên cho các hành động sử dụng nhiều bộ nhớ và xử lý như liên kết trong các bản dựng C++ mà không phân bổ quá nhiều cho các tác vụ ít đòi hỏi hơn.

Xác định nhóm thực thi

Trong quá trình xác định quy tắc, tác giả quy tắc có thể khai báo một tập hợp nhóm thực thi. Trên mỗi nhóm thực thi, tác giả quy tắc có thể chỉ định mọi thứ cần thiết để chọn một nền tảng thực thi cho nhóm thực thi đó, cụ thể là mọi ràng buộc thông qua exec_compatible_with và các loại chuỗi công cụ thông qua 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"))
    },
)

Trong đoạn mã ở trên, bạn có thể thấy rằng các phần phụ thuộc công cụ cũng có thể chỉ định quá trình chuyển đổi cho một nhóm thực thi bằng cách sử dụng cfg tham số thuộc tính và config mô-đun. Mô-đun này hiển thị một hàm exec nhận một tham số chuỗi duy nhất là tên của nhóm thực thi mà phần phụ thuộc cần được xây dựng.

Giống như trên các quy tắc gốc, nhóm thực thi test được hiển thị theo mặc định trên các quy tắc kiểm thử Starlark.

Truy cập vào nhóm thực thi

Trong quá trình triển khai quy tắc, bạn có thể khai báo rằng các hành động phải được chạy trên nền tảng thực thi của một nhóm thực thi. Bạn có thể thực hiện việc này bằng cách sử dụng exec_group tham số của các phương thức tạo hành động, cụ thể là ctx.actions.runctx.actions.run_shell.

# foo.bzl
def _impl(ctx):
  ctx.actions.run(
     inputs = [ctx.attr._some_tool, ctx.srcs[0]]
     exec_group = "compile",
     # ...
  )

Tác giả quy tắc cũng có thể truy cập vào các chuỗi công cụ đã phân giải của nhóm thực thi, tương tự như cách bạn có thể truy cập vào chuỗi công cụ đã phân giải của một mục tiêu:

# 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",
     # ...
  )

Sử dụng nhóm thực thi để đặt thuộc tính thực thi

Nhóm thực thi được tích hợp với thuộc tính exec_properties tồn tại trên mọi quy tắc và cho phép trình ghi mục tiêu chỉ định một từ điển chuỗi thuộc tính, sau đó được truyền đến cơ chế thực thi. Ví dụ: nếu bạn muốn đặt một số thuộc tính, chẳng hạn như bộ nhớ, cho mục tiêu và cấp cho một số hành động một mức phân bổ bộ nhớ cao hơn, thì bạn sẽ viết một mục exec_properties có khoá được tăng cường bằng nhóm thực thi, chẳng hạn như:

# BUILD
my_rule(
    name = 'my_target',
    exec_properties = {
        'mem': '12g',
        'link.mem': '16g'
    }
    
)

Tất cả các hành động có exec_group = "link" sẽ thấy từ điển thuộc tính thực thi là {"mem": "16g"}. Như bạn thấy ở đây, các chế độ cài đặt ở cấp nhóm thực thi sẽ ghi đè các chế độ cài đặt ở cấp mục tiêu.

Nhóm thực thi cho quy tắc gốc

Bạn có thể sử dụng các nhóm thực thi sau đây cho các hành động do quy tắc gốc xác định:

  • test: Các hành động của trình chạy kiểm thử.
  • cpp_link: Các hành động liên kết C++.

Nhóm thực thi và thuộc tính thực thi nền tảng

Bạn có thể xác định exec_properties cho các nhóm thực thi tuỳ ý trên mục tiêu nền tảng (không giống như exec_properties được đặt trực tiếp trên một mục tiêu, trong đó các thuộc tính cho các nhóm thực thi không xác định sẽ bị từ chối). Sau đó, các mục tiêu sẽ kế thừa exec_properties của nền tảng thực thi ảnh hưởng đến nhóm thực thi mặc định và mọi nhóm thực thi có liên quan khác.

Ví dụ: giả sử việc chạy một bài kiểm thử C++ yêu cầu một số tài nguyên phải có sẵn, nhưng không bắt buộc phải biên dịch và liên kết; điều này có thể được mô hình hoá như sau:

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 được xác định trực tiếp trên các mục tiêu sẽ được ưu tiên hơn những mục tiêu được kế thừa từ nền tảng thực thi.