Membuat Makro Lama

PENTING: Tutorial ini ditujukan untuk makro lama. Jika Anda hanya perlu mendukung Bazel 8 atau yang lebih baru, sebaiknya gunakan makro simbolis; lihat Membuat Makro Simbolis.

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

Makro cocok untuk tugas sederhana. Jika Anda ingin melakukan sesuatu 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, definisikan sebuah fungsi dalam file .bzl terpisah, dan panggil file tersebut 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
    )

Sedikit catatan:

  • Menurut konvensi, makro lama memiliki argumen name, seperti aturan.

  • Untuk mendokumentasikan perilaku makro lama, gunakan docstring seperti di Python.

  • Untuk memanggil genrule, atau aturan native lainnya, tambahkan awalan native..

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

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

Terakhir, catatan peringatan: makro mengasumsikan bahwa src adalah string nama file (jika tidak, outs = ["small_" + src] akan gagal). Jadi, src = "image.png" berfungsi; tetapi apa yang terjadi jika file BUILD menggunakan src = "/versions/8.3.0//other/package:image.png", atau bahkan src = select(...)?

Anda harus memastikan untuk mendeklarasikan asumsi tersebut dalam dokumentasi makro. Sayangnya, makro lama, terutama yang berukuran besar, cenderung rapuh karena sulit untuk melihat dan mendokumentasikan semua asumsi tersebut dalam kode Anda – dan, tentu saja, beberapa pengguna makro tidak akan membaca dokumentasi. Sebaiknya, jika memungkinkan, gunakan makro simbolis, yang memiliki pemeriksaan bawaan pada jenis atribut.