Bazel ile program oluşturun

Sorun bildir Kaynağı göster

Bu sayfada Bazel ile program oluşturma, komut söz dizimi oluşturma ve hedef kalıbı söz dizimi konuları ele alınmaktadır.

Hızlı Başlangıç

Bazel'ı çalıştırmak için temel çalışma alanı dizinine veya alt dizinlerinden birine gidin ve bazel yazın. Yeni bir çalışma alanı oluşturmanız gerekiyorsa derleme konusuna bakın.

bazel help
                             [Bazel release bazel version]
Usage: bazel command options ...

Mevcut komutlar

  • analyze-profile: Derleme profili verilerini analiz eder.
  • aquery: Analiz sonrası işlem grafiğinde bir sorgu yürütür.
  • build: Belirtilen hedefleri oluşturur.
  • canonicalize-flags: Bazel işaretlerini standartlaştırır.
  • clean: Çıkış dosyalarını kaldırır ve isteğe bağlı olarak sunucuyu durdurur.
  • cquery: Analiz sonrası bağımlılık grafiği sorgusu yürütür.
  • dump: Bazel sunucusu işleminin dahili durumunu boşaltır.
  • help: Komutlar veya dizin ile ilgili yardımı yazdırır.
  • info: Bazel sunucusuyla ilgili çalışma zamanı bilgilerini gösterir.
  • fetch: Hedefin tüm harici bağımlılıklarını getirir.
  • mobile-install: Uygulamaları mobil cihazlara yükler.
  • query: Bağımlılık grafiği sorgusu yürütür.
  • run: Belirtilen hedefi çalıştırır.
  • shutdown: Bazel sunucusunu durdurur.
  • test: Belirtilen test hedeflerini oluşturur ve çalıştırır.
  • version: Bazel için sürüm bilgilerini yazdırır.

Yardım alma

  • bazel help command: command ile ilgili yardım ve seçenekleri yazdırır.
  • bazel helpstartup_options: Bazel'ı barındıran JVM seçenekleri.
  • bazel helptarget-syntax: Hedefleri belirtmek için kullanılan söz dizimini açıklar.
  • bazel help info-keys: Bilgi komutu tarafından kullanılan tuşların listesini görüntüler.

bazel aracı, komut adı verilen birçok işlev gerçekleştirir. En yaygın kullanılanlar bazel build ve bazel test. Online yardım mesajlarına bazel help ifadesini kullanarak göz atabilirsiniz.

Tek bir hedef oluşturma

Derlemeye başlayabilmeniz için bir çalışma alanına ihtiyacınız vardır. Çalışma alanı, uygulamanızı oluşturmak için gereken tüm kaynak dosyaları içeren bir dizin ağacıdır. Bazel, tamamen salt okunur bir birimden derleme yapmanıza olanak tanır.

Bazel ile program oluşturmak için bazel build yazın ve ardından oluşturmak istediğiniz hedefi yazın.

bazel build //foo

//foo derleme komutunu verdikten sonra şuna benzer bir çıkış görürsünüz:

INFO: Analyzed target //foo:foo (14 packages loaded, 48 targets configured).
INFO: Found 1 target...
Target //foo:foo up-to-date:
  bazel-bin/foo/foo
INFO: Elapsed time: 9.905s, Critical Path: 3.25s
INFO: Build completed successfully, 6 total actions

Bazel önce hedefinizin bağımlılık grafiğindeki tüm paketleri yükler. Buna bildirilen bağımlılıklar, doğrudan hedefin BUILD dosyasında listelenen dosyalar ve hedefinizin bağımlılıklarının BUILD dosyalarında listelenen geçişli bağımlılıklar dahildir. Bazel tüm bağımlılıkları tanımladıktan sonra doğruluk açısından analiz eder ve oluşturma işlemlerini oluşturur. Son olarak, Bazel derleyicileri ve derlemenin diğer araçlarını çalıştırır.

Bazel, derlemenin yürütme aşamasında ilerleme mesajlarını yazdırır. İlerleme mesajları, başlatılan geçerli derleme adımını (derleyici veya bağlayıcı gibi) ve toplam derleme işlemi sayısı üzerinden tamamlanan sayıyı içerir. Bazel aksiyon grafiğinin tamamını keşfettikçe, derleme başladığında toplam eylem sayısı genellikle artar ancak sayı birkaç saniye içinde sabitlenir.

