Tạo Macro

Hãy tưởng tượng rằng bạn cần chạy một công cụ trong quá trình xây dựng. Ví dụ: bạn có thể tạo, xử lý trước tệp nguồn hoặc nén tệp nhị phân. Trong hướng dẫn này, bạn sẽ tạo một macro đổi kích thước hình ảnh.

Macro phù hợp cho những nhiệm vụ đơn giản. Nếu bạn muốn phức tạp hơn, chẳng hạn như hỗ trợ thêm cho ngôn ngữ lập trình mới, hãy cân nhắc tạo quy tắc. Quy tắc cung cấp cho bạn nhiều quyền kiểm soát và sự linh hoạt hơn.

Cách dễ nhất để tạo macro đổ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 các hình ảnh khác, bạn nên sử dụng lại mã. Để làm điều đó, 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],
    outs = ["small_" + src],
    cmd = "convert $< -resize " + size + " $@",
    **kwargs
  )

Một số nhận xét:

  • Theo quy ước, macro có đối số name, giống như quy tắc.

  • Để ghi lại hành vi của macro, hãy sử dụng docstring như trong Python.

  • Để gọi genrule hoặc bất kỳ quy tắc gốc nào khác, hãy sử dụng native..

  • Sử dụng **kwargs để chuyển tiếp các đối số bổ sung cho genrule (đối tượng này hoạt động giống như trong Python). Thuộc tính này 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ặc tags.

Bây giờ, hãy sử dụng macro từ 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"],
)