Derleme Etkinliği Protokolü Örnekleri

Sorun bildirme Kaynağı görüntüleme Nightly · 7.4 . 7.3 · 7.2 · 7.1 · 7.0 · 6.5

Build Event Protocol'ün tam spesifikasyonunu, protokol arabelleği tanımında bulabilirsiniz. Ancak spesifikasyona bakmadan önce biraz fikir edinmeniz faydalı olabilir.

İki boş kabuk komut dosyasından (foo.sh ve foo_test.sh) ve aşağıdaki BUILD dosyasından oluşan basit bir Bazel çalışma alanını düşünün:

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

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

Bu projede bazel test ... çalıştırıldığında, oluşturulan derleme etkinliklerinin derleme grafiği aşağıdaki grafiğe benzer. Oklar, yukarıda belirtilen üst öğe ve alt öğe ilişkisini gösterir. Bazı derleme etkinliklerinin ve çoğu alanın kısaltılması için çıkarıldığını unutmayın.

bep-graph

Şekil 1. BEP grafiği.

İlk olarak bir BuildStarted etkinliği yayınlanır. Bu etkinlik, derlemenin bazel test komutu aracılığıyla çağrıldığını bize bildirir ve alt etkinlikleri duyurur:

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

İlk üç etkinlik, Bazel'in nasıl çağrıldığı hakkında bilgi sağlar.

PatternExpanded derleme etkinliği, ... kalıbının hangi belirli hedeflere genişlediği hakkında bilgi sağlar: //foo:foo_lib ve //foo:foo_test. Bunu, iki TargetConfigured etkinliğini çocuk olarak tanımlayarak yapar. TargetConfigured etkinliğinin, Configuration etkinliği TargetConfigured etkinliğinden önce yayınlanmış olsa bile Configuration etkinliğini alt etkinlik olarak tanımladığını unutmayın.

Etkinlikler, üst öğe ve alt öğe ilişkisinin yanı sıra derleme etkinliği tanımlayıcılarını kullanarak da birbirlerine referans verebilir. Örneğin, yukarıdaki grafikte TargetComplete etkinliği, fileSets alanındaki NamedSetOfFiles etkinliğini ifade eder.

Dosyalara atıfta bulunan derleme etkinlikleri, genellikle dosya adlarını ve yolları etkinliğe yerleştirmez. Bunun yerine, bir NamedSetOfFiles etkinliğinin derleme etkinliği tanımlayıcısını içerir. Daha sonra bu etkinlik, gerçek dosya adlarını ve yollarını içerir. NamedSetOfFiles etkinliği, bir dosya grubunun bir kez raporlanmasına ve birçok hedef tarafından referans alınmasına olanak tanır. Aksi takdirde bazı durumlarda Build Event Protocol çıkış boyutu, dosya sayısıyla birlikte karesel olarak büyüyeceği için bu yapı gereklidir. Ayrıca bir NamedSetOfFiles etkinliğine tüm dosyalar yerleştirilmemiş olabilir. Bunun yerine, oluşturma etkinliği tanımlayıcıları aracılığıyla diğer NamedSetOfFiles etkinliklerine referans verilir.

Aşağıda, yukarıdaki grafikteki //foo:foo_lib hedefi için TargetComplete etkinliğinin, protokol arabelleğinin JSON temsilinde basılı bir örneği verilmiştir. Derleme etkinliği tanımlayıcısı, hedefi opak bir dize olarak içerir ve derleme etkinliği tanımlayıcısını kullanarak Configuration etkinliğini ifade eder. Etkinlik, alt etkinlik duyurmaz. Yük, hedefin başarıyla oluşturulup oluşturulmadığı, çıkış dosyası grubu ve oluşturulan hedef türü hakkında bilgi içerir.

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

BEP'de Yönem Sonuçları

Normal derlemeler, (target, configuration) çiftleriyle ilişkili işlemleri değerlendirir. Aspektler etkinken Bazel, belirli bir etkin özellikten etkilenen her hedef için (target, configuration, aspect) üçlüleriyle ilişkili hedefleri de değerlendirir.

Konuya özgü etkinlik türleri bulunmasa bile, unsurlara ilişkin değerlendirme sonuçları BEP'de mevcuttur. Geçerli bir yönü olan her (target, configuration) çifti için Bazel, yönü hedefe uygulamanın sonucunu içeren ek bir TargetConfigured ve TargetComplete etkinliği yayınlar. Örneğin, //:foo_lib, --aspects=aspects/myaspect.bzl%custom_aspect ile oluşturulduysa bu etkinlik BEP'de de görünür:

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

NamedSetOfFiles tüketiliyor

Belirli bir hedef (veya unsur) tarafından üretilen yapıları belirlemek, bir hazırlıkla verimli bir şekilde yapılabilecek, yaygın olarak kullanılan bir BEP kullanım alanıdır. Bu bölümde, NamedSetOfFiles etkinliğinin sunduğu ve Starlark Depset yapısıyla eşleşen yinelenen, paylaşılan yapı ele alınmaktadır.

Büyük derlemeler bu tür on binlerce etkinliği içerebildiği ve ikinci dereceden karmaşıklığa sahip geçişlerde yüz milyonlarca işlem gerektirebileceği için tüketiciler NamedSetOfFiles etkinliklerini işlerken ikinci dereceden algoritmalardan kaçınmaya dikkat etmelidir.

namedsetoffiles-bep-graph

Şekil 2. NamedSetOfFiles BEP grafiği.

NamedSetOfFiles etkinliği, BEP akışında kendisine referans veren TargetComplete veya NamedSetOfFiles etkinliğinden önce görünür. Bu, ilk etkinlik dışındaki tüm etkinliklerin, etkinliği duyuran en az bir etkinlikten sonra göründüğü "üst-alt" etkinlik ilişkisinin tersidir. NamedSetOfFiles etkinliği, anlamsallığı olmayan bir Progress etkinliği tarafından duyurulur.

Bu sıralama ve paylaşım kısıtlamaları göz önüne alındığında, tipik bir tüketicinin BEP akışı sona erene kadar tüm NamedSetOfFiles etkinliklerini arabelleğe alması gerekir. Aşağıdaki JSON etkinlik akışı ve Python kodu, "varsayılan" çıkış grubundaki hedef/yönden oluşturulmuş yapıların haritasının nasıl doldurulacağını ve oluşturulmuş hedeflerin/yönlerin alt kümesi için çıkışların nasıl işleneceğini gösterir:

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)