Derlemenin sonunda, Bazel hangi hedeflerin istendiğini, bunların başarıyla oluşturulup oluşturulmadığını ve olması halinde çıkış dosyalarının nerede bulunabileceğini yazdırır. Derlemeleri çalıştıran komut dosyaları bu çıkışı güvenilir bir şekilde ayrıştırabilir. Daha fazla bilgi için --show_result sayfasına bakın.

Aynı komutu tekrar yazarsanız derleme çok daha hızlı tamamlanır.

bazel build //foo
INFO: Analyzed target //foo:foo (0 packages loaded, 0 targets configured).
INFO: Found 1 target...
Target //foo:foo up-to-date:
  bazel-bin/foo/foo
INFO: Elapsed time: 0.144s, Critical Path: 0.00s
INFO: Build completed successfully, 1 total action

Bu null build. Hiçbir şey değişmediği için yeniden yüklenecek paket ve yürütülecek derleme adımı yoktur. "foo" bölümünde veya bağımlılıklarında bir şey değişirse Bazel bazı derleme işlemlerini yeniden yürütür veya ek bir derlemeyi tamamlar.

Birden çok hedef oluşturma

Bazel, oluşturulacak hedefleri belirtmek için çeşitli yöntemler sağlar. Bunlar toplu olarak hedef kalıplar olarak bilinir. Bu söz dizimi, build, test veya query gibi komutlarda kullanılır.

Etiketler, BUILD dosyalarında bağımlılık bildirmek gibi bağımsız hedefleri belirtmek için kullanılırken Bazel'in hedef kalıpları birden çok hedef belirtir. Hedef kalıpları, joker karakterler kullanılarak hedef grupları için etiket söz diziminin genelleştirilmiş halidir. En basit şekilde açıklamak gerekirse, geçerli tüm etiketler aynı zamanda, tam olarak bir tane hedef grubunu tanımlayan geçerli bir hedef kalıbıdır.

// ile başlayan tüm hedef kalıpları, mevcut çalışma alanına göre çözümlenir.

//foo/bar:wiz Yalnızca tek hedef //foo/bar:wiz.
//foo/bar //foo/bar:bar etiketine eş değer.
//foo/bar:all foo/bar paketindeki tüm kural hedefleri.
//foo/... foo dizininin altındaki tüm paketlerdeki tüm kural hedefleri.
//foo/...:all foo dizininin altındaki tüm paketlerdeki tüm kural hedefleri.
//foo/...:* foo dizininin altındaki tüm paketlerdeki tüm hedefler (kurallar ve dosyalar).
//foo/...:all-targets foo dizininin altındaki tüm paketlerdeki tüm hedefler (kurallar ve dosyalar).
//... Çalışma alanındaki paketlerdeki tüm hedefler. Buna harici depolardaki hedefler dahil değildir.
//:all Çalışma alanının kökünde bir "BUILD" dosyası varsa üst düzey paketteki tüm hedefler.

// ile başlamayan hedef kalıpları, geçerli çalışma dizinine göre çözümlenir. Bu örneklerde foo çalışma dizininin olduğu varsayılmıştır:

:foo //foo:foo etiketine eş değer.
bar:wiz //foo/bar:wiz etiketine eş değer.
bar/wiz Şuna eşdeğerdir:
  • foo/bar/wiz paketse //foo/bar/wiz:wiz
  • foo/bar paketse //foo/bar:wiz
  • Aksi durumda //foo:bar/wiz
bar:all //foo/bar:all etiketine eş değer.
:all //foo:all etiketine eş değer.
...:all //foo/...:all etiketine eş değer.
... //foo/...:all etiketine eş değer.
bar/...:all //foo/bar/...:all etiketine eş değer.

Varsayılan olarak, çalışma alanının kök dizininde oluşturulan kolaylık sembolleri gibi çıktı tabanının altına işaret edenler hariç, yinelemeli hedef kalıpları için dizin simgesel bağlantıları varsayılan olarak izlenir.

Ayrıca Bazel, aşağıdaki gibi adlandırılmış bir dosyayı içeren herhangi bir dizindeki yinelemeli hedef kalıplarını değerlendirirken sembolik bağlantıları izlemez: DONT_FOLLOW_SYMLINKS_WHEN_TRAVERSING_THIS_DIRECTORY_VIA_A_RECURSIVE_TARGET_PATTERN

foo/..., paketler üzerinde bir joker karakterdir ve foo dizininin (paket yolunun tüm kökleri için) altındaki tüm paketleri yinelemeli olarak belirtir. :all, hedefler üzerinde bir joker karakterdir ve paket içindeki tüm kurallarla eşleşir. Bu ikisi, foo/...:all örneğinde olduğu gibi birleştirilebilir ve her iki joker karakter de kullanıldığında foo/... olarak kısaltılabilir.

