Tạo Macro

Báo cáo vấn đề Xem nguồn Nightly · 8.4 · 8.3 · 8.2 · 8.1 · 8.0 · 7.6

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 để đổ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 có thể đổ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],
    outs = ["small_" + src],
    cmd = "convert $< -resize " + size + " $@",
    **kwargs
  )

Một số lưu ý:

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

  • Để ghi lại hành vi của một macro, 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 dùng native..

  • Sử dụng **kwargs để chuyển tiếp các đối số bổ sung đến genrule 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ặc tags.

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"],
)