QUAN TRỌNG: Hướng dẫn này dành cho macro cũ. Nếu chỉ cần hỗ trợ Bazel 8 trở lên, bạn nên sử dụng macro tượng trưng thay thế; hãy xem phần Tạo macro tượng trưng.
Hãy tưởng tượng rằng bạn cần chạy một công cụ trong quá trình tạo bản dựng. Ví dụ: bạn có thể muốn tạo hoặc xử lý trước một tệp nguồn, hoặc nén một tệp nhị phân. Trong hướng dẫn này, bạn sẽ tạo một macro cũ để đổi kích thước hình ảnh.
Macro phù hợp với các tác vụ đơn giản. Nếu bạn muốn làm điều gì đó phức tạp hơn, chẳng hạn như thêm tính năng hỗ trợ cho một ngôn ngữ lập trình mới, hãy cân nhắc việc tạo một quy tắc. Quy tắc giúp bạn có thêm quyền kiểm soát và sự linh hoạt.
Cách dễ nhất để tạo một macro thay đổi kích thước hình ảnh là sử dụng genrule
:
genrule(
name = "logo_miniature",
srcs = ["logo.png"],
outs = ["small_logo.png"],
cmd = "convert $< -resize 100x100 $@",
)
cc_binary(
name = "my_app",
srcs = ["my_app.cc"],
data = [":logo_miniature"],
)
Nếu cần đổi kích thước nhiều hình ảnh hơn, bạn có thể muốn sử dụng lại mã này. Để làm như vậy, hãy xác định một hàm trong tệp .bzl
riêng biệt và gọi tệp miniature.bzl
:
def miniature(name, src, size = "100x100", **kwargs):
"""Create a miniature of the src image.
The generated file is prefixed with 'small_'.
"""
native.genrule(
name = name,
srcs = [src],
# Note that the line below will fail if `src` is not a filename string
outs = ["small_" + src],
cmd = "convert $< -resize " + size + " $@",
**kwargs
)
Một số lưu ý:
Theo quy ước, các macro cũ có đối số
name
, giống như các quy tắc.Để ghi lại hành vi của một macro cũ, hãy sử dụng docstring như trong Python.
Để gọi một
genrule
hoặc bất kỳ quy tắc gốc nào khác, hãy thêm tiền tốnative.
.Sử dụng
**kwargs
để chuyển tiếp các đối số bổ sung đếngenrule
cơ bản (cách này hoạt động giống như trong Python). Điều này rất hữu ích để người dùng có thể sử dụng các thuộc tính tiêu chuẩn nhưvisibility
hoặctags
.
Bây giờ, hãy sử dụng macro trong tệp BUILD
:
load("//path/to:miniature.bzl", "miniature")
miniature(
name = "logo_miniature",
src = "image.png",
)
cc_binary(
name = "my_app",
srcs = ["my_app.cc"],
data = [":logo_miniature"],
)
Cuối cùng, lưu ý cảnh báo: macro giả định rằng src
là một chuỗi tên tệp (nếu không, outs = ["small_" + src]
sẽ không thành công). Vậy src = "image.png"
hoạt động; nhưng điều gì sẽ xảy ra nếu tệp BUILD
thay vì dùng src =
"//other/package:image.png"
, hoặc thậm chí là src = select(...)
?
Bạn nên đảm bảo khai báo những giả định như vậy trong tài liệu của macro. Rất tiếc, các macro cũ, đặc biệt là các macro lớn, có xu hướng dễ bị lỗi vì bạn khó có thể nhận thấy và ghi lại tất cả những giả định như vậy trong mã của mình – và tất nhiên, một số người dùng macro sẽ không đọc tài liệu. Nếu có thể, bạn nên sử dụng macro tượng trưng. Macro này có các chế độ kiểm tra tích hợp sẵn về các loại thuộc tính.