BazelCon 2022 findet vom 16. bis 17. November in New York und online statt.
Jetzt anmelden

Makros erstellen

Mit Sammlungen den Überblick behalten Sie können Inhalte basierend auf Ihren Einstellungen speichern und kategorisieren.

Stellen Sie sich vor, Sie müssen ein Tool als Teil Ihres Builds ausführen. Sie können beispielsweise eine Quelldatei generieren oder vorverarbeiten oder eine Binärdatei komprimieren. In dieser Anleitung erstellen Sie ein Makro, mit dem die Größe eines Bildes angepasst wird.

Makros eignen sich für einfache Aufgaben. Wenn Sie komplexere Änderungen vornehmen möchten und beispielsweise eine neue Programmiersprache unterstützen, können Sie eine Regel erstellen. Regeln bieten mehr Kontrolle und Flexibilität.

Am einfachsten erstellen Sie ein Makro, das die Größe eines Bildes ändert, mit einem 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"],
)

Wenn Sie die Größe weiterer Bilder ändern möchten, können Sie den Code wiederverwenden. Definieren Sie dazu eine Funktion in einer separaten .bzl-Datei und rufen Sie die Datei miniature.bzl auf:

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
  )

Einige Anmerkungen:

  • Genau wie Regeln haben Makros standardmäßig ein name-Argument.

  • Zum Dokumentieren des Verhaltens eines Makros verwenden Sie docstring wie in Python.

  • Verwenden Sie native. zum Aufrufen von genrule oder einer anderen nativen Regel.

  • Verwenden Sie **kwargs, um die zusätzlichen Argumente an die zugrunde liegende genrule weiterzuleiten. Dies funktioniert genau wie bei Python. Dies ist hilfreich, damit Nutzer Standardattribute wie visibility oder tags verwenden können.

Verwenden Sie jetzt das Makro aus der Datei 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"],
)