Ayrıca :* (veya :all-targets), java_binary kurallarıyla ilişkili _deploy.jar dosyaları gibi normalde herhangi bir kural tarafından oluşturulmayan dosyalar dahil olmak üzere eşleşen paketlerdeki her hedef ile eşleşen bir joker karakterdir.

Bu, :* değerinin :all üst kümesini ifade ettiği anlamına gelir. Ancak bu söz dizimi, kafa karıştırıcı olsa da _deploy.jar gibi hedeflerin oluşturulmasının istenmediği tipik derlemelerde, bilinen :all joker karakterinin kullanılmasına izin verir.

Ayrıca Bazel, etiket söz diziminin gerektirdiği iki nokta yerine eğik çizgi kullanılmasına da olanak tanır. Bu, Bash dosya adı genişletmesi kullanılırken çoğu zaman kolay olur. Örneğin foo/bar/wiz, //foo/bar:wiz (foo/bar paketi varsa) veya //foo:bar/wiz (foo paketi varsa) ile eş değerdir.

Çoğu Bazel komutu, hedef kalıpları listesini bağımsız değişken olarak kabul eder ve hepsinde, ön ek olumsuzlama operatörü - geçerli olur. Bu özellik, bir hedef grubunu, önceki bağımsız değişkenler tarafından belirtilen kümeden çıkarmak için kullanılabilir. Bunun sıra önemli olduğu anlamına geldiğini unutmayın. Örneğin,

bazel build foo/... bar/...

"foo altındaki tüm hedefleri ve bar altındaki tüm hedefleri oluştur" anlamına gelirken,

bazel build -- foo/... -foo/bar/...

"foo/bar altındakiler haricinde, foo altındaki tüm hedefleri oluştur" anlamına gelir. (-- bağımsız değişkeni, - ile başlayan sonraki bağımsız değişkenlerin ek seçenekler olarak yorumlanmasını önlemek için gereklidir.)

Hedefleri bu şekilde çıkarmanın, çıkarılmayan hedeflerin bağımlılıkları olabileceğinden, hedeflerin oluşturulmadığını garanti etmeyeceğini belirtmek gerekir. Örneğin, diğerlerinin yanı sıra //foo/bar:api temelli bir //foo:all-apis hedefi varsa ikincisi //foo/bar:api katmanını oluşturmanın bir parçası olarak oluşturulur.

tags = ["manual"] içeren hedefler, bazel build ve bazel test gibi komutlarda belirtildiğinde joker karakter hedef kalıplarına (..., :*, :all vb.) dahil edilmez (ancak negatif joker karakter hedef kalıplarına dahil edilirler, yani çıkarılırlar). Bazel'ın oluşturmasını/test etmesini istiyorsanız bu test hedeflerini komut satırında açık hedef kalıplarıyla belirtmeniz gerekir. Buna karşılık bazel query, bu tür filtrelemeleri otomatik olarak gerçekleştirmez (bu, bazel query özelliğinin amacını bozar).

Dış bağımlılıkları getirme

Varsayılan olarak Bazel, oluşturma sırasında harici bağımlılıkları indirir ve sembolik bağlantılar oluşturur. Ancak bu durum, yeni dış bağımlılıkların ne zaman eklendiğini öğrenmek veya bağımlılıkları "önceden getirmek" (örneğin, çevrimdışı olacağınız bir uçuştan önce) istediğiniz için istenmeyen bir durum olabilir. Derlemeler sırasında yeni bağımlılıkların eklenmesini önlemek istiyorsanız --fetch=false işaretini belirtebilirsiniz. Bu işaretin yalnızca yerel dosya sistemindeki bir dizine işaret etmeyen depo kuralları için geçerli olduğunu unutmayın. Örneğin local_repository, new_local_repository ve Android SDK ile NDK deposu kurallarında yapılan değişiklikler --fetch değeri ne olursa olsun her zaman geçerli olur .

Derlemeler sırasında getirme işlemine izin vermezseniz ve Bazel yeni dış bağımlılıklar bulursa derlemeniz başarısız olur.

bazel fetch komutunu çalıştırarak bağımlılıkları manuel olarak getirebilirsiniz. Derleme sırasında getirmeyi izin vermezseniz bazel fetch komutunu çalıştırmanız gerekir:

  • İlk kez derleme yapmadan önce.
  • Yeni bir dış bağımlılık ekledikten sonra.

