Bazel ile program oluşturun

Sorun bildir Kaynağı göster

Bu sayfada, Bazel ile nasıl program oluşturulacağı, komut söz diziminin ve hedef kalıbı söz diziminin nasıl oluşturulacağı açıklanmaktadır.

Hızlı Başlangıç

Bazel'ı çalıştırmak için temel çalışma alanı dizinine veya alt dizinlerinden herhangi birine gidip 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 ...

Kullanılabilir komutlar

  • analyze-profile: Derleme profili verilerini analiz eder.
  • aquery: Analiz sonrası eylem 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 atar.
  • help: Komutlar veya dizin için yardımı yazdırır.
  • info: Bazel sunucusu hakkındaki ç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 için yardım ve seçenekleri yazdırır.
  • bazel helpstartup_options: Bazel'ı barındıran JVM seçenekleri.
  • bazel helptarget-syntax: Hedefleri belirlemeye ilişkin 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şlev gerçekleştirir. En yaygın kullanılanlar bazel build ve bazel test. bazel help kullanarak çevrimiçi yardım mesajlarına 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 hedef yazın.

bazel build //foo

//foo derleme komutunu verdikten sonra aşağıdakine 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 ilk olarak 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.

Derlemenin yürütme aşamasında Bazel, 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. Geliştirme başladığında, Bazel tüm eylem grafiğini keşfettikçe genellikle toplam işlem sayısı artar, ancak sayı birkaç saniye içinde sabitlenir.

Derlemenin sonunda Bazel, hangi hedeflerin istendiğini, başarıyla oluşturulup oluşturulmadığını ve olması durumunda çı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ını inceleyin.

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

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 artımlı bir derlemeyi tamamlar.

Birden çok hedef oluşturma

Bazel, oluşturulacak hedefleri belirtmek için çeşitli yöntemler sunar. 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 fazla hedef belirtir. Hedef kalıpları, hedef grupları için joker karakterler kullanılarak yapılan etiket söz diziminin genelleştirilmesidir. En basit örnekte, herhangi bir geçerli etiket aynı zamanda bir hedef grubunu tam olarak tanımlayan geçerli bir hedef kalıbıdır.

// ile başlayan tüm hedef kalıpları, geçerli ç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).
//... Ana depodaki paketlerdeki tüm kural hedefleri. Harici depolardaki hedefleri içermez.
//:all Çalışma alanının kök dizininde bir "BUILD" dosyası varsa üst düzey paketteki tüm kural hedefleri.

// ile başlamayan hedef kalıpları, geçerli çalışma dizinine göre çözümlenir. Bu örneklerde foo çalışma dizininin kullanıldığı 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 paketse //foo/bar/wiz:wiz
  • foo/bar paketse //foo/bar:wiz
  • aksi takdirde //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.

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

Ayrıca Bazel, aşağıdaki gibi adlandırılmış bir dosya 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/..., foo dizininin (paket yolunun tüm kökleri için) altındaki tüm paketleri yinelemeli olarak gösteren, paketler üzerinde bir joker karakterdir. :all, hedefler üzerinde bulunan ve paket içindeki tüm kurallarla eşleşen bir joker karakterdir. 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şkilendirilmiş _deploy.jar dosyaları gibi normalde herhangi bir kural tarafından oluşturulmayan dosyalar dahil olmak üzere eşleşen paketlerdeki her hedefle 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 çizginin kullanılmasına izin verir. Bu durum genellikle Bash dosya adı genişletmesi kullanılırken kolaylık sağlar. Ö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 hedef kalıpları listesini kabul eder ve hepsinde - ön ek olumsuzlama operatörü kullanılır. Bu işlem, bir grup hedefi, önceki bağımsız değişkenlerde belirtilen kümeden çıkarmak için kullanılabilir. Bunun sıra önemli olduğu anlamına gelir. Ö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ında olanlar hariç 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.)foo

Hedeflerin bu şekilde çıkarılması, çıkarılmayan hedeflerin bağımlılıkları olabileceğinden, söz konusu hedeflerin oluşturulmadığını garanti etmez. Örneğin, diğerlerinin yanı sıra //foo/bar:api temelli bir hedef //foo:all-apis varsa bu hedef //foo:all-apis 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 edilir, yani çıkarılır). Bazel'ın bunları oluşturmasını/test etmesini istiyorsanız komut satırında açık hedef kalıplarıyla bu tür test hedeflerini belirtmeniz gerekir. Buna karşın, bazel query bu tür bir filtrelemeyi otomatik olarak gerçekleştirmez (bu, bazel query işlevinin amacını bozar).

Harici 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 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 bu 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 getirme işlemine izin vermezseniz bazel fetch öğesini çalıştırmanız gerekir:

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

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

