Criar uma macro legada

Informar um problema Ver fonte Nightly · 8.3 · 8.2 · 8.1 · 8.0 · 7.6

IMPORTANTE: este tutorial é para macros legadas. Se você só precisar oferecer suporte ao Bazel 8 ou mais recente, recomendamos usar macros simbólicas. Consulte Como criar uma macro simbólica.

Imagine que você precise executar uma ferramenta como parte da sua build. Por exemplo, você pode querer gerar ou pré-processar um arquivo de origem ou compactar um binário. Neste tutorial, você vai criar uma macro legada que redimensiona uma imagem.

As macros são adequadas para tarefas simples. Se você quiser fazer algo mais complicado, por exemplo, adicionar suporte para uma nova linguagem de programação, considere criar uma regra. As regras oferecem mais controle e flexibilidade.

A maneira mais fácil de criar uma macro que redimensiona uma imagem é usar um 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"],
)

Se você precisar redimensionar mais imagens, reutilize o código. Para fazer isso, defina uma função em um arquivo .bzl separado e chame o arquivo 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
    )

Algumas observações:

  • Por convenção, as macros legadas têm um argumento name, assim como as regras.

  • Para documentar o comportamento de uma macro legada, use docstring, como no Python.

  • Para chamar um genrule ou qualquer outra regra nativa, use o prefixo native..

  • Use **kwargs para encaminhar os argumentos extras ao genrule subjacente. Isso funciona da mesma forma que no Python. Isso é útil para que um usuário possa usar atributos padrão como visibility ou tags.

Agora, use a macro do arquivo 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"],
)

Por fim, uma observação de aviso: a macro pressupõe que src é uma string de nome de arquivo. Caso contrário, outs = ["small_" + src] vai falhar. Então, src = "image.png" funciona. Mas o que acontece se o arquivo BUILD usar src = "//other/package:image.png" ou até mesmo src = select(...)?

Declare essas proposições na documentação da sua macro. Infelizmente, as macros legadas, principalmente as grandes, tendem a ser frágeis porque pode ser difícil notar e documentar todas essas proposições no código. Além disso, alguns usuários da macro não leem a documentação. Recomendamos, se possível, usar macros simbólicas, que têm verificações integradas nos tipos de atributos.