Çalıştırıldığında, WORKSPACE dosyası değişinceye kadar tekrar çalıştırmanız gerekmez.

fetch, bağımlılıkları getirilecek hedeflerin listesini alır. Örneğin bu işlem, //foo:bar ve //bar:baz derlemek için gereken bağımlılıkları getirir:

bazel fetch //foo:bar //bar:baz

Bir çalışma alanının tüm harici bağımlılıklarını getirmek için şu komutu çalıştırın:

bazel fetch //...

Bazel 7.1 veya sonraki sürümlerde, Bzlmod'u etkinleştirdiyseniz tüm harici bağımlılıkları

bazel fetch

Çalışma alanı kökü altında kullandığınız tüm araçlara (kitaplık jar'larından JDK'nın kendisine kadar) sahipseniz bazel getirme işlemini çalıştırmanız gerekmez. Ancak, çalışma alanı dizininin dışında bir şey kullanıyorsanız Bazel, bazel build çalıştırmadan önce otomatik olarak bazel fetch çalıştırır.

Depo önbelleği

Bazel, farklı çalışma alanlarında aynı dosyanın bulunması veya harici bir deponun tanımı değişmiş olmasına rağmen aynı dosyanın indirilmesi gerektiğinde bile aynı dosyayı birkaç kez getirmekten kaçınmaya çalışır. Bazel bunu yapmak için kod deposu önbelleğinde indirilen tüm dosyaları önbelleğe alır. Bu dosyalar varsayılan olarak ~/.cache/bazel/_bazel_$USER/cache/repos/v1/ konumunda bulunur. Konum, --repository_cache seçeneği ile değiştirilebilir. Önbellek, tüm çalışma alanları ve Bazel'in yüklü sürümleri arasında paylaşılır. Bazel doğru dosyanın bir kopyasına sahip olduğundan eminse, yani indirme isteğinde belirtilen dosyanın SHA256 toplamı varsa ve bu karmaya sahip bir dosya önbellekte yer alıyorsa önbellekten bir giriş alınır. Dolayısıyla, her harici dosya için bir karma değeri belirlemek, güvenlik açısından iyi bir fikir olmanın yanı sıra gereksiz indirmelerin önlenmesine de yardımcı olur.

Her önbellek isabetinde, önbellekteki dosyanın değiştirilme zamanı güncellenir. Bu şekilde, örneğin önbelleği manuel olarak temizlemek için dosyanın önbellek dizinindeki son kullanımı kolayca belirlenebilir. Önbellek, artık yukarı akışta kullanılmayan bir dosyanın kopyasını içerebileceğinden hiçbir zaman otomatik olarak temizlenmez.

Dağıtım dosyası dizinleri

Dağıtım dizini, gereksiz indirmeleri önlemek için kullanılan başka bir Bazel mekanizmasıdır. Bazel, depo önbelleğinden önce dağıtım dizinlerinde arama yapar. Temel fark, dağıtım dizininin manuel olarak hazırlanmasını gerektirmesidir.

--distdir=/path/to-directory seçeneğini kullanarak, dosyaları getirmek yerine aramak için ek salt okunur dizinler belirtebilirsiniz. Dosya adı, URL'nin temel adına eşitse ve ayrıca dosyanın karma değeri indirme isteğinde belirtilene eşitse dosya bu tür bir dizinden alınır. Bu işlem yalnızca WORKSPACE bildiriminde dosya karması belirtilmişse çalışır.

Dosya adındaki koşul doğruluk için gerekli olmasa da, aday dosya sayısını belirtilen dizin başına bir adet olacak şekilde azaltır. Bu şekilde, böyle bir dizindeki dosyaların sayısı büyüse bile, dağıtım dosyası dizinlerinin belirtilmesi verimli olmaya devam eder.

Bazel'ı havadan uzakta çalıştırma

Bazel'ın ikili program boyutunu küçük tutmak için Bazel'ın örtülü bağımlılıkları ilk kez çalışırken ağ üzerinden getirilir. Bu dolaylı bağımlılıklar, herkes için gerekli olmayabilecek araç zincirleri ve kurallar içerir. Örneğin, Android araçları yalnızca Android projeleri oluşturulurken gruptan çıkarılır ve getirilir.