fetch, bağımlılıkları getirilecek hedeflerin listesini alır. Örneğin, //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 veya sonraki bir sürümde, Bzlmod'u etkinleştirdiyseniz tüm harici bağımlılıkları

bazel fetch

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

Depo önbelleği

Farklı çalışma alanlarında aynı dosyanın bulunması ya da harici bir deponun tanımı değişmiş ancak yine de indirilebilmesi için aynı dosyanın tanımı değişmiş olsa bile, Bazel aynı dosyayı birkaç kez getirmekten kaçınmaya çalışır. Bunu yapmak için Bazel, kod deposu önbelleğinden 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'ın yüklü sürümleri arasında paylaşılır. Bazel doğru dosyanın bir kopyasına sahip olduğundan emin olursa, yani indirme isteğinde belirtilen dosyanın SHA256 toplamına sahipse ve bu karmaya sahip bir dosya önbellekte yer alıyorsa önbellekten bir giriş alınır. Bu nedenle, her bir 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ştirme 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, artık yukarı yönlü olmayan bir dosyanın bir kopyasını içerebileceğinden hiçbir zaman otomatik olarak temizlenmez.

[Kullanımdan kaldırıldı] Dağıtım dosyaları dizinleri

Kullanımdan kaldırıldı: Çevrimdışı derlemeyi gerçekleştirmek için depo önbelleğinin kullanılması tercih edilir.

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 hazırlama 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 ve ek olarak dosyanın karması, indirme isteğinde belirtilenle eşitse bu tür bir dizinden dosya alınır. Bu özellik yalnızca dosya karması WORKSPACE bildiriminde belirtildiğinde çalışır.

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

Bazel'ı havasız ortamda çalıştırma

Bazel'in ikili programın boyutunu küçük tutmak için Bazel'in ö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ı gruptan çıkarılır ve yalnızca Android projeleri oluşturulurken getirilir.

Ancak bu örtülü bağımlılıklar, tüm dış bağımlılıklarınızı temin etmiş olsanız bile Bazel'i 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 depo önbelleği (Bazel 7 veya sonraki sürümlerle) ya da dağıtım dizini (7'den önce Bazel ile) hazırlayabilir ve daha sonra, çevrimdışı yaklaşımla bunları Airglise kullanan ortama aktarabilirsiniz.

Depo önbelleği (Bazel 7 veya sonraki sürümleri ile)

Depo önbelleğini hazırlamak için --repository_cache işaretini kullanın. Örtülü 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 erişimi uygulanan ortamınızın dışına taşımak için önce boş bir çalışma alanı oluşturun:

mkdir empty_workspace && cd empty_workspace
touch MODULE.bazel
touch WORKSPACE

Yerleşik Bzlmod bağımlılıklarını getirmek için

bazel fetch --repository_cache="path/to/repository/cache"

Eski WORKSPACE dosyasını kullanmaya devam ediyorsanız yerleşik WORKSPACE bağımlılıklarını getirmek için

bazel sync --repository_cache="path/to/repository/cache"

Son olarak, hava boşluklu ortamınızda Bazel'i kullanırken aynı --repository_cache işaretini geçirin. İsterseniz .bazelrc girişi olarak ekleyebilirsiniz:

common --repository_cache="path/to/repository/cache"

Ayrıca, BCR'yi yerel olarak klonlamanız ve Bazel'in internet üzerinden BCR'ye erişmesini önlemek için yerel kopyanızı yönlendirmek üzere --registry işaretini kullanmanız gerekebilir. Aşağıdaki satırı .bazelrc cihazınıza ekleyin:

