Bazel ile program oluşturun

Sorun bildirin Kaynağı göster

Bu sayfada Bazel ile nasıl program oluşturulacağı, derleme komutu söz dizimi ve hedef kalıp söz dizimi açıklanmaktadır.

Hızlı Başlangıç

Bazel'i çalıştırmak için temel workspace dizinine veya alt dizinlerinden birine gidin ve bazel yazın. Yeni bir çalışma alanı oluşturmanız gerekiyorsa derleme bölümüne 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ın.
  • 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 sunucu işleminin dahili durumunu döküm haline getirir.
  • help: Komutlar veya dizin için yardımı yazdırır.
  • info: Bazel sunucusuyla ilgili çalışma zamanı bilgilerini gösterir.
  • fetch: Bir hedefin tüm harici bağımlılıklarını getirir.
  • mobile-install: Mobil cihazlara uygulamaları 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'i barındıran JVM için seçenekler.
  • bazel helptarget-syntax: Hedefleri belirtmek için kullanılan söz dizimini açıklar.
  • bazel help info-keys: Bilgi komutu tarafından kullanılan anahtarların listesini görüntüler.

bazel aracı, komut adı verilen birçok işlevi yerine getirir. En sık kullanılanlar bazel build ve bazel test. bazel help kullanarak çevrimiçi yardım mesajlarına göz atabilirsiniz.

Bir hedef oluşturma

Derleme işlemi başlatabilmek için çalışma alanına ihtiyacınız vardır. Çalışma alanı, uygulamanızı derlemek 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ıp 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

İlk olarak Bazel, 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. Tüm bağımlılıkları belirledikten sonra, Bazel bunları doğruluk açısından analiz eder ve derleme işlemlerini oluşturur. Son olarak Bazel, derlemenin derleyicilerini ve diğer araçlarını çalıştırır.

Derlemenin yürütme aşamasında Bazel, ilerleme mesajlarını yazdırır. İlerleme mesajları, başlangıçta geçerli derleme adımını (derleyici veya bağlayıcı gibi) ve toplam derleme işlemi sayısına göre tamamlanan sayıyı içerir. Derleme başladığında, Bazel tüm işlem grafiğini keşfettikçe genellikle toplam işlem sayısı artar ancak bu sayı birkaç saniye içinde sabitlenir.

Derlemenin sonunda Bazel, hangi hedeflerin istendiğini, başarıyla oluşturulup oluşturulmadıklarını ve oluşturulduysa çıkış dosyalarının nerede bulunabileceğini yazdırır. Derleme ç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 değişiklik olursa Bazel bazı derleme işlemlerini yeniden yürütür veya artımlı bir derleme tamamlardı.

Birden çok hedef oluşturma

Bazel, oluşturulacak hedeflerin belirlenmesi için çeşitli yöntemler sunar. Bunlar topluca hedef kalıplar olarak bilinir. Bu söz dizimi, build, test veya query gibi komutlarda kullanılır.

Etiketler, bağımsız hedefleri belirtmek için (BUILD dosyalarında bağımlılıkları bildirmek gibi) kullanılırken Bazel'in hedef kalıpları birden fazla hedef belirtir. Hedef kalıpları, hedef grupları için joker karakterler kullanılarak etiket söz diziminin genelleştirilmesidir. En basit şekilde, geçerli herhangi bir etiket aynı zamanda tam olarak bir hedeften oluşan bir kümeyi 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 bir 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 paketlerde bulunan tüm kural hedefleri.
//foo/...:all foo dizininin altındaki tüm paketlerde bulunan 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 depolar'daki hedefler dahil değildir.
//:all Çalışma alanının kökünde bir "BUILD" dosyası varsa tüm hedefler üst düzey pakette bulunur.

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

:foo //foo:foo etiketine eş değer.
bar:wiz //foo/bar:wiz etiketine eş değer.
bar/wiz Eşdeğeri:
  • foo/bar/wiz bir paketse //foo/bar/wiz:wiz
  • foo/bar bir 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, dizin sembolik bağlantıları, çalışma alanının kök dizininde oluşturulan kolaylık sembolleri gibi çıkış tabanının altındakileri işaret edenler hariç olmak üzere, yinelemeli hedef kalıpları için izlenir.