Ancak bu örtülü bağımlılıklar, WORKSPACE bağımlılıklarınızın tümünü sağlamış olsanız bile, Bazel'ı hava boşluğuna sahip bir ortamda çalıştırırken sorunlara yol açabilir. Bu sorunu çözmek için ağ erişimi olan bir makinede bu bağımlılıkları içeren bir dağıtım dizini hazırlayabilir ve ardından çevrimdışı yaklaşımla bunları hava erişimli ortama aktarabilirsiniz.

Dağıtım dizinini hazırlamak için --distdir işaretini kullanın. Örtülü bağımlılıklar her sürümde farklı olabileceğinden bu işlemi her yeni Bazel ikili sürümü için bir kez yapmanız gerekir.

Bu bağımlılıkları hava geçişli ortamınız dışında oluşturmak için önce doğru sürümdeki Bazel kaynak ağacına bakın:

git clone https://github.com/bazelbuild/bazel "$BAZEL_DIR"
cd "$BAZEL_DIR"
git checkout "$BAZEL_VERSION"

Ardından, söz konusu Bazel sürümü için örtülü çalışma zamanı bağımlılıklarını içeren tarball'u derleyin:

bazel build @additional_distfiles//:archives.tar

Bu tarball'u, hava boşluklu ortamınıza kopyalanabilen bir dizine dışa aktarın. --distdir, dizin iç içe yerleştirme düzeyi konusunda oldukça titiz olabileceğinden --strip-components işaretine dikkat edin:

tar xvf bazel-bin/external/additional_distfiles/archives.tar \
  -C "$NEW_DIRECTORY" --strip-components=3

Son olarak, hava boşluklu ortamınızda Bazel'i kullanırken, dizini işaret eden --distdir işaretini iletin. Kolaylık olması için bunu .bazelrc girişi olarak ekleyebilirsiniz:

build --distdir=path/to/directory

Yapılandırmalar ve çapraz derleme oluşturma

Belirli bir derlemenin davranışını ve sonucunu belirten tüm girişler iki farklı kategoriye ayrılabilir. Birinci tür, projenizin BUILD dosyalarında depolanan içsel bilgilerdir: derleme kuralı, özelliklerinin değerleri ve geçişli bağımlılıklarının tamamı. İkinci tür ise kullanıcı veya derleme aracı tarafından sağlanan harici ya da çevresel verilerdir: hedef mimari, derleme ve bağlantı seçenekleri ve diğer araç zinciri yapılandırma seçenekleri. Tüm çevresel verileri yapılandırma olarak adlandırırız.

Herhangi bir derlemede birden fazla yapılandırma olabilir. 64 bit mimari için yürütülebilir bir //foo:bin dosyası oluşturduğunuz ancak iş istasyonunuzun 32 bit makine olduğu çapraz derlemeyi düşünün. Derlemenin 64 bit yürütülebilir dosyalar oluşturabildiği bir araç zinciri kullanılarak //foo:bin derlenmesi gerektiği açıkça bellidir. Ancak derleme sisteminin, derlemenin kendisi sırasında kullanılan çeşitli araçları da (örneğin, kaynaktan oluşturulan ve daha sonra genrule'da kullanılan araçlar) derlemesi gerekir ve bu araçlar da iş istasyonunuzda çalışacak şekilde oluşturulmalıdır. Böylece iki yapılandırma tanımlayabiliriz: Derleme sırasında çalışan araçlar oluşturmak için kullanılan exec yapılandırması ve sonuç olarak istediğiniz ikili programı oluşturmak için kullanılan hedef yapılandırma (veya istek yapılandırması diyoruz ancak bu kelimenin zaten birçok anlamı olsa da "hedef yapılandırma" diyoruz).

