IMPORTANTE: este tutorial é para macros simbólicas, o novo sistema de macros introduzido no Bazel 8. Se você precisar oferecer suporte a versões mais antigas do Bazel, escreva uma macro legada. Consulte Como criar uma macro legada.
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 simbólica 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 isso, defina uma função de implementação e uma declaração de macro em um arquivo .bzl
separado e chame o arquivo miniature.bzl
:
# 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,
},
)
Algumas observações:
As funções de implementação de macros simbólicas precisam ter parâmetros
name
evisibility
. Elas devem ser usadas para o principal objetivo da macro.Para documentar o comportamento de uma macro simbólica, use parâmetros
doc
paramacro()
e seus atributos.Para chamar um
genrule
ou qualquer outra regra nativa, usenative.
.Use
**kwargs
para encaminhar os argumentos herdados extras para ogenrule
subjacente. Ele funciona da mesma forma que no Python. Isso é útil para que um usuário possa definir atributos padrão comotags
outestonly
.
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"],
)