IMPORTANTE: este tutorial é para macros legadas. Se você só precisar oferecer suporte ao Bazel 8 ou mais recente, recomendamos o uso de macros simbólicas. Consulte Criar uma macro simbólica.
Imagine que você precisa executar uma ferramenta como parte da sua build. Por exemplo, talvez você queira 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 a 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 uma 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, talvez queira reutilizar 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 uma
genruleou qualquer outra regra nativa, adicione o prefixonative..Use
**kwargspara encaminhar os argumentos extras para agenrulesubjacente (funciona como em Python). Isso é útil para que um usuário possa usar atributos padrão, comovisibilityoutags.
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"],
)
E, por fim, uma observação de aviso: a macro pressupõe que src seja uma string de nome de arquivo
. Caso contrário, outs = ["small_" + src] vai falhar. Portanto, src = "image.png"
funciona, mas o que acontece se o arquivo BUILD usar src =
"/versions/9.1.0//other/package:image.png" ou até mesmo src = select(...)?
É necessário declarar essas suposições na documentação da macro. Infelizmente, as macros legadas, especialmente as grandes, tendem a ser frágeis porque pode ser difícil notar e documentar todas essas suposições no código. Além disso, alguns usuários da macro não vão ler a documentação. Recomendamos, se possível, usar macros simbólicas, que têm verificações integradas nos tipos de atributos.