Ayrıca Bazel, aşağıdaki gibi adlandırılmış bir dosyayı içeren dizinlerdeki 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 kullanılan bir joker karakterdir ve foo dizininin altında (paket yolunun tüm kökleri için) tüm paketleri yinelemeli olarak gösterir. :all, bir paketteki tüm kurallarla eşleşen, hedefler üzerinde bir joker karakterdir. Bu ikisi, foo/...:all özelliğinde olduğu gibi birleştirilebilir. Her iki joker karakter de kullanıldığında bu karakter 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 da dahil olmak üzere eşleşen paketlerdeki her hedefle eşleşen bir joker karakterdir.

Bu, :* değerinin :all üst kümesini belirttiği anlamına gelir. Bu söz dizimi, karışık bir durum içerse de bilindik :all joker karakterinin, _deploy.jar gibi hedeflerin istenmediği tipik derlemelerde kullanılmasına izin verir.

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

Birçok Bazel komutu, bağımsız değişken olarak bir hedef kalıpları listesini kabul eder ve hepsi, - ön ek olumsuzlama operatörüne uyar. Bu işlem, bir hedef grubunu, önceki bağımsız değişkenler tarafından belirtilen kümeden çıkarmak için kullanılabilir. Bunun sıralamanın önemli olduğunu 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 gelir.

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

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

Yine de hedefleri bu şekilde çıkarmanın, çıkarılmamış hedeflerin bağımlılıkları olabileceğinden bunların oluşturulmadığını garanti etmediğini vurgulamak önemlidir. Örneğin, diğerleri arasında //foo/bar:api bağımlılığı olan bir hedef //foo:all-apis varsa ikinci hedef, ilkini 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). Bu tür test hedeflerini, Bazel'in oluşturmasını/test etmesini istiyorsanız komut satırında açık hedef kalıplarıyla belirtmeniz gerekir. Buna karşılık bazel query, otomatik olarak bu tür filtreleme yapmaz (bu durum bazel query işlevinin işlevini bozar).

Harici bağımlılıkları getirme

Varsayılan olarak Bazel, derleme sırasında harici bağımlılıkları indirir ve bunların sembolleriyle bağlantı kurar. Ancak bu, yeni harici bağımlılıkların ne zaman eklendiğini öğrenmek veya bağımlılıkları "önceden getirmek" istediğiniz için (örneğin, çevrimdışı olacağınız bir uçuştan önce) 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ğerinden bağımsız olarak her zaman geçerlilik kazanır .

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

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

  • İlk kez yapı oluşturmadan önce.
  • Yeni bir harici bağımlılık ekledikten sonra.

Çalıştırıldıktan sonra WORKSPACE dosyası değişene kadar dosyayı tekrar çalıştırmanız gerekmez.

fetch, bağımlılıkları getirmek için hedeflerin listesini alır. Örneğin bu, //foo:bar ve //bar:baz derlemesi 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

bazel fetch

Kullandığınız tüm araçlar (kitaplık jar'larından JDK'nin kendisine kadar) Workspace kökünüzün altında varsa bazel getirmeyi hiç çalıştırmanız gerekmez. Bununla birlikte, çalışma alanı dizini dışında herhangi bir uygulama kullanıyorsanız Bazel, bazel build çalıştırmadan önce otomatik olarak bazel fetch komutunu çalıştırır.

Depo önbelleği

