Membuat Makro Simbolis

Laporkan masalah Lihat sumber Nightly · 7.4 . 7.3 · 7.2 · 7.1 · 7.0 · 6.5

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 sebelumnya, 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, sebaiknya buat 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 perlu mengubah ukuran lebih banyak gambar, sebaiknya gunakan kembali kode tersebut. Untuk melakukannya, tentukan fungsi implementasi 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 implementasi makro simbolis harus memiliki parameter name dan visibility. Nilai ini 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 tambahan yang diwarisi 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"],
)