Membuat Makro Simbolis

Laporkan masalah Lihat sumber Nightly · 8.4 · 8.3 · 8.2 · 8.1 · 8.0 · 7.6

PENTING: Tutorial ini ditujukan untuk makro simbolis – sistem makro baru yang diperkenalkan di Bazel 8. Jika Anda perlu mendukung versi Bazel yang lebih lama, sebaiknya tulis makro lama; lihat Membuat Makro Lama.

Bayangkan Anda perlu menjalankan alat sebagai bagian dari build. Misalnya, Anda mungkin ingin membuat atau memproses file sumber, atau mengompresi biner. Dalam tutorial ini, Anda akan membuat makro simbolis yang mengubah ukuran gambar.

Makro cocok untuk tugas sederhana. Jika Anda ingin melakukan hal yang lebih rumit, misalnya menambahkan dukungan untuk bahasa pemrograman baru, pertimbangkan untuk membuat aturan. Aturan memberi Anda lebih banyak kontrol dan fleksibilitas.

Cara termudah untuk membuat makro yang mengubah ukuran gambar adalah dengan menggunakan 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"],
)

Jika Anda perlu mengubah ukuran lebih banyak gambar, Anda dapat menggunakan kembali kode tersebut. Untuk melakukannya, tentukan fungsi penerapan dan deklarasi makro dalam file .bzl terpisah, lalu panggil file miniature.bzl:

# Implementation function
def _miniature_impl(name, visibility, src, size, **kwargs):
    native.genrule(
        name = name,
        visibility = visibility,
        srcs = [src],
        outs = [name + "_small_" + src.name],
        cmd = "convert $< -resize " + size + " $@",
        **kwargs,
    )

# Macro declaration
miniature = macro(
    doc = """Create a miniature of the src image.

    The generated file name will be prefixed with `name + "_small_"`.
    """,
    implementation = _miniature_impl,
    # Inherit most of genrule's attributes (such as tags and testonly)
    inherit_attrs = native.genrule,
    attrs = {
        "src": attr.label(
            doc = "Image file",
            allow_single_file = True,
            # Non-configurable because our genrule's output filename is
            # suffixed with src's name. (We want to suffix the output file with
            # srcs's name because some tools that operate on image files expect
            # the files to have the right file extension.)
            configurable = False,
        ),
        "size": attr.string(
            doc = "Output size in WxH format",
            default = "100x100",
        ),
        # Do not allow callers of miniature() to set srcs, cmd, or outs -
        # _miniature_impl overrides their values when calling native.genrule()
        "srcs": None,
        "cmd": None,
        "outs": None,
    },
)

Beberapa catatan:

  • Fungsi penerapan makro simbolis harus memiliki parameter name dan visibility. Harus digunakan untuk target utama makro.

  • Untuk mendokumentasikan perilaku makro simbolis, gunakan parameter doc untuk macro() dan atributnya.

  • Untuk memanggil genrule, atau aturan native lainnya, gunakan native..

  • Gunakan **kwargs untuk meneruskan argumen turunan tambahan ke genrule yang mendasarinya (berfungsi seperti di Python). Hal ini berguna agar pengguna dapat menetapkan atribut standar seperti tags atau testonly.

Sekarang, gunakan makro dari file 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"],
)