common --registry="path/to/local/bcr/registry"
Dağıtım dizini (7'den önce Bazel ile)

Dağıtım dizinini hazırlamak için --distdir işaretini kullanın. Örtülü 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 erişimi olan ortamınızın dışında oluşturmak için öncelikle doğru sürümdeki Bazel kaynak ağacına göz atı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 dolaylı çalışma zamanı bağımlılıklarını içeren tarball'u oluşturun:

bazel build @additional_distfiles//:archives.tar

Bu tarball'u, hava erişimi uygulanmış 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 geçirin. İsterseniz .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. İlk tür, projenizin BUILD dosyalarında depolanan doğal 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 veya çevresel verilerdir: hedef mimari, derleme, bağlantı seçenekleri ve diğer araç zinciri yapılandırma seçenekleri. Çevresel verilerin tamamına yapılandırma adı verilir.

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ş istasyonunuz 32 bit bir makine olan çapraz derlemeyi düşünün. Derlemenin mutlaka 64 bit yürütülebilir dosyalar oluşturabilen bir araç zinciri kullanarak //foo:bin derlemesi gerektiği açıkça görülüyor. Ancak derleme sisteminin, derleme sırasında kullanılan çeşitli araçları da (ör. kaynaktan derlenen ve daha sonra düzenli olarak kullanılan araçlar) oluşturması gerekir. Bu araçların da iş istasyonunuzda çalışacak şekilde tasarlanması gerekir. Bu sayede iki yapılandırma belirleyebiliriz: derleme sırasında çalışan araçlar oluşturmak için kullanılan exec yapılandırması ve en sonunda istediğiniz ikili programı oluşturmak için kullanılan hedef yapılandırma (veya istek yapılandırması diyoruz ancak kelime zaten birçok anlamı olsa da "hedef yapılandırma" deriz)

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 birçok kitaplık bulunur. Bu tür kitaplıklar, bir kez yürütme yapılandırması ve bir kez hedef yapılandırma için olmak üzere iki kez oluşturulmalıdır. Bazel, her iki varyantın da oluşturulmasını ve türetilen dosyaların girişim olmaması için ayrı tutulmasını sağlar. Bu tür hedefler, birbirinden bağımsız oldukları 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, istek yapılandırmasında belirtilenle aynı Crosstool (--crosstool_top) 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, --use_ijars ve --host_crosstool_top kullanılıyorsa yönetici yapılandırması için Crosstool'da bir default_toolchain araması yapmak (--compiler yok sayılarak) için --host_cpu değeri kullanılır.
  • --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şturulmadı (--copt=-g0).
  • Yürütülebilir dosyalardaki ve paylaşılan kitaplıklardaki hata ayıklama bilgilerini kaldırır (--strip=always).
  • Türetilen tüm dosyaları, olası tüm istek yapılandırması tarafından kullanılandan farklı, özel bir konuma yerleştirin.
  • Derleme verileriyle ikili programların damgalanmasını önleyin (--embed_* seçeneklerine bakın).
  • Diğer tüm değerler varsayılan değerlerinde kalır.

Birçok nedenden dolayı istek yapılandırmasından ayrı bir yönetici yapılandırması seçmek tercih edilebilir. En önemlisi:

İlk olarak, sadeleştirilmiş, optimize edilmiş ikili programları kullanarak araçları birbirine bağlamak ve yürütmek 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, daha önce açıklandığı gibi, tüm derlemelerdeki yönetici ve istek yapılandırmalarını ayrıştırarak 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çınırsınız.

Doğru artımlı yeniden oluşturma işlemleri

Bazel projesinin birincil hedeflerinden biri, doğru artımlı yeniden oluşturma işlemleridir. Önceki derleme araçları, özellikle de Make'e dayalı olanlar, artımlı derlemeleri uygularken bazı alakasız varsayımlarda bulunuyor.

İlk olarak, dosyaların zaman damgaları monoton olarak artar. Normalde böyle bir durum olsa da bu varsayıma saptırmak çok kolaydır; bir dosyanın daha eski bir düzeltmesine senkronize edilmesi o dosyada değişiklik süresinin kısalmasına neden olur; Make-tabanlı sistemler yeniden oluşturulmaz.

Daha genel olarak ifade etmek gerekirse Yap, dosyalarda değişiklik algılarken komutlardaki 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ı make clean kullanarak manuel olarak silmeniz gerekir.

Ayrıca Make, alt işlemlerinden birinin çıkış dosyasına yazmaya başladıktan sonra başarısız bir şekilde sonlandırılmasına karşı güçlü değildir. Mevcut Make yürütme işlemi başarısız olsa da bir sonraki Make komutu, kesilmiş çıkış dosyasının geçerli olduğunu (çünkü dosya girişlerinden daha yeni olduğu için) kabul etmez ve dosya yeniden oluşturulmaz. Benzer şekilde, Yapma süreci sona erdirilirse 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ını tutar ve yalnızca bu derleme adımındaki giriş dosyaları grubunun (ve bunların zaman damgalarının) ve bu derleme adımı için derleme komutunun veritabanındaki bir girişle tam olarak eşleştiğini ve veritabanı girişine ait çıkış dosyaları grubunun (ve bunların zaman damgalarının) diskteki dosyalar zaman damgalarıyla tam olarak eşleştiğini tespit etmesi durumunda derleme adımını atlar. Giriş dosyalarında, çıkış dosyalarında veya 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ılara avantajı, karışıklık nedeniyle daha az zaman kaybıdır. (Ayrıca, make clean kullanımından kaynaklanan yeniden oluşturma işlemleri için harcanan süre azalır. Bu süre, gerekli veya önleme amaçlıdır.)

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

Resmi olarak, beklenen tüm çıkış dosyaları mevcut olduğunda ve bunların içerikleri doğru olduğunda, derlemelerin durumunu tutarlı olarak tanımlarız. Bu durum, dosyaları oluşturmak için gereken adımlar veya kurallarda belirtildiği şekilde doğru demektir. Bir kaynak dosyayı düzenlediğinizde, derlemenin durumunun tutarsız olduğu söylenir ve derleme aracını başarıyla tamamlamak için bir sonraki çalıştırmanıza kadar tutarsız kalır. Bu yalnızca geçici bir durum olduğu ve derleme aracı çalıştırılarak tutarlılık sağlandığı için bu durumu kararsız tutarsızlık olarak tanımlarız.

Zararlı olan başka bir tutarsızlık türü daha vardır: istikrarlı tutarsızlık. Derleme kararlı bir tutarsız duruma ulaşırsa derleme aracının tekrarlanan başarılı çağrıları tutarlılığı geri yüklemez: Derleme "sıkışmış" ve sonuçlar yanlış kalır. Kararlı tutarsız durumlar, Make (ve diğer derleme araçları) kullanıcılarının make clean türünü paylaşmasının ana nedenidir. Derleme aracının bu şekilde başarısız olduğunu (ve daha sonra bu durumdan kurtarabileceğinizi) keşfetmek zaman alıcı ve çok sinir bozucu olabilir.

Kavramsal olarak tutarlı bir derleme elde etmenin en kolay yolu, önceki tüm derleme çıktılarını bir kenara atıp yeniden başlamak, her derlemeyi temiz bir yapı haline getirmektir. Bu yaklaşım bariz şekilde çok zaman alıcı olduğu için pratik olamayacak (belki de sürüm mühendisleri için) ve bu nedenle derleme aracının yararlı olması için tutarlılıktan ödün vermeden kademeli derlemeler gerçekleştirebilmesi gerekir.

Doğru 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 istikrarlı tutarsız durumlardan kaçınarak başarısız olur. Buna karşın, Bazel şu garantiyi sunar: Derleme aracı, düzenleme yapmadığınız başarılı bir şekilde çağrıldıktan sonra, derleme tutarlı bir durumda olur. (Bir derleme sırasında kaynak dosyalarınızı düzenlerseniz Bazel, mevcut derlemenin sonucunun tutarlılığı konusunda garanti vermez. Ancak bir sonraki derlemenin sonuçlarının tutarlılığı geri yükleyeceğini garanti eder.)

Tüm garantilerde olduğu gibi, bazı küçük yazımlar söz konusudur: Bazel ile tutarlı ve tutarsız bir duruma geçmenin bilinen bazı yolları vardır. Artımlı bağımlılık analizinde hata bulmaya yönelik kasıtlı çalışmalardan kaynaklanan bu tür sorunları araştıracağımızı garanti edemeyiz, ancak oluşturma aracının normal veya "makul" kullanımından kaynaklanan tüm kararlı tutarsız durumları araştıracağız ve düzeltmek için elimizden geleni yapacağız.

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

Korumalı alana sahip yürütme

Bazel, işlemlerin hermetik ve doğru şekilde çalışmasını garanti etmek için korumalı alanları kullanır. Bazel, aracın işini yapabilmesi için gereken minimum dosya grubunu içeren korumalı alanlarda spawns (ya da eylemler) çalıştırır. Korumalı alan, ş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ı alan kullanımını desteklemiyorsa, derlemelerin 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 aktarabilirsiniz.

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. 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 ile geneller ve --spawn_strategy=standalone ile diğer kurallar için korumalı alanı devre dışı bırakmayı deneyin. Ayrıca, konuyu araştırıp sonraki bir sürümde düzeltme sunabilmemiz için lütfen sorun izleyicimizdeki bir hatayı ve hangi Linux dağıtımını kullandığınızı belirtin.

Derleme aşamaları

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

Aşama yükleniyor

Birincisi, ilk hedefler için gerekli tüm DERLEME dosyalarının ve 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 DERLEME dosyalarının yüklendiği kadar saniye sürer. Sonraki derlemelerde, özellikle de hiçbir DERLEME dosyası değiştirilmemişse yükleme çok hızlı bir şekilde gerçekleşir.

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

Analiz aşaması

İkinci aşama olan analiz, her derleme kuralının semantik analizi 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üklemede olduğu 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 yapılması gerekenleri analiz eder. Böylece, önceki derlemeden bu yana paketlerin değişmediği durumlarda artımlı derlemeler son derece hızlı olabilir.

Bu aşamada bildirilen hatalar şunlardır: uygunsuz bağımlılıklar, bir kurala girilen 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 G/Ç dosyalarından 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 üzerine uygulanan, Bazel'ın query komutu gibi analiz araçları için iyi bir temel oluşturur.

Yürütme aşamasında

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ğlama/vb. araçları yeniden çalıştırır. Bu adım, büyük bir derlemede birkaç saniyeden uzun bir süreye kadar, derlemenin zamanının çoğunu harcadığı yerdir. Bu aşamada rapor edilen hatalar şunlardır: eksik kaynak dosyalar, bir derleme işlemi tarafından yürütülen araçtaki hatalar veya bir aracın beklenen çıkış kümesini üretememesi.