Genellikle hem istenen derleme hedefinin (//foo:bin) hem de bir veya daha fazla yürütme aracının (örneğin, bazı temel kitaplıklar) ön koşulu olan birçok kitaplık vardır. Bu tür kitaplıkların, biri yürütme yapılandırması, diğeri hedef yapılandırma için olmak üzere iki kez oluşturulması gerekir. Bazel, her iki varyantın derlendiğinden ve türetilen dosyaların parazitten kaçınmak için ayrı tutulmasına özen gösterir. Bu tür hedefler, birbirinden bağımsız olduğu için genellikle eşzamanlı olarak oluşturulabilir. Belirli bir hedefin iki kez oluşturulduğunu belirten ilerleme mesajları görüyorsanız büyük olasılıkla açıklama budur.

Yürütme yapılandırması, aşağıdaki gibi hedef yapılandırmadan türetilir:

  • --host_crosstool_top belirtilmediği sürece, Crosstool (--crosstool_top) sürümünün istek yapılandırmasında belirtilenle aynı sürümünü kullanın.
  • --cpu için --host_cpu değerini kullanın (varsayılan: k8).
  • Bu seçenekler için, istek yapılandırmasında belirtilenlerle aynı değerleri kullanın: --compiler ve --use_ijars. --host_crosstool_top kullanılırsa exec yapılandırması için Crosstool öğesinde bir default_toolchain aramak için --host_cpu değeri kullanılır (--compiler göz ardı edilir).
  • --javabase için --host_javabase değerini kullanın
  • --java_toolchain için --host_java_toolchain değerini kullanın
  • C++ kodu için optimize edilmiş derlemeler kullanın (-c opt).
  • Hata ayıklama bilgisi oluşturma (--copt=-g0).
  • Yürütülebilir dosyalardan ve paylaşılan kitaplıklardan hata ayıklama bilgilerini kaldır (--strip=always).
  • Türetilen tüm dosyaları, olası istek yapılandırması tarafından kullanılandan farklı, özel bir konuma yerleştirin.
  • Derleme verileriyle, ikili programların damgalanmasını engelleyin (--embed_* seçeneklerine bakın).
  • Diğer tüm değerler varsayılan değerlerinde kalır.

İstek yapılandırmasından ayrı bir yönetici yapılandırması seçmenin tercih edilmesinin birçok nedeni olabilir. En önemlisi:

İlk olarak, sadeleştirilmiş ve optimize edilmiş ikili programlar kullanarak araçları birbirine bağlamak ve çalıştırmak için harcanan süreyi, araçların kapladığı disk alanını ve dağıtılmış derlemelerde ağ G/Ç süresini azaltırsınız.

İkinci olarak, tüm derlemelerdeki yönetici ve istek yapılandırmalarını ayrıştırarak daha önce açıklandığı gibi istek yapılandırmasında küçük değişikliklerden (bağlayıcı seçeneklerinin değiştirilmesi gibi) kaynaklanacak çok pahalı yeniden derlemelerden kaçınmış olursunuz.

Artımlı yeniden oluşturma işlemlerini düzeltin

Bazel projesinin birincil hedeflerinden biri, doğru artımlı yeniden oluşturma işlemlerinin yapılmasını sağlamaktır. Önceki derleme araçları, özellikle de Make'e dayalı olanlar, artımlı derlemelerin uygulanması sırasında bazı geçersiz varsayımlarda bulunuyor.

İlk olarak, dosyaların zaman damgaları tekdüze şekilde artar. Bu, tipik bir durum olsa da bu varsayıma saptırmak çok kolaydır; bir dosyanın daha önceki bir düzeltmesine senkronize etmek, dosyada değişiklik yapma süresinin azalmasına neden olur; Make tabanlı sistemler yeniden oluşturulmaz.

Daha genel olarak ifade etmek gerekirse, Yap işlevi dosyalarda değişiklik algılarken komut değişikliklerini algılamaz. Belirli bir derleme adımında derleyiciye iletilen seçenekleri değiştirirseniz Make, derleyiciyi yeniden çalıştırmaz ve önceki derlemenin geçersiz çıkışlarını make clean kullanarak manuel olarak silmek gerekir.

Ayrıca Make, alt işlemlerden birinin çıkış dosyasına yazmaya başladıktan sonra başarısız bir şekilde sonlandırılmasına karşı dayanıklı değildir. Make'nin mevcut yürütmesi başarısız olsa da sonraki Make çağrısı, kısaltılmış çıkış dosyasının geçerli olduğunu (çünkü dosyanın girişlerinden daha yeni olması nedeniyle) kabul edilmez ve yeniden oluşturulmaz. Benzer şekilde, Yapma süreci durdurulursa benzer bir durum ortaya çıkabilir.

Bazel bu varsayımlardan ve başka varsayımlardan kaçınmaktadır. Bazel daha önce yapılan tüm işlerin yer aldığı bir veritabanı tutar ve yalnızca bu derleme adımındaki giriş dosyaları grubunun (ve bunların zaman damgalarının) ve bu derleme adımına ait derleme komutunun veritabanındaki bir öğeyle tam olarak eşleştiğini ve veritabanı girişine ait çıkış dosyaları grubunun (ve bunların zaman damgalarının) diskteki dosyalarla tam olarak eşleştiğini tespit etmesi durumunda derleme adımını atlar. Giriş dosyaları, çıkış dosyaları veya komutun kendisinde yapılan herhangi bir değişiklik, derleme adımının yeniden yürütülmesine neden olur.

Doğru artımlı derlemelerin kullanıcılara avantajı, karışıklık nedeniyle daha az zaman kaybıdır. (Ayrıca, make clean kullanımından kaynaklanan yeniden derlemeler için beklemeye harcanan süre azalır. Bu süre, gerekli veya önlem amaçlıdır.)

Tutarlılık ve artımlı derlemeler oluşturun

Resmi olarak, beklenen tüm çıkış dosyaları mevcut olduğunda ve bu dosyaları oluşturmak için gereken adımlar ya da kurallarda belirtilen içerikler doğru olduğunda derlemenin durumunu tutarlı olarak tanımlarız. Bir kaynak dosyayı düzenlediğinizde, derlemenin durumunun tutarsız olduğu söylenir ve başarıyla tamamlama için derleme aracını bir sonraki çalıştırmanıza kadar tutarsız kalır. Bu yalnızca geçici olduğu ve derleme aracının çalıştırılmasıyla tutarlılık sağlandığı için bu durumu kararsız tutarsızlık olarak tanımlıyoruz.

Tehlikeli başka bir tutarsızlık türü daha vardır: istikrarlı tutarsızlık. Derleme, tutarlı ve tutarsız bir duruma ulaşırsa yapı aracının başarılı bir şekilde tekrar çağrılması tutarlılığı geri kazandırmaz: Derleme "sıkışmıştır" ve çıktılar yanlış kalır. Kararlı tutarsız durumlar, Make (ve diğer derleme araçları) kullanıcılarının make clean yazmasının ana nedenidir. Derleme aracının bu şekilde başarısız olduğunu (ve daha sonra aracıdan kurtarmak) keşfetmek zaman alıcı ve çok sinir bozucu olabilir.

Kavramsal olarak tutarlı bir derleme elde etmenin en basit yolu, önceki tüm derleme çıktılarını bir kenara bırakıp yeniden başlamaktır: her derlemeyi temiz bir yapıya kavuşturun. Bu yaklaşım, pratik olamayacak kadar zaman alıcıdır (belki de sürüm mühendisleri için dışında) ve bu nedenle derleme aracının yararlı olması için tutarlılıktan ödün vermeden artımlı derlemeler gerçekleştirebilmesi gerekir.

Doğru artımlı bağımlılık analizi zordur ve yukarıda açıklandığı gibi diğer birçok derleme aracı, ek derlemeler sırasında istikrarlı tutarsız durumlardan kaçınarak yetersiz bir iş çıkarır. Öte yandan, Bazel şu garantiyi sunar: Oluşturma aracı hiçbir düzenleme yapmadan başarılı bir şekilde çağrıldıktan sonra, derleme tutarlı bir durumda olacaktır. (Bir derleme sırasında kaynak dosyalarınızı düzenlerseniz Bazel, geçerli derlemenin sonucunun tutarlılığı konusunda garanti vermez. Ancak bir sonraki derlemenin sonuçlarının tutarlılığı geri getirmesini garanti eder.)

Tüm garantilerde olduğu gibi, bazı küçük notlar var: Bazel'de tutarlı ve tutarsız bir duruma geçmenin bilinen bazı yolları vardır. Artımlı bağımlılık analizindeki hataları bulmaya yönelik kasıtlı girişimlerden kaynaklanan bu tür sorunları araştıracağımızı garanti edemeyiz. Ancak, geliştirme aracının normal veya "makul" kullanımından kaynaklanan tüm sabit tutarsız durumları araştırıp düzeltmek için elimizden geleni yapacağız.

Bazel'da tutarlı ve tutarsız bir durum tespit ederseniz lütfen hata bildiriminde bulunun.

Korumalı alana alınmış yürütme

Bazel, işlemlerin hermetik ve doğru şekilde çalışmasını garanti etmek için korumalı alanları kullanır. Bazel, yalnızca aracın işini yapmak için gereken minimum dosya grubunu içeren korumalı alanlarda spawns (daha genel bir ifadeyle eylemler) çalıştırır. Korumalı alan oluşturma şu anda CONFIG_USER_NS seçeneği etkinleştirilmiş Linux 3.12 veya daha yeni sürümlerde ve macOS 10.11 veya sonraki sürümlerde çalışmaktadır.

Sisteminiz korumalı alana almayı desteklemiyorsa, yapıların hermetik olduğu garanti edilmediği ve ana makine sistemini bilinmeyen şekillerde etkileyebileceği konusunda sizi uyarmak için Bazel bir uyarı yazdırır. Bu uyarıyı devre dışı bırakmak için --ignore_unsupported_sandboxing işaretini Bazel'a geçirebilirsiniz.

Google Kubernetes Engine küme düğümleri veya Debian gibi bazı platformlarda, güvenlik nedeniyle kullanıcı ad alanları varsayılan olarak devre dışı bırakılır. Bu, /proc/sys/kernel/unprivileged_userns_clone dosyasına bakılarak kontrol edilebilir: Dosya mevcutsa ve 0 içeriyorsa kullanıcı ad alanları sudo sysctl kernel.unprivileged_userns_clone=1 ile etkinleştirilebilir.

Bazı durumlarda Bazel korumalı alanı, sistem kurulumu nedeniyle kuralları yürütemez. Bu belirti genellikle namespace-sandbox.c:633: execvp(argv[0], argv): No such file or directory benzeri bir mesaj veren bir hatadır. Bu durumda, --strategy=Genrule=standalone içeren genruler ve --spawn_strategy=standalone içeren diğer kurallar için korumalı alanı devre dışı bırakmayı deneyin. Ayrıca, sorun izleyicimizdeki bir hatayı ve hangi Linux dağıtımını kullandığınızı belirtin. Böylece, bunu araştırıp sonraki bir sürümde düzeltme yapabiliriz.

Derleme aşamaları

Bazel'de bir derleme üç farklı aşamada gerçekleşir. Kullanıcı olarak, aralarındaki farkın anlaşılması, bir derlemeyi kontrol eden seçenekler hakkında bilgi sağlar (aşağıya bakın).

Yükleme aşaması

Birincisi, başlangıçtaki hedefler için gerekli tüm DERLEME dosyalarının ve bunların bağımlılıkların geçişli olarak kapatılmasının yüklendiği, ayrıştırıldığı, değerlendirildiği ve önbelleğe alındığı yükleme işlemidir.

Bazel sunucusu başlatıldıktan sonraki ilk derleme için yükleme aşaması genellikle dosya sisteminden yüklenen BUILD dosyası kadar saniye sürer. Sonraki derlemelerde, özellikle de hiçbir DERLEME dosyası değişmemişse yükleme çok hızlı bir şekilde gerçekleşir.

Bu aşamada bildirilen hatalar şunlardır: paket bulunamadı, hedef bulunamadı, BUILD dosyasındaki sözlük ve dil bilgisi hataları ile değerlendirme hataları.

Analiz aşaması

İkinci aşama olan analiz; her derleme kuralının anlamsal analizini ve doğrulanmasını, bir derleme bağımlılık grafiğinin oluşturulmasını ve derlemenin her adımında tam olarak hangi işin yapılması gerektiğini belirlemeyi içerir.

Yükleme işlemi gibi, analiz de bütünüyle hesaplandığında birkaç saniye sürer. Ancak Bazel, bağımlılık grafiğini bir derlemeden diğerine önbelleğe alır ve yalnızca gerekenleri yeniden analiz eder. Böylece, paketlerin önceki derlemeden bu yana değişmediği durumlarda artımlı derlemeler son derece hızlı bir şekilde oluşturulabilir.

Bu aşamada bildirilen hatalar şunlardır: uygunsuz bağımlılıklar, kural için geçersiz girişler ve kurala özgü tüm hata mesajları.

Yükleme ve analiz aşamaları hızlıdır, çünkü Bazel bu aşamada gereksiz dosya G/Ç'sinden kaçınır ve yapılacak işi belirlemek için yalnızca DERLEME dosyalarını okur. Bu tasarım gereğidir ve Bazel, yükleme aşamasının üstünde uygulanan Bazel'ın query komutu gibi analiz araçları için iyi bir temel oluşturur.

Yürütme aşaması

Derlemenin üçüncü ve son aşaması yürütme aşamasıdır. Bu aşama, derlemedeki her adımın çıktılarının girişlerle tutarlı olmasını sağlar ve gerektiğinde derleme/bağlantı oluşturma/vb. araçları tekrar çalıştırır. Büyük bir derlemede birkaç saniyeden bir saate kadar, derlemenin zamanının çoğunu bu adımda harcar. Bu aşamada rapor edilen hatalar şunlardır: eksik kaynak dosyalar, bazı derleme işlemleri tarafından yürütülen araçtaki hatalar veya bir aracın beklenen çıkış kümesini üretememesi.