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 prefixonative.
.Use
**kwargs
para encaminhar os argumentos extras aogenrule
subjacente. Isso funciona da mesma forma que no Python. Isso é útil para que um usuário possa usar atributos padrão comovisibility
outags
.
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.