Cómo crear una macro

Imagina que necesitas ejecutar una herramienta como parte de tu compilación. Por ejemplo, puede que quieras generar o procesar previamente un archivo de origen, o comprimir un objeto binario. En este instructivo, crearás una macro que cambia el tamaño de una imagen.

Las macros son adecuadas para tareas simples. Si quieres hacer algo más complicado, por ejemplo, agrega compatibilidad con un lenguaje de programación nuevo, te recomendamos que crees una regla. Las reglas te brindan más control y flexibilidad.

La forma más fácil de crear una macro que cambie el tamaño de una imagen es usar un 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"],
)

Si necesita cambiar el tamaño de otras imágenes, vuelva a usar el código. Para ello, define una función en un archivo .bzl separado y llama al archivo 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
  )

Algunos comentarios:

  • Por convención, las macros tienen un argumento name, como reglas.

  • Para documentar el comportamiento de una macro, usa docstring como en Python.

  • Para llamar a un genrule o a cualquier otra regla nativa, usa native..

  • Usa **kwargs para reenviar los argumentos adicionales al genrule subyacente (funciona como en Python). Esto es útil para que un usuario pueda usar atributos estándar como visibility o tags.

Ahora, usa la macro del archivo 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"],
)