Aynı dosyaya farklı çalışma alanlarında ihtiyaç duyulsa veya harici bir deponun tanımı değişip de indirmek için aynı dosyanın tanımı değişse bile, Bazel aynı dosyayı birkaç kez getirmekten kaçınmaya çalışır. Bunu yapmak için Bazel, varsayılan olarak ~/.cache/bazel/_bazel_$USER/cache/repos/v1/ konumunda bulunan depo önbelleğine indirilen tüm dosyaları önbelleğe alır. 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ının bulunduğundan emin olmak istiyorsa (yani indirme isteğinde belirtilen dosyanın SHA256 toplamına sahip olduğundan ve bu karmaya sahip bir dosya önbellekteyse) önbellekten bir giriş alınır. Bu nedenle, her bir harici dosya için bir karma belirlemek, güvenlik açısından iyi bir fikir olmanın yanı sıra gereksiz indirmelerden de kaçınmaya yardımcı olur.

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

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. En önemli fark, dağıtım dizininin manuel hazırlık 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 böyle bir dizinden dosya alınır. Bu işlem yalnızca dosya karması WORKSPACE bildiriminde belirtildiğinde çalışır.

Dosya adındaki koşul, doğruluk için gerekli olmasa da aday dosyaların sayısını belirtilen dizin başına bir olacak şekilde azaltır. Bu şekilde, dağıtım dosyası dizinlerini belirlemek, böyle bir dizindeki dosya sayısı artsa bile verimli kalır.

Bazel'i hava boşluklu bir ortamda çalıştırma

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

Ancak bu örtülü bağımlılıklar, WORKSPACE bağımlılıklarınızın tümünü sağlıyor olsanız bile Bazel'ı havalandırmalı bir ortamda çalıştırırken sorunlara neden olabilir. 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 bunları çevrimdışı bir yaklaşımla yayınlanan ortama aktarabilirsiniz.

Dağıtım dizinini hazırlamak için --distdir işaretini kullanın. Dolaylı bağımlılıklar her sürüm için 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 testli ortamınızın dışında oluşturmak için öncelikle doğru sürümdeki Bazel kaynak ağacını inceleyin:

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ünün dolaylı çalışma zamanı bağımlılıklarını içeren tarball'u derleyin:

bazel build @additional_distfiles//:archives.tar

Bu tarball'u, Airgapped ortamınıza kopyalanabilecek bir dizine aktarın. --distdir, dizin iç içe yerleştirme seviyesi konusunda son derece hassas olabileceğinden --strip-components işaretini unutmayın:

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

Son olarak, Airgapped ortamınızda Bazel'ı kullanırken dizine işaret eden --distdir işaretini iletin. Kolaylık olması için bu girişi bir .bazelrc girişi olarak ekleyebilirsiniz:

build --distdir=path/to/directory

Yapılandırmaları ve çapraz derleme derleme

Belirli bir derlemenin davranışını ve sonucunu belirten tüm girişler iki farklı kategoriye ayrılabilir. Bunlardan ilki, projenizin BUILD dosyalarında depolanan içsel bilgidir: derleme kuralı, özelliklerinin değerleri ve geçişli bağımlılıklarının eksiksiz kümesi. İkinci tür ise kullanıcı veya derleme aracı tarafından sağlanan harici veya çevresel verilerdir: hedef mimari seçimi, derleme ve bağlantı seçenekleri ve diğer araç zinciri yapılandırma seçenekleri. Tüm çevresel verilere yapılandırma adı verilir.

Herhangi bir derlemede birden fazla yapılandırma olabilir. 64 bit mimari için yürütülebilir //foo:bin dosyası derlediğiniz ancak iş istasyonunuzun 32 bit bir makine olduğu çapraz derlemeyi düşünün. Derleme için açık bir şekilde, 64 bit yürütülebilir dosyalar oluşturabilen bir araç zinciri kullanarak //foo:bin oluşturulması gerekecektir. Ancak derleme sistemi, derleme sırasında kullanılan çeşitli araçları da derlemelidir. Örneğin, kaynaktan derlenen ve ardından bir yardımcı olarak kullanılan araçlar. Ayrıca, bunların da iş istasyonunuzda çalışacak şekilde derlenmesi gerekir. Bu şekilde, iki yapılandırma tanımlayabiliriz: Derleme sırasında çalışan araçlar derlemek için kullanılan exec yapılandırması ve nihai olarak istediğiniz ikili dosyayı oluşturmak için kullanılan hedef yapılandırma (veya istek yapılandırması diyelim, ancak "hedef yapılandırma" sözcüğünün zaten pek çok anlamı olmasına rağmen daha sık deniyoruz).

