Bağımlılıklar

. Sorun bildirin Kaynağı göster Gece · 7,3 · 7,2 · 7,1 · 7,0 · 6,5

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();
}
      
a, b ve c'yi birleştiren oklarla bildirilmiş bağımlılık grafiği
Beyan bağımlılık grafiği
Beyan edilen bağımlılıkla eşleşen gerçek bağımlılık grafiği
                  a, b ve c'yi birleştiren okların olduğu grafik
Gerçek bağımlılık grafiği

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();
      
 
a, b ve c'yi birleştiren oklarla bildirilmiş bağımlılık grafiği
Beyan bağımlılık grafiği
a, b ve c'yi bağlayan okların yer aldığı gerçek bağımlılık grafiği. 
                  ok artık A'dan C'ye de bağlanıyor. Bu,
                  bildirilen bağımlılık grafiği
Gerçek bağımlılık grafiği

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();
      }
      
a ile b'yi birleştiren okların olduğu bildirilen bağımlılık grafiği.
                  b artık c'ye bağlanmaz, bu da a'nın c ile bağlantısını koparır
Beyan bağımlılık grafiği
b ve c’ye bağlantıyı gösteren gerçek bağımlılık grafiği
                  ancak b artık c'ye bağlanmaz
Gerçek bağımlılık grafiği

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