Como criar uma macro

Informar um problema Mostrar fonte Por noite · 7,3 · 7,2 · 7,1 · 7,0 · 6,5

Imagine que você precise executar uma ferramenta como parte do build. Por exemplo, talvez você queira gerar ou pré-processar um arquivo de origem ou compactar um binário. Neste você vai criar uma macro que redimensiona uma imagem.

Macros são adequadas para tarefas simples. Se você quiser fazer mais alguma coisa complicada, 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 redimensione 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 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],
    outs = ["small_" + src],
    cmd = "convert $< -resize " + size + " $@",
    **kwargs
  )

Algumas observações:

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

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

  • Para chamar uma genrule ou qualquer outra regra nativa, use native..

  • Use **kwargs para encaminhar os outros argumentos ao genrule. Ele funciona como 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"],
)