Derleme Etkinliği Protokolü'nün tüm spesifikasyonu, protokol arabelleği tanımında bulunabilir. Ancak spesifikasyona bakmadan önce biraz fikir edinmeniz faydalı olabilir.
foo.sh
ve foo_test.sh
adlı iki boş kabuk komut dosyası ile 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 bahsedilen üst
ve alt ilişkisini gösterir. Bazı derleme etkinliklerinin ve çoğu alanın kısalık için atlandığını unutmayın.
Şekil 1. BEP grafiği.
Başlangıçta bir BuildStarted
etkinliği yayınlanır. 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ığıyla ilgili bilgi sağlar.
PatternExpanded
oluşturma etkinliği, ...
kalıbının hangi belirli hedeflere genişletildiğine dair bilgi sağlar: //foo:foo_lib
ve //foo:foo_test
. Bunu, iki TargetConfigured
etkinliğini çocuk 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.
Üst ve alt ilişkisinin yanı sıra etkinlikler de kendi derleme etkinliği tanımlayıcıları kullanılarak birbirlerine işaret edebilir. Örneğin, yukarıdaki grafikte TargetComplete
etkinliği, fileSets
alanındaki NamedSetOfFiles
etkinliğine başvuruda bulunur.
Dosyalara atıfta bulunan derleme etkinlikleri, genellikle dosya adlarını ve yolları etkinliğe yerleştirmez. Bunun yerine, NamedSetOfFiles
etkinliğinin derleme etkinliği tanımlayıcısını içerir. Bu tanımlayıcı, 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 Derleme Etkinlik Protokolü çıkış boyutu, dosya sayısıyla birlikte ikinci dereceye kadar büyüyeceğinden 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ılı bir şekilde oluşturulup oluşturulmadığı, çıkış dosyaları kümesi ve oluşturulan hedefin türü ile ilgili bilgileri 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.
Yönlere özgü etkinlik türleri olmamasına rağmen, yönlerle ilgili değerlendirme sonuçları BEP'de kullanılabilir. 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 derlenirse şu 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üketimi
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, bir Starlark Depset'in yapısına uygun olan NamedSetOfFiles
etkinliği tarafından sunulan yinelemeli ve paylaşılan yapı ele alınmaktadır.
Büyük derlemeler on binlerce bu tür etkinlik içerebileceğinden ve bu da kare karmaşıklığa sahip bir tarama işleminde yüz milyonlarca işlem gerektirdiğinden, tüketiciler NamedSetOfFiles
etkinliklerini işlerken kare algoritmalardan kaçınmalıdır.
Şekil 2. NamedSetOfFiles
BEP grafiği.
NamedSetOfFiles
etkinliği, bu etkinliğe referans veren TargetComplete
veya NamedSetOfFiles
etkinliğinden önce BEP akışında her zaman 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 sipariş ve paylaşım kısıtlamaları nedeniyle, normal bir tüketici BEP akışı bitene kadar tüm NamedSetOfFiles
etkinliklerini arabelleğe almalıdır. 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)