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 toolchain riêng và thực hiện toolchain resolution riêng.
Trạng thái hiện tại
Bạn có thể dùng các nhóm thực thi cho một số thao tác được khai báo gốc, chẳng hạn như CppLink
, bên trong exec_properties
để đặt các yêu cầu thực thi cho mỗi thao tác, mỗi mục tiêu. Để biết thêm thông tin chi tiết, hãy xem phần Nhóm thực thi mặc định.
Thông tin khái quát
Các 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ó thể khác nhau. Nhiều nền tảng thực thi có thể cho phép các thao tác thực thi theo cách khác, ví dụ: 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 cục bộ.
Khả năng xác định các nhóm thao tác cũng giúp giảm bớt việc sử dụng từ viết tắt của thao tác làm proxy để chỉ định thao tác. Không có gì đảm bảo rằng các phím tắt là duy nhất và chỉ có thể tham chiếu một thao tác 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 bộ nhớ cụ thể và các thao tác đòi hỏi nhiều quy trình xử lý như liên kết trong các bản dựng C++ mà không phân bổ quá mức 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 các 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ủa 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 tham số thuộc tính cfg
và mô-đun config
. 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 sẽ được tạo.
Giống như trên các quy tắc gốc, nhóm thực thi test
sẽ xuất hiện theo mặc định trên các quy tắc kiểm thử Starlark.
Truy cập vào các 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 thao tác sẽ 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 tham số exec_group
của các phương thức tạo thao tác, cụ thể là ctx.actions.run
và ctx.actions.run_shell
.
# foo.bzl
def _impl(ctx):
ctx.actions.run(
inputs = [ctx.attr._some_tool, ctx.srcs[0]]
exec_group = "compile",
# ...
)
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, tác giả quy tắc cũng sẽ có thể truy cập vào các chuỗi công cụ đã phân giải của các nhóm thực thi:
# 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",
# ...
)
Nhóm thực thi mặc định
Sau đây là các nhóm thực thi được xác định trước:
test
: Các thao tác của trình chạy kiểm thử (để biết thêm thông tin, hãy xem phần nền tảng thực thi của Bách khoa toàn thư về kiểm thử).cpp_link
: Các thao tác liên kết C++.
Sử dụng nhóm thực thi để đặt các thuộc tính thực thi
Các nhóm thực thi được tích hợp với thuộc tính exec_properties
có trên mọi quy tắc và cho phép người viết mục tiêu chỉ định một chuỗi dict gồm các thuộc tính, sau đó được truyền đến cơ chế thực thi. Ví dụ: nếu muốn đặt một số thuộc tính, chẳng hạn như bộ nhớ, cho mục tiêu và phân bổ bộ nhớ cao hơn cho một số hành động nhất định, bạn sẽ viết một mục exec_properties
có khoá tăng cườ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 thao tác với exec_group = "link"
sẽ thấy từ điển thuộc tính exec dưới dạng {"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.
Sử dụng nhóm thực thi để đặt các quy tắc ràng buộc về nền tảng
Các nhóm thực thi cũng được tích hợp với các thuộc tính exec_compatible_with
và exec_group_compatible_with
có trên mọi quy tắc và cho phép người viết mục tiêu chỉ định các ràng buộc bổ sung mà các nền tảng thực thi được chọn cho các hành động của mục tiêu phải đáp ứng.
Ví dụ: nếu quy tắc my_test
xác định nhóm thực thi link
ngoài nhóm thực thi mặc định và test
, thì việc sử dụng các thuộc tính này sẽ chạy các thao tác trong nhóm thực thi mặc định trên một nền tảng có số lượng CPU cao, thao tác kiểm thử trên Linux và thao tác liên kết trên nền tảng thực thi mặc định:
# 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"],
},
...
)
Nhóm thực thi cho các quy tắc gốc
Bạn có thể sử dụng các nhóm thực thi sau đây cho những hành động do các quy tắc gốc xác định:
test
: Các thao tác của trình chạy kiểm thử.cpp_link
: Các thao tác 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 các 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 các quy trình kiểm thử trên nền tảng exec yêu cầu phải có một số tài nguyên, nhưng không bắt buộc phải biên dịch và liên kết; bạn có thể mô hình hoá việc này 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.