Ejemplos de protocolo de eventos de compilación

Informar un problema Ver fuente Por la noche · 7.2 · 7.1 · 7.0 · 6.5 · 6.4

La especificación completa del protocolo del evento de compilación se puede encontrar en su protocolo definición del búfer. Sin embargo, podría ser útil aprender algo de intuición antes de mirar la especificación.

Considera un lugar de trabajo simple de Bazel que consta de dos secuencias de comandos de shell vacías foo.sh y foo_test.sh, y el siguiente archivo BUILD:

sh_library(
    name = "foo_lib",
    srcs = ["foo.sh"],
)

sh_test(
    name = "foo_test",
    srcs = ["foo_test.sh"],
    deps = [":foo_lib"],
)

Cuando se ejecuta bazel test ... en este proyecto, el gráfico de compilación del elemento generado de compilación serán similares al siguiente gráfico. Las flechas indican antes mencionada. Ten en cuenta que algunos eventos de compilación y la mayoría de los campos se omitieron para mayor brevedad.

bep-graph

Figura 1: Grafo de BEP.

Inicialmente, se publica un evento BuildStarted. El evento nos informa que el Se invocó la compilación mediante el comando bazel test y anuncia eventos secundarios:

  • OptionsParsed
  • WorkspaceStatus
  • CommandLine
  • UnstructuredCommandLine
  • BuildMetadata
  • BuildFinished
  • PatternExpanded
  • Progress

Los primeros tres eventos proporcionan información sobre cómo se invocó Bazel.

El evento de compilación PatternExpanded proporciona estadísticas a los que se expandió el patrón ... de destinos específicos: //foo:foo_lib y //foo:foo_test. Para ello, declara dos TargetConfigured eventos como secundarios. Ten en cuenta que el evento TargetConfigured declara el evento Configuration como un evento secundario, aunque Configuration se publicó antes del evento TargetConfigured.

Además de la relación entre padres e hijos, los eventos también pueden hacer referencia entre sí. con identificadores de eventos de compilación. Por ejemplo, en el gráfico anterior la El evento TargetComplete hace referencia al evento NamedSetOfFiles en su fileSets .

Los eventos de compilación que hacen referencia a archivos no suelen incorporarlos. y las rutas de acceso en el evento. En su lugar, contienen el identificador del evento de compilación de un evento NamedSetOfFiles, que contendrá los nombres de archivos reales y rutas de ataque. El evento NamedSetOfFiles permite que un conjunto de archivos se informe una vez y a las que se hace referencia. Esta estructura es necesaria porque, de lo contrario, En algunos casos, el tamaño de salida del protocolo de eventos de compilación crecería cuadráticamente con la cantidad de archivos. Además, es posible que un evento NamedSetOfFiles no tenga todos sus archivos incorporados, sino que hacen referencia a otros eventos NamedSetOfFiles a través de su identificadores de eventos de compilación.

A continuación, se muestra una instancia del evento TargetComplete correspondiente al evento //foo:foo_lib. como destino del gráfico anterior, impreso en la representación JSON del búfer de protocolo. El identificador del evento de compilación contiene el objetivo como una cadena opaca y hace referencia a El evento Configuration mediante su identificador de evento de compilación El evento no anunciar eventos secundarios. La carga útil contiene información sobre si el el destino se compiló correctamente, el conjunto de archivos de salida y el tipo construyen.

{
  "id": {
    "targetCompleted": {
      "label": "//foo:foo_lib",
      "configuration": {
        "id": "544e39a7f0abdb3efdd29d675a48bc6a"
      }
    }
  },
  "completed": {
    "success": true,
    "outputGroup": [{
      "name": "default",
      "fileSets": [{
        "id": "0"
      }]
    }],
    "targetKind": "sh_library rule"
  }
}

Resultados de aspecto en BEP

Las compilaciones comunes evalúan acciones asociadas con (target, configuration). pares. Cuando compilas con aspects habilitados, Bazel Además, evalúa objetivos asociados con triples de (target, configuration, aspect) para cada objetivo afectado por un aspecto habilitado determinado.

Los resultados de la evaluación de aspectos están disponibles en BEP a pesar de la ausencia de tipos de eventos de aspecto específico. Para cada par (target, configuration) con un aspecto correspondiente, Bazel publica un TargetConfigured adicional y TargetComplete que lleva el resultado de la aplicación del aspecto al objetivo. Por ejemplo, si //:foo_lib se compila con --aspects=aspects/myaspect.bzl%custom_aspect, este evento también aparecerá en la BEP:

{
  "id": {
    "targetCompleted": {
      "label": "//foo:foo_lib",
      "configuration": {
        "id": "544e39a7f0abdb3efdd29d675a48bc6a"
      },
      "aspect": "aspects/myaspect.bzl%custom_aspect"
    }
  },
  "completed": {
    "success": true,
    "outputGroup": [{
      "name": "default",
      "fileSets": [{
        "id": "1"
      }]
    }]
  }
}

Consumo de NamedSetOfFiles

Determinar los artefactos producidos por un objetivo (o aspecto) determinado es una práctica caso de uso de BEP que se puede hacer de manera eficiente con un poco de preparación. Esta sección Se analiza la estructura recursiva y compartida que ofrece NamedSetOfFiles. evento, que coincide con la estructura de un Depset de Starlark.

Los consumidores deben evitar los algoritmos cuadráticos al procesar NamedSetOfFiles porque las compilaciones grandes pueden contener decenas de miles de estos eventos, lo que requiere cientos de millones de operaciones en un recorrido con complejidad cuadrática.

namedsetoffiles-bep-graph

Figura 2: Gráfico de BEP de NamedSetOfFiles.

Un evento NamedSetOfFiles siempre aparece en la transmisión de BEP antes de TargetComplete o NamedSetOfFiles que hace referencia a ella. Este es el inversa de "principal-secundario" relación de evento, en la que todos, excepto el primer aparece después de al menos un evento en el que se anuncie. Un evento NamedSetOfFiles es anunciado por un evento Progress sin semántica.

Dadas estas restricciones para ordenar y compartir, un consumidor típico debe almacenar en búfer todos Eventos NamedSetOfFiles hasta que se agote la transmisión de BEP. El siguiente JSON de eventos y el código de Python demuestran cómo completar un mapa desde objetivo/aspecto para compilar artefactos en la “configuración grupo de salida y cómo Procesar los resultados para un subconjunto de objetivos o aspectos compilados:

named_sets = {}  # type: dict[str, NamedSetOfFiles]
outputs = {}     # type: dict[str, dict[str, set[str]]]

for event in stream:
  kind = event.id.WhichOneof("id")
  if kind == "named_set":
    named_sets[event.id.named_set.id] = event.named_set_of_files
  elif kind == "target_completed":
    tc = event.id.target_completed
    target_id = (tc.label, tc.configuration.id, tc.aspect)
    outputs[target_id] = {}
    for group in event.completed.output_group:
      outputs[target_id][group.name] = {fs.id for fs in group.file_sets}

for result_id in relevant_subset(outputs.keys()):
  visit = outputs[result_id].get("default", [])
  seen_sets = set(visit)
  while visit:
    set_name = visit.pop()
    s = named_sets[set_name]
    for f in s.files:
      process_file(result_id, f)
    for fs in s.file_sets:
      if fs.id not in seen_sets:
        visit.add(fs.id)
        seen_sets.add(fs.id)