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. Confira como criar uma macro legada.
Imagine que você precisa executar uma ferramenta como parte do seu build. Por exemplo, você pode 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, como 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 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, use o código novamente. Para fazer isso,
defina uma função de implementação e uma declaração de macro em um arquivo
.bzl
separado e chame o arquivo de 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
. Eles devem ser usados para o alvo principal da macro.Para documentar o comportamento de uma macro simbólica, use parâmetros
doc
paramacro()
e os atributos dela.Para chamar uma
genrule
ou qualquer outra regra nativa, usenative.
.Use
**kwargs
para encaminhar os argumentos herdados extras para ogenrule
(funciona exatamente como 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"],
)