Derleme veya kontrol sırasında A
için B
gerekiyorsa bir A
hedefi B
hedefine bağlıdır
biraz zaman alabilir. Şunlara bağlıdır: İlişki,
Yönlendirilmiş Döngüsel Grafik
(DAG) kullanır ve buna bağımlılık grafiği adı verilir.
Bir hedefin doğrudan bağımlılıkları, bir yolla ulaşılabilen diğer hedeflerdir uzunluğu 1’dir. Bir hedefin geçişli bağımlılıkları herhangi bir uzunluktaki bir yolla bağlı olduğu o hedefleri izler.
Aslında, derlemeler bağlamında iki bağımlılık grafiği vardır: gerçek bağımlılıkların sayısını ve bildirilen bağımlılıkların grafiğini görebilirsiniz. Çoğu bu iki grafik o kadar benzerdir ki bu ayrımın yapılması gerekmez bu metin, aşağıdaki tartışma için faydalıdır.
Gerçek ve bildirilen bağımlılıklar
Y
olması gerekiyorsa hedef X
, Y
hedefine aslında bağımlıdır.
doğru şekilde tasarlanması için X
adlı bir tasarım öğesi içermesi gerekir. Oluşturuldu
oluşturulmuş, işlenmiş, derlenmiş, bağlantılı, arşivlenmiş, sıkıştırılmış, yürütülen veya
rutin olarak gerçekleşen diğer görev türlerini kapsar.
Bağımlılık varsa X
hedefinin Y
hedefinde bildirilen bir bağımlılığı var
X
paketinde X
ile Y
arasında.
Doğru derlemeler için gerçek bağımlılıklar grafiği A,
tanımlanan bağımlılıkların grafiği D. Başka bir deyişle,
A bölgesindeki x --> y
doğrudan bağlı düğümlerin de doğrudan bağlı olması gerekir
D. D'nin, A'ya fazla tahmini olduğu söylenebilir.
BUILD
dosya yazarları,
bağımlılığının altını çizer.
Bu ilkeye uyulmaması tanımlanmamış davranışa neden olur: Derleme başarısız olabilir, Ancak daha da kötüsü, derleme önceki bazı işlemlere veya geçişli bağımlılıkları belirlemenize yardımcı olur. Bazel eksik olup olmadığını kontrol ediyor bağımlılıkları ve rapor hatalarını takip eder, ancak bu kontrolün tüm durumlarda eksiksiz olmalıdır.
Dolaylı olarak içe aktarılan her şeyi listelemenize gerek yoktur (ve denememelisiniz).
A
tarihine kadar gerekse bile geçerlidir.
X
hedefi oluşturma sırasında, derleme aracı tüm geçişli öğeyi inceler
Bu hedeflerdeki herhangi bir değişikliğin yapıldığından emin olmak için X
bağımlılıkları
ve ara ürünleri gerektiği şekilde yeniden oluşturarak nihai sonuca yansıtılır.
Bağımlılıkların geçişli doğası yaygın bir hataya yol açar. Bazen,
dosyadaki kod dolaylı bir bağımlılık tarafından sağlanan kodu kullanabilir.
beyan edilen bağımlılık grafiğinde geçişli ancak doğrudan kenar yoktur. Dolaylı
bağımlılıklar BUILD
dosyasında görünmez. Çünkü kural
gibi bir strateji de dahil olmadığı sürece,
aşağıdaki örnek zaman çizelgesini inceleyin:
1. Bildirilen bağımlılıklar gerçek bağımlılıklarla eşleşiyor
Başlangıçta her şey çalışır. a
paketindeki kod, b
paketindeki kodu kullanıyor.
b
paketindeki kod, c
paketindeki kodu kullandığından geçişli olarak a
kullanıyor
şuna bağlıdır: c
.
a/BUILD |
b/BUILD |
---|---|
rule( name = "a", srcs = "a.in", deps = "//b:b", ) |
rule( name = "b", srcs = "b.in", deps = "//c:c", ) |
a / a.in |
b / b.in |
import b; b.foo(); |
import c; function foo() { c.bar(); } |
|
|
Beyan edilen bağımlılıklar, gerçek bağımlılıklara fazla yakındır. Her şey yolunda.
2. Bildirilmemiş bir bağımlılık ekleme
Birisi a
uygulamasına kod ekleyen ve
c
üzerinde doğrudan gerçek bağımlılığa neden oluyor, ancak bunu derleme dosyasında bildirmeyi unutuyor
a/BUILD
.
a / a.in |
|
---|---|
import b; import c; b.foo(); c.garply(); |
|
|
|
Beyan edilen bağımlılıklar, artık gerçek bağımlılıklara fazla değer vermiyor.
Bu normal olabilir, çünkü iki grafiğin geçişli kapanışları eşittir,
ancak bir sorunu maskeliyor: a
, c
öğesine gerçek ancak bildirilmemiş bir bağımlılığa sahip.
3. Beyan edilen bağımlılık grafikleri ile gerçek bağımlılık grafikleri arasındaki farklılık
Birisi b
için yeniden düzenleme yaptığında tehlike ortaya çıkar, böylece artık şuna bağlı kalmayabilir
c
, a
adlı kişiyi yanlışlıkla hayır işlemini kırıyor
fark edebiliyorlar.
b/BUILD |
|
---|---|
rule( name = "b", srcs = "b.in", deps = "//d:d", ) |
|
b / b.in |
|
import d; function foo() { d.baz(); } |
|
|
|
Beyan edilen bağımlılık grafiği artık gerçek bağımlılıkları, yani geçişli olarak kapatılsa bile. derlemenin başarısız olma ihtimali yüksektir.
Bu sorun, projenin kaynaklandığı fiili bağımlılığın
2. adımda tanıtılan c
için a
, BUILD
dosyasında doğru şekilde tanımlandı.
Bağımlılık türleri
Çoğu derleme kuralının farklı türlerde dönüşümleri belirtmek için
genel bağımlılıklar: srcs
, deps
ve data
. Bunlar aşağıda açıklanmıştır. Örneğin,
Ayrıntılı bilgi için
Tüm kurallarda ortak olan özellikler.
Birçok kuralın, kurala özgü türler için
bağımlılıkları (örneğin, compiler
veya resources
). Bunlar,
Ansiklopedi oluşturun.
srcs
bağımlılık
Doğrudan kaynak dosyaları oluşturan kural veya kurallar tarafından kullanılan dosyalar.
deps
bağımlılık
Başlık dosyaları sağlayan, ayrı olarak derlenmiş modülleri işaret eden kural simgeler, kitaplıklar, veriler vb.
data
bağımlılık
Bir derleme hedefinin düzgün çalışması için bazı veri dosyaları gerekebilir. Bu veri dosyaları kaynak kod değildir: hedefin nasıl oluşturulduğunu etkilemez. Örneğin, birim testi, bir işlevin çıktısını dosya içeriğiyle karşılaştırabilir. Google Takvim widget'ını birim testini derlemek için dosyaya ihtiyacınız yoktur, ancak deneyin. Aynı durum, yürütme sırasında başlatılan araçlar için de geçerlidir.
Derleme sistemi, testleri izole bir dizinde çalıştırır. Bu dizinde yalnızca,
data
müsait. Bu nedenle, bir ikili program/kitaplık/testin çalışması için bazı dosyalar gerekiyorsa
bunları data
içinde belirtin (veya bunları içeren bir derleme kuralı). Örneğin:
# I need a config file from a directory named env:
java_binary(
name = "setenv",
...
data = [":env/default_env.txt"],
)
# I need test data from another directory
sh_test(
name = "regtest",
srcs = ["regtest.sh"],
data = [
"//data:file1.txt",
"//data:file2.txt",
...
],
)
Bu dosyalara path/to/data/file
göreli yolu kullanılarak erişilebilir. Testlerde,
testin kaynağının yollarını birleştirerek bu dosyalara
çalışma alanına bağlı yolu da belirleyebilirsiniz.
${TEST_SRCDIR}/workspace/path/to/data/file
Dizinlere başvurmak için etiketleri kullanma
BUILD
dosyalarımıza bakarken bazı data
etiketlerinin olduğunu
dizinlere başvuruda bulunur. Bu etiketler, bu örneklerde olduğu gibi /.
veya /
ile biter.
kullanmamalısınız:
Önerilmez:
data = ["//data/regression:unittest/."]
Önerilmez:
data = ["testdata/."]
Önerilmez:
data = ["testdata/"]
Bu, özellikle testler açısından kullanışlı görünüyor çünkü testin dizindeki tüm veri dosyalarını kullanır.
Ama bunu yapmamaya çalışın. Artımlı yeniden oluşturma işlemlerinin doğru şekilde yapılmasını sağlamak için (ve
bir değişiklikten sonra, derleme sistemi
bu testlerin yeniden yürütülmesinden sonra
derleme (veya test) için girilen tam dosya grubudur. Belirttiğinizde
yeniden oluşturma işlemini yalnızca dizin
(dosyaların eklenmesi veya silinmesi nedeniyle), ancak verileri algılamazsanız
tek tek dosyalarda düzenleme yapmamanız gerekir. Çünkü bu değişiklikler çevreleyen dizini etkilemeyecektir.
Dizinleri derleme sistemine girdi olarak belirtmek yerine
içerdikleri dosya grubunu açıkça veya
glob()
işlevini kullanın. (**
glob()
, yinelemeli olacaktır.)
Önerilen:
data = glob(["testdata/**"])
Maalesef dizin etiketlerinin kullanılması gereken bazı senaryolar vardır.
Örneğin, testdata
dizini, adları
etiket söz dizimine uygun olduğundan,
dosyaların açık bir şekilde numaralandırılması veya
glob()
işlevi geçersiz etiketler oluşturuyor
hatası. Bu durumda dizin etiketlerini kullanmanız gerekir, ancak
yukarıda açıklanan hatalı yeniden oluşturma riskleri.
Dizin etiketleri kullanmanız gerekiyorsa
göreli ../
yoluna sahip üst paket; bunun yerine
//data/regression:unittest/.
.
Test gibi birden fazla dosya kullanması gereken harici kurallar,
bunların tümüne bağımlı olduğunu açık bir şekilde beyan etmelidir. filegroup()
ile yapabilecekleriniz:
dosyaları birlikte BUILD
dosyasında gruplandırın:
filegroup(
name = 'my_data',
srcs = glob(['my_unittest_data/*'])
)
Daha sonra, testinizde veri bağımlılığı olarak my_data
etiketine referans verebilirsiniz.
dosya derleyin | Görünürlük |