Sembolik makro oluşturma

Sorun bildirme Kaynağı görüntüleme Nightly · 7.4 . 7.3 · 7.2 · 7.1 · 7.0 · 6.5

ÖNEMLİ: Bu eğitim, Bazel 8'de kullanıma sunulan yeni makro sistemi olan sembolik makrolar içindir. Eski Bazel sürümlerini desteklemeniz gerekiyorsa bunun yerine eski bir makro yazmanız gerekir. Eski Makro Oluşturma başlıklı makaleyi inceleyin.

Derleme işleminiz kapsamında bir araç çalıştırmanız gerektiğini varsayalım. Örneğin, bir kaynak dosya oluşturmak veya önceden işlemek ya da bir ikili dosyayı sıkıştırmak isteyebilirsiniz. Bu eğitimde, bir resmin boyutunu değiştiren sembolik bir makro oluşturacaksınız.

Makrolar basit görevler için uygundur. Daha karmaşık bir işlem yapmak istiyorsanız (ör. yeni bir programlama dili için destek eklemek) kural oluşturabilirsiniz. Kurallar size daha fazla kontrol ve esneklik sağlar.

Bir resmin boyutunu değiştiren bir makro oluşturmanın en kolay yolu genrule kullanmaktır:

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

Daha fazla resmi yeniden boyutlandırmanız gerekiyorsa kodu yeniden kullanabilirsiniz. Bunun için ayrı bir .bzl dosyasında bir uygulama işlevi ve makro beyanı tanımlayın ve dosyayı miniature.bzl olarak adlandırın:

# 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,
    },
)

Birkaç açıklama:

  • Sembolik makro uygulama işlevlerinde name ve visibility parametreleri olmalıdır. Bunlar, makronun ana hedefi için kullanılmalıdır.

  • Sembolik bir makronun davranışını belgelemek için macro() ve özellikleri için doc parametrelerini kullanın.

  • Bir genrule veya başka bir yerel kuralı çağırmak için native. kullanın.

  • Devralınan ek bağımsız değişkenleri temel genrule işlevine iletmek için **kwargs kullanın (tıpkı Python'da olduğu gibi çalışır). Bu, kullanıcıların tags veya testonly gibi standart özellikleri ayarlayabilmesi için kullanışlıdır.

Ardından, BUILD dosyasında bulunan makroyu kullanın:

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