Genellikle hem istenen derleme hedefinin (//foo:bin) hem de bir veya daha fazla yönetici aracının (örneğin bazı temel kitaplıklar) ön koşulu olan çok sayıda kitaplık bulunur. Bu tür kitaplıklar, biri yönetici yapılandırması ve diğeri hedef yapılandırma için olmak üzere iki kez derlenmelidir. Bazel, her iki varyantın da oluşturulmasını ve türetilen dosyaların müdahaleyi önlemek için ayrı tutulmasını sağlıyor. Bu tür hedefler genellikle birbirinden bağımsız olduğu için eş zamanlı olarak oluşturulabilir. Belirli bir hedefin iki kez oluşturulduğunu belirten ilerleme mesajları görürseniz muhtemelen açıklama budur.

Yürütme yapılandırması, hedef yapılandırmadan şu şekilde türetilir:

  • --host_crosstool_top belirtilmediği sürece Crosstool (--crosstool_top)'un 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çeneklerin, istek yapılandırmasında belirtilen değerleri kullanın: --compiler, --use_ijars ve --host_crosstool_top kullanılıyorsa yönetici yapılandırması için Crosstool'da bir default_toolchain aramak için --host_cpu değeri kullanılır (--compiler yok sayılır).
  • --javabase için --host_javabase değerini kullanın
  • --java_toolchain için --host_java_toolchain değerini kullanın
  • C++ kodu (-c opt) için optimize edilmiş derlemeler kullanın.
  • Hata ayıklama bilgisi oluşturmayın (--copt=-g0).
  • Yürütülebilir dosyalardan ve paylaşılan kitaplıklardan hata ayıklama bilgilerini kaldırın (--strip=always).
  • Türetilen tüm dosyaları, olası herhangi bir istek yapılandırması tarafından kullanılandan farklı özel bir konuma yerleştirin.
  • Derleme verileriyle ikili programların damgalanmasını engelle (--embed_* seçeneklerine bakın).
  • Diğer tüm değerler varsayılan ayarlarında kalır.

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

İlk olarak, sadeleştirilmiş ve optimize edilmiş ikili programlar kullanarak araçları bağlama ve yürütmeye 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 yapılan küçük değişikliklerden (bir bağlayıcı seçeneklerinin değiştirilmesi gibi) kaynaklanabilecek çok pahalı yeniden oluşturma işlemlerinden kaçınmış olursunuz.

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

Bazel projesinin birincil hedeflerinden biri, artımlı yeniden oluşturma işlemlerinin doğru şekilde yapılmasını sağlamaktır. Önceki derleme araçları, özellikle de Make temelli olanlar, artımlı derlemeleri uygularken birkaç sağlam varsayımda bulunur.

İlk olarak, dosyaların zaman damgaları tekdüze olarak artar. Tipik bir durum olsa da bu varsayımdan sapmak çok kolaydır. Bir dosyanın daha önceki bir düzeltmesiyle senkronize edildiğinde dosyanın değiştirilme süresinin kısalmasına neden olur. Oluşturma tabanlı sistemler yeniden derlenmez.

Daha genel olarak belirtmek gerekirse, Yap özelliği dosyalarda yapılan değişiklikleri algılarken, komutlarda yapılan değişiklikleri 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ın make clean kullanılarak manuel olarak silinmesi gerekir.

Ayrıca Make, bir alt işlem çıkış dosyasına yazmaya başladıktan sonra alt işlemlerinden birinin başarısız şekilde sonlandırılmasına karşı dayanıklı değildir. Mevcut Make yürütme işlemi başarısız olsa da, bir sonraki Yapma çağrısı, kısaltılan çıkış dosyasının geçerli olduğunu (çünkü girişlerinden daha yeni olduğu için) var olduğunu ve yeniden oluşturulmayacağını varsayacak. Benzer şekilde, Yapma işlemi iptal edilirse benzer bir durum ortaya çıkabilir.

Bazel, bu ve benzeri varsayımlardan kaçınır. Bazel, daha önce yapılan tüm çalışmaların yer aldığı bir veritabanı tutar ve derleme adımını, yalnızca bu derleme adımına ait giriş dosyası grubunun (ve bunların zaman damgaları) ve bu derleme adımına ait derleme komutunun veritabanındaki bir grupla tam olarak eşleştiğini ve veritabanı girişine ait çıkış dosyaları grubunun (ve bunların zaman damgalarının) diskteki zaman damgalarıyla tam olarak eşleştiğini tespit ederse atlar. Giriş dosyalarında veya çıkış dosyalarında ya da komutun kendisinde yapılacak herhangi bir değişiklik, derleme adımının yeniden yürütülmesine neden olur.

Doğru artımlı derlemelerin kullanıcılarına faydası şu gibidir: Karışıklık nedeniyle daha az zaman. (Ayrıca, gerekli veya önleme amaçlı olsun, make clean kullanımından kaynaklanan yeniden oluşturma işlemleri için daha az süre harcanır.)

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

Resmî bir şekilde, beklenen tüm çıkış dosyaları mevcut olduğunda ve bunların içerikleri doğru olduğunda, derlemenin durumunu tutarlı olarak tanımlarız. Bu dosyalar, onları oluşturmak için gereken adımlar veya kurallarla belirtilir. Bir kaynak dosyayı düzenlediğinizde, derleme durumunun tutarsız olduğu söylenir ve derleme aracını başarılı bir şekilde tamamlayana kadar bu durum tutarlı olmaz. Bu durum geçici olduğundan ve derleme aracı çalıştırıldığında tutarlılık sağlandığından bu durumu kararsız tutarsızlık olarak tanımlıyoruz.

Zararlı olan başka bir tutarsızlık türü daha vardır: kararlı tutarsızlık. Derleme stabil ve tutarsız bir duruma ulaşırsa derleme aracının tekrarlanan başarılı çağrısı, tutarlılığı geri kazanmaz: Derleme "takılıp kaldı" ve çıkışlar yanlış olarak kalır. Kararlı tutarsız durumlar, Yap (ve diğer derleme araçları) türünün make clean kullanıcılarının bulunmasının ana nedenidir. Derleme aracının bu şekilde başarısız olduğunu keşfetmek (ve sonra bunu kurtarmak) çok zaman alıcı ve çok sinir bozucu olabilir.

Kavramsal olarak, tutarlı bir derleme elde etmenin en basit yolu önceki tüm derleme çıkışlarını kaldırıp baştan başlamaktır: her derlemeyi temiz bir derleme yapmak. Bu yaklaşım, pratik olamayacak kadar zaman alıcıdır (sürüm mühendisleri için olabilir) ve bu nedenle, derleme aracının kullanışlı olabilmesi için tutarlılıktan ödün vermeden artımlı derlemeler yapabilmesi gerekir.

Doğru bir artımlı bağımlılık analizi yapmak zordur ve yukarıda açıklandığı gibi, diğer birçok derleme aracı, artımlı derlemeler sırasında kararlı tutarsız durumlardan kaçınmak konusunda başarısız olur. Buna karşın Bazel, şu garantiyi sunar: Siz hiçbir düzenleme yapmamış olan derleme aracı başarılı bir şekilde çağrıldıktan sonra, derleme tutarlı bir durumda olacaktır. (Derleme sırasında kaynak dosyalarınızı düzenlerseniz Bazel, mevcut derlemenin sonucunun tutarlılığı hakkında herhangi bir garanti vermez. Ancak sonraki derlemenin sonuçlarının tutarlılığı geri getireceğini garanti eder.)

Tüm garantilerde olduğu gibi, bazı ek bilgiler söz konusudur: Bazel ile istikrarlı bir tutarsızlık durumuna girmenin bilinen bazı yolları vardır. Artımlı bağımlılık analizinde kasıtlı olarak hata bulmaya yönelik girişimlerden kaynaklanan bu tür sorunları araştırmayı garanti etmeyiz ancak derleme aracının normal veya "makul" kullanımından kaynaklanan tüm kararlı tutarsız durumları araştırır ve düzeltmek için elimizden geleni yaparız.

Bazel'de sabit bir tutarsız durum tespit ederseniz lütfen hata bildirin.

Korumalı alanlı 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 ihtiyaç duyduğu minimum dosya grubunu içeren korumalı alanlarda spawns (kısaca işlemler) çalıştırır. Korumalı alan, şu anda CONFIG_USER_NS seçeneğinin etkinleştirildiği Linux 3.12 veya sonraki sürümlerde ve macOS 10.11 veya sonraki sürümlerde çalışır.

Sisteminiz korumalı alan kullanımını desteklemiyorsa, derlemelerin hermetik olacağı garanti edilmediği ve ana makine sistemini bilinmeyen şekillerde etkileyebileceği konusunda sizi uyarmak için bir uyarı yazdırır. Bu uyarıyı devre dışı bırakmak için --ignore_unsupported_sandboxing işaretini Bazel'e iletebilirsiniz.

Google Kubernetes Engine küme düğümleri veya Debian gibi bazı platformlarda, güvenlik endişeleri nedeniyle kullanıcı ad alanları varsayılan olarak devre dışı bırakılır. Bunu, /proc/sys/kernel/unprivileged_userns_clone dosyasına bakarak kontrol edebilirsiniz: Dosya varsa 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 üreten bir hatadır. Bu durumda, --strategy=Genrule=standalone öğesini içeren genrules ve --spawn_strategy=standalone içeren diğer kurallar için korumalı alanı devre dışı bırakmayı deneyin. Ayrıca lütfen sorun izleyicimizde bir hatayı bildirin ve hangi Linux dağıtımını kullandığınızı belirtin. Böylece, sorunu araştırıp sonraki bir sürümde düzeltebiliriz.

Yapının aşamaları

Bazel'de derleme üç farklı aşamada gerçekleşir. Kullanıcı olarak bunlar arası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ı

İlki yüklemedir. Bu sırada, başlangıç hedefleri için gereken tüm BUILD dosyaları ve bağımlılıkların geçişli olarak kapatılması, yüklenir, ayrıştırılır, değerlendirilir ve önbelleğe alınır.

Bazel sunucusu başlatıldıktan sonraki ilk derlemede, yükleme aşaması genellikle dosya sisteminden çok sayıda DERLE dosyası yüklendiğinde birkaç saniye sürer. Sonraki derlemelerde, özellikle de hiçbir BUILD dosyası değişmediyse yükleme çok hızlı bir şekilde gerçekleşir.

Bu aşamada bildirilen hatalar şunları içerir: paket bulunamadı, hedef bulunamadı, BUILD dosyasındaki sözlük ve dil bilgisi hataları ve 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ğinin belirlenmesini içerir.

Yükleme gibi, analiz de tamamen 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 yapılması gerekenleri yeniden analiz eder. Böylece, paketlerin önceki derlemeden bu yana değişmediği durumlarda artımlı derlemeler son derece hızlı olabilir.

Bu aşamada bildirilen hatalar şunları içerir: uygunsuz bağımlılıklar, kurala geçersiz girişler ve kurala özel tüm hata mesajları.

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

Yürütme aşamasında

Derlemenin üçüncü ve son aşaması yürütme adımıdır. Bu aşama, derlemedeki her adımın çıktılarının girişlerle tutarlı olmasını ve derlemeyi/bağlama vb. araçları gerektiği şekilde yeniden çalıştırmasını sağlar. Bu adımda, derleme zamanının büyük bölümünü harcar. Büyük bir derleme için birkaç saniye ile bir saat arasında değişir. Bu aşamada bildirilen hatalar şunları içerir: 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.