Derleme Etkinliği Protokolü Örnekleri

Derleme Etkinliği Protokolü'nün tam spesifikasyonunu protokol arabellek tanımında bulabilirsiniz. Ancak spesifikasyona bakmadan önce sezgi oluşturmak faydalı olabilir.

İki boş kabuk komut dosyası olan foo.sh ve foo_test.sh ile aşağıdaki BUILD dosyasından oluşan basit bir Bazel çalışma alanı 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ılırken oluşturulan derleme etkinliklerinin derleme grafiği aşağıdaki grafiğe benzeyecektir. Oklar, bahsi geçen üst ve alt ilişkiyi gösterir. Bazı derleme etkinliklerinin ve çoğu alanın kısa olması için çıkarıldığını unutmayın.

bep-grafik

Şekil 1. BEP grafiği.

Başlangıçta bir BuildStarted etkinliği yayınlanır. Etkinlik bize derlemenin bazel test komutuyla çağrıldığını bildirir ve alt etkinlikleri duyurur:

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

İlk üç etkinlik, Bazel'ın nasıl çağrıldığıyla ilgili bilgi sağlar.

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

Etkinlikler, üst ve alt ilişkisinin yanı sıra derleme etkinliği tanımlayıcılarını kullanarak birbirlerine de başvuruda bulunabilir. Örneğin, yukarıdaki grafikte TargetComplete etkinliği, fileSets alanındaki NamedSetOfFiles etkinliğine karşılık gelir.

Dosyalara referans veren 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. Bu tanımlayıcı, gerçek dosya adlarını ve yolları da içerir. NamedSetOfFiles etkinliği, bir dizi dosyanın bir kez raporlanmasına ve birçok hedef tarafından referans verilmesine olanak tanır. Aksi takdirde, Derleme Etkinliği Protokolü çıkış boyutu dosya sayısıyla birlikte ikinci dereceden büyüyeceğinden bu yapı gereklidir. Bir NamedSetOfFiles etkinliğindeki tüm dosyalar yerleşik olmayabilir. Bunun yerine, derleme etkinliği tanımlayıcıları üzerinden diğer NamedSetOfFiles etkinliklerine başvuruda bulunabilir.

Aşağıda, yukarıdaki grafikte yer alan //foo:foo_lib hedefi için TargetComplete etkinliğinin bir örneği protokol arabelleğinin JSON gösteriminde yazılıdır. 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ğine referans verir. Etkinlik herhangi bir alt etkinlik duyurusu yapmaz. Yük; hedefin başarılı bir şekilde derlenip derlenmediği, çıkış dosyaları kümesi ve oluşturulan hedefin türü hakkında bilgiler 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'deki Sonuçları İnceleme

Sıradan derlemeler, (target, configuration) çiftleriyle ilişkili işlemleri değerlendirir. Yönler etkinken Bazel, ayrıca belirli bir etkin unsurdan etkilenen her hedef için (target, configuration, aspect) üç adımla ilişkili hedefleri de değerlendirir.

Yöne özgü etkinlik türleri olmasa da BEP'de yönler için değerlendirme sonuçları mevcuttur. Geçerli bir özelliğe sahip her (target, configuration) çifti için Bazel, bu özelliğin hedefe uygulanmasını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 özellik) tarafından üretilen yapıların belirlenmesi, biraz hazırlıkla verimli bir şekilde yapılabilen yaygın bir BEP kullanım alanıdır. Bu bölümde NamedSetOfFiles etkinliği tarafından sunulan ve Starlark Depset'in yapısıyla eşleşen yinelemeli, paylaşılan yapı açıklanmaktadır.

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

adlandırılmışsetoffiles-bep-graph

2. Şekil. NamedSetOfFiles BEP grafiği.

NamedSetOfFiles etkinliği, BEP akışında her zaman kendisine referans veren TargetComplete veya NamedSetOfFiles etkinliğinden önce görünür. Bu, "üst-öğe" etkinlik ilişkisinin tersidir. Bu ilişkide, ilk etkinlik hariç tümü, etkinlik duyurusundan sonra en az bir etkinlikten sonra görünür. Bir NamedSetOfFiles etkinliği, anlam içermeyen bir Progress etkinliği tarafından duyurulur.

Bu sıralama ve paylaşım kısıtlamaları göz önünde bulundurulduğunda, tipik bir tüketicinin BEP akışı tüketilene kadar tüm NamedSetOfFiles etkinliklerini arabelleğe alması gerekir. Aşağıdaki JSON etkinlik akışı ve Python kodunda, bir haritanın "varsayılan" çıkış grubundaki hedef/en boydan derlenmiş yapılara nasıl doldurulacağı ve oluşturulmuş hedeflerin/yönlerin alt kümesi için çıktıların nasıl işleneceği gösterilmektedir:

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)