Bazel ile program oluşturun

Sorun bildirme Kaynağı görüntüleme Nightly · 8.0 7.4 . 7.3 · 7.2 · 7.1 · 7.0 · 6.5

Bu sayfada, Bazel ile program oluşturma, derleme komutu söz dizimi ve hedef kalıp söz dizimi ele alınmaktadır.

Hızlı başlangıç kılavuzu

Bazel'i çalıştırmak için ana çalışma alanı dizininize veya alt dizinlerinden birine gidip bazel yazın. Yeni bir çalışma alanı oluşturmanız gerekiyorsa oluştur bölümüne bakın.

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

Mevcut komutlar

  • analyze-profile: Oluşturma profili verilerini analiz eder.
  • aquery: Analizin ardından işlem grafiğinde bir sorgu yürütür.
  • build: Belirtilen hedefleri oluşturur.
  • canonicalize-flags: Bazel işaretlerini standart hale getirin.
  • clean: Çıkış dosyalarını kaldırır ve isteğe bağlı olarak sunucuyu durdurur.
  • cquery: Analizin ardından bağımlılık grafiği sorgusu yürütür.
  • dump: Bazel sunucu sürecinin dahili durumunu döker.
  • help: Komutlarla ilgili yardım bilgilerini veya dizini yazdırır.
  • info: Bazel sunucusu hakkında çalışma zamanı bilgilerini gösterir.
  • fetch: Bir hedefin tüm harici bağımlılıklarını getirir.
  • mobile-install: Mobil cihazlara uygulama 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'in sürüm bilgilerini yazdırır.

Yardım alma

  • bazel help command: command için baskılarla ilgili yardım ve seçenekler.
  • bazel helpstartup_options: Bazel'i barındıran JVM seçenekleri.
  • bazel helptarget-syntax: Hedefleri belirtme 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 gerçekleştirir. En sık kullanılanlar bazel build ve bazel test'dur. bazel help simgesini kullanarak çevrimiçi yardım mesajlarına göz atabilirsiniz.

Tek bir hedef oluşturma

Derleme işlemine başlamadan önce bir çalışma alanı oluşturmanız gerekir. Çalışma alanı, uygulamanızı oluşturmak için gereken tüm kaynak dosyalarını içeren bir dizin ağacıdır. Bazel, tamamen salt okunur bir hacimden derleme yapmanıza olanak tanır.

Bazel ile program derlemek için bazel build yazıp ardından derlemek istediğiniz hedefi 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 beyan edilen bağımlılar (doğrudan hedefin BUILD dosyasında listelenen dosyalar) ve geçiş bağımlılar (hedefinizin bağımlılıklarının BUILD dosyalarında listelenen dosyalar) dahildir. Bazel, tüm bağımlılıkları belirledikten sonra doğruluk açısından analiz eder ve derleme işlemlerini oluşturur. Son olarak Bazel, derleyicileri ve derlemenin diğer araçlarını executes.

Bazel, derlemenin yürütme aşamasında ilerleme mesajları yazdırır. İlerleme mesajları, mevcut derleme adımını (ör. derleyici veya bağlayıcı) başladığı anda ve toplam derleme işlemi sayısına göre tamamlanan sayıyı içerir. Derleme başladığında Bazel, işlem grafiğinin tamamını keşfettiği için toplam işlem sayısı genellikle artar ancak birkaç saniye içinde sabitlenir.

Derlemenin sonunda Bazel, hangi hedeflerin istendiğini, bunların başarıyla derlenip derlenmediğini ve derlendiyse çı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 bölümüne bakın.

Aynı komutu tekrar yazarsanız derleme işlemi ç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 bir boş derleme. Hiçbir şey değişmediğinden yeniden yüklenecek paket ve yürütülecek derleme adımı yoktur. "foo" veya bağımlılıklarında bir değişiklik olursa Bazel bazı derleme işlemlerini yeniden yürütür ya da artımlı derleme işlemini tamamlar.

Birden fazla hedef oluşturma

Bazel, derlenecek hedefleri belirtmek için çeşitli yöntemlere olanak tanır. Bunlar birlikte 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ıkları belirtmek gibi tek hedefleri belirtmek için kullanılırken Bazel'in hedef kalıpları birden çok hedefi belirtir. Hedef kalıpları, joker karakterler kullanılarak hedeflerin grupları için etiket söz dizimini genelleştirir. En basit durumda, geçerli etiketler de geçerli hedef kalıplardır ve tam olarak bir hedef grubu tanımlar.

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

//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 depoda bulunan paketlerdeki tüm kural hedefleri. Harici depolardan gelen hedefleri içermez.
//:all Çalışma alanının kökünde bir "BUILD" dosyası varsa üst düzey paketteki tüm kural hedefleri.

// ile başlamayan hedef kalıplar, geçerli çalışma dizine göre çözülür. Bu örneklerde, foo çalışma dizini 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ğer:
  • foo/bar/wiz bir paketse //foo/bar/wiz:wiz
  • foo/bar bir paketse //foo/bar:wiz
  • //foo:bar/wiz aksi durumda
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ı, çıkış tabanının altına işaret edenler hariç (ör. çalışma alanının kök dizininde oluşturulan kolaylık sembolik bağlantıları) yinelenen hedef kalıpları için takip edilir.

Ayrıca Bazel, aşağıdaki şekilde adlandırılmış bir dosya içeren herhangi bir dizindeki yinelenen hedef kalıplarını değerlendirirken sembolik bağlantıları takip etmez: DONT_FOLLOW_SYMLINKS_WHEN_TRAVERSING_THIS_DIRECTORY_VIA_A_RECURSIVE_TARGET_PATTERN

foo/..., paketler için bir joker karakterdir ve foo dizininin altındaki tüm paketleri yinelenen şekilde belirtir (paket yolunun tüm kökleri için). :all, bir paketteki tüm kuralları eşleştiren hedefler için bir joker karakterdir. Bu ikisi, foo/...:all gibi bir ifadede birleştirilebilir ve her iki joker karakter de kullanıldığında bu ifade foo/... olarak kısaltılabilir.

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

Bu, :*'ün :all'ın süper kümesini ifade ettiği anlamına gelir. Bu söz dizimi, kafa karıştırıcı olsa da _deploy.jar gibi derleme hedeflerinin istenmediği tipik derlemelerde tanıdık :all joker karakterinin kullanılmasına olanak tanır.

Ayrıca Bazel, etiket söz diziminde gereken iki nokta üst üste yerine eğik çizgi kullanılmasına izin verir. Bu, 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ıp listesi kabul eder ve bunların tümü ön ek olumsuzlama operatörünü - kullanır. Bu, önceki bağımsız değişkenler tarafından belirtilen gruptan bir hedef grubu çıkarmak için kullanılabilir. Sıranı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 derle" anlamına gelir.

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

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

Ancak bu şekilde çıkarılan hedeflerin, çıkarılmayan hedeflerin bağımlılıkları olabileceğinden, bu hedeflerin oluşturulmadığının garanti edilmeyeceğini belirtmek önemlidir. Örneğin, diğerlerinin yanı sıra //foo/bar:api'a bağlı bir //foo:all-apis hedefi varsa ikincisi, birincinin oluşturulmasını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'in bu test hedeflerini derlemesini/test etmesini istiyorsanız komut satırında açık hedef kalıplarıyla bu test hedeflerini belirtmeniz gerekir. Buna karşılık bazel query, bu tür bir filtrelemeyi otomatik olarak gerçekleştirmez (bu, bazel query'ün amacını geçersiz kılar).

Harici bağımlılıkları getirme

Varsayılan olarak Bazel, derleme sırasında harici bağımlılıkları indirip sembolik bağlantı oluşturur. Ancak yeni harici bağımlılıkların ne zaman eklendiğini bilmek veya bağımlılıkları "önceden almak" (ör. çevrimdışı olacağınız bir uçuştan önce) istemeniz nedeniyle bu durum istenmeyebilir. Derleme sırasında yeni bağımlılıkların eklenmesini engellemek istiyorsanız --fetch=false işaretini belirtebilirsiniz. Bu işaretin yalnızca yerel dosya sistemindeki bir dizini işaretlemeyen depo kuralları için geçerli olduğunu unutmayın. Örneğin, local_repository, new_local_repository ve Android SDK ve NDK depo kurallarında yapılan değişiklikler, --fetch değerinden bağımsız olarak her zaman geçerli olur .

Derlemeler sırasında getirme işlemine izin vermezseniz ve Bazel yeni harici bağımlılık 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'yi çalıştırmanız gerekir:

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

Bir kez çalıştırıldıktan sonra MODULE.bazel dosyası değişene kadar tekrar çalıştırmanız gerekmez.

fetch, bağımlılıkları getirilecek hedeflerin listesini alır. Örneğin, bu komut //foo:bar ve //bar:baz'yi 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ı almak için şu komutu çalıştırın:

bazel fetch //...

Bazel 7 veya sonraki sürümlerde, Bzlmod'u etkinleştirdiyseniz aşağıdaki komutu çalıştırarak tüm harici bağımlılıkları da getirebilirsiniz:

bazel fetch

Kullandığınız tüm araçlar (kitaplık jar'larından JDK'ya kadar) Workspace kök dizininizdeyse bazel fetch'i çalıştırmanız gerekmez. Ancak Workspace 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, aynı dosyanın farklı çalışma alanlarında kullanılması gerekse bile veya harici bir deposun tanımı değişse bile yine aynı dosyanın indirilmesi gerekiyorsa bile aynı dosyayı birden çok kez getirmemeye çalışır. Bunun için bazel, indirilen tüm dosyaları varsayılan olarak ~/.cache/bazel/_bazel_$USER/cache/repos/v1/ konumunda bulunan depo önbelleği içinde önbelleğe alır. Konum, --repository_cache seçeneğiyle 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ğunu kesin olarak biliyorsa (yani indirme isteğinde belirtilen dosyanın SHA256 toplamı varsa ve önbellekte bu karmaya sahip bir dosya varsa) önbellekten bir giriş alınır. Bu nedenle, her harici dosya için karma değeri belirtmek yalnızca güvenlik açısından iyi bir fikir değil, aynı zamanda gereksiz indirmelerden de kaçınmanıza yardımcı olur.

Her önbelleğe isabet edildiğinde, önbelleğe alınan dosyanın değişiklik zamanı güncellenir. Bu sayede, önbellek dizininde bir dosyanın son kullanımı kolayca belirlenebilir (ör. önbelleği manuel olarak temizlemek için). Artık yayında olmayan bir dosyanın kopyasını içerebileceği için önbellek hiçbir zaman otomatik olarak temizlenmez.

[Kullanımdan Kaldırıldı] Dağıtım dosyası dizinleri

Kullanımdan kaldırıldı: Çevrimdışı derleme yapmak için depolama alanı önbelleğini kullanmak 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. Başlıca fark, dağıtım dizininin manuel olarak hazırlanması gerektiğidir.

--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ıyla aynıysa ve ayrıca dosyanın karması indirme isteğinde belirtilenle aynıysa bu tür bir dizinden dosya alınır. Bu yöntem yalnızca dosya karması, depo kuralı beyanında 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 bire düşürür. Bu sayede, dağıtım dosyası dizinlerini belirtmek, bu tür bir dizindeki dosya sayısı çok fazla olsa bile etkili olmaya devam eder.

Bazel'i hava boşluğu olan bir ortamda çalıştırma

Bazel'in ikili dosya boyutunu küçük tutmak için Bazel'in gizli bağımlılıkları, ilk kez çalıştırıldığında ağ üzerinden getirilir. Bu gizli bağımlılıklarda, herkes için gerekli olmayabilecek araç zincirleri ve kurallar bulunur. Örneğin, Android araçları yalnızca Android projeleri oluşturulurken paketten çıkarılır ve getirilir.

Ancak bu gizli bağımlılıklar, tüm harici bağımlılıklarınıza tedarikçi firma sağlamış olsanız bile Bazel'i hava boşluğu olan 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ümlerde) ya da dağıtım dizini (Bazel 7'den önceki sürümlerde) hazırlayabilir ve ardından bunları çevrimdışı bir yaklaşımla hava boşluğu ortamına aktarabilirsiniz.

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

Depo önbelleğini hazırlamak için --repository_cache işaretini kullanın. Örtük bağımlılıklar her sürüm için farklı olabileceğinden, bunu her yeni Bazel ikili sürümü için bir kez yapmanız gerekir.

Bu bağımlılıkları, izole edilmiş ortamınızın dışından almak için önce boş bir çalışma alanı oluşturun:

mkdir empty_workspace && cd empty_workspace
touch MODULE.bazel

Yerleşik Bzlmod bağımlılıkları almak 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ı almak için

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

Son olarak, Bazel'i hava boşluğu olan ortamınızda kullanırken aynı --repository_cache işaretini iletin. Kolaylık sağlamak için .bazelrc girişi olarak ekleyebilirsiniz:

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

Ayrıca, Bazel'in internet üzerinden BCR'ye erişmesini önlemek için BCR'yi yerel olarak kopyalamanız ve yerel kopyanızı işaretlemek için --registry işaretini kullanmanız da gerekebilir. .bazelrc dosyanıza aşağıdaki satırı ekleyin:

common --registry="path/to/local/bcr/registry"
Dağıtım dizini (7'den önceki Bazel sürümleriyle)

Dağıtım dizini oluşturmak için --distdir işaretini kullanın. Örtük bağımlılıklar her sürüm için farklı olabileceğinden, bunu her yeni Bazel ikili sürümü için bir kez yapmanız gerekir.

Bu bağımlılıkları hava boşluğu olan ortamınızın dışında derlemek için önce 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ünün varsayılan çalışma zamanı bağımlılıkları içeren tarball'ı oluşturun:

bazel build @additional_distfiles//:archives.tar

Bu tarball'ı, hava boşluğu olan ortamınıza kopyalanabilecek bir dizine aktarın. --distdir, dizin iç içe yerleştirme düzeyinde 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, Bazel'i hava boşluğu olan ortamınızda kullanırken dizine işaret eden --distdir işaretini iletin. Kolaylık sağlamak için .bazelrc girişi olarak ekleyebilirsiniz:

build --distdir=path/to/directory

Derleme yapılandırmaları ve çapraz 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 içsel bilgilerdir: derleme kuralı, özelliklerinin değerleri ve geçişli bağımlılıklarının tamamı. İkinci tür, kullanıcı veya derleme aracı tarafından sağlanan harici veya çevresel verilerdir: hedef mimari seçimi, derleme ve bağlama seçenekleri ve diğer araç zinciri yapılandırma seçenekleri. Tam bir çevre verisi grubuna yapılandırma denir.

Herhangi bir derlemede birden fazla yapılandırma olabilir. 64 bit mimari için //foo:bin yürütülebilir dosya oluşturduğunuz ancak iş istasyonunuzun 32 bit bir makine olduğu bir çapraz derleme düşünün. Derleme işlemi için //foo:bin'ün 64 bit yürütülebilir dosyalar oluşturabilen bir araç zinciri kullanılarak derlenmesi gerektiği açıktır. Ancak derleme sistemi, derleme sırasında kullanılan çeşitli araçları (ör. kaynaktan derlenen ve daha sonra bir genrule'de kullanılan araçlar) da derlemelidir ve bu araçlar, iş istasyonunuzda çalışacak şekilde derlenmelidir. Bu nedenle, iki yapılandırma tanımlayabiliriz: derleme sırasında çalışan araçları derlemek için kullanılan yürütme yapılandırması ve nihayetinde istediğiniz ikili dosyayı derlemek için kullanılan hedef yapılandırma (veya istem yapılandırması, ancak bu kelimenin zaten birçok anlamı olmasına rağmen daha çok "hedef yapılandırma" deriz).

Genellikle hem istenen derleme hedefinin (//foo:bin) hem de bir veya daha fazla yürütme aracının (ör. bazı temel kitaplıklar) ön koşulu olan birçok kitaplık vardır. 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 derlenmelidir. Bazel, her iki varyantın da derlendiğinden ve türetilmiş dosyaların karışıklık olmaması için ayrı tutulduğundan emin olur. Bu tür hedefler genellikle birbirinden bağımsız oldukları için eşzamanlı olarak derlenebilir. Belirli bir hedefin iki kez oluşturulduğunu belirten ilerleme mesajları görüyorsanız bunun nedeni büyük olasılıkla budur.

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

  • --host_crosstool_top belirtilmediği sürece, istek yapılandırmasında belirtilen Crosstool (--crosstool_top) 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 belirtilenlerle aynı değerlerini kullanın: --compiler, --use_ijars ve --host_crosstool_top kullanılıyorsa exec yapılandırması için Crosstool'da bir default_toolchain aramak üzere --host_cpu değeri kullanılır (--compiler yoksayı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ş derlemeleri kullanın (-c opt).
  • Hata ayıklama bilgisi oluşturmaz (--copt=-g0).
  • Hata ayıklama bilgilerini yürütülebilir dosyalardan ve paylaşılan kitaplıklardan kaldırın (--strip=always).
  • Tüm türetilmiş dosyaları, olası tüm istek yapılandırmalarının kullandığından farklı bir özel konuma yerleştirin.
  • Derleme verileriyle ikili dosyaların damgalanması engellenir (--embed_* seçeneklerine bakın).
  • Diğer tüm değerler varsayılan değerlerinde kalır.

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

Öncelikle, yalıtılmış ve optimize edilmiş ikili dosyalar kullanarak araçları bağlama ve yürütme için harcanan zamanı, araçların kapladığı disk alanını ve dağıtılmış derlemelerde ağ I/O süresini azaltırsınız.

İkinci olarak, tüm derlemelerde yürütme ve istek yapılandırmalarını birbirinden ayırarak, daha önce açıklandığı gibi istek yapılandırmasında yapılan küçük değişikliklerden (ör. bir bağlayıcı seçeneğini değiştirme) kaynaklanan çok pahalı yeniden derlemelerden kaçınabilirsiniz.

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

Bazel projesinin birincil hedeflerinden biri, doğru artımlı yeniden derlemeleri sağlamaktır. Önceki derleme araçları (özellikle Make'e dayalı olanlar), artımlı derlemeleri uygulama konusunda birkaç mantıksız varsayımda bulunur.

Öncelikle, dosyaların zaman damgalarının tekdüze şekilde arttığına dikkat edin. Bu durum genelde geçerli olsa da bu varsayıma düşmek çok kolaydır. Bir dosyanın önceki bir düzeltmesiyle senkronize edildiğinde, söz konusu dosyanın değişiklik zamanı azalır. Make tabanlı sistemler yeniden oluşturmaz.

Daha genel bir ifadeyle, Make, dosyalarda yapılan değişiklikleri algılar ancak 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ı make clean kullanarak manuel olarak reddetmek gerekir.

Ayrıca Make, alt işlemlerinden biri çıkış dosyasına yazmaya başladıktan sonra bu alt işlemin başarısız bir şekilde sonlandırılmasına karşı güçlü değildir. Make'in mevcut yürütmesi başarısız olsa da Make'in sonraki çağrısı, kısaltılmış çıkış dosyasının geçerli olduğunu (girişlerinden daha yeni olduğu için) varsayar ve yeniden oluşturulmaz. Benzer şekilde, Make işlemi sonlandırılırsa benzer bir durum ortaya çıkabilir.

Bazel bu ve diğer varsayımlardan kaçınır. Bazel, daha önce yapılan tüm çalışmaların veritabanını tutar ve yalnızca ilgili derleme adımı için girişteki giriş dosyalarının (ve zaman damgalarının) ve derleme komutunun veritabanındaki bir girişle tam olarak eşleştiğini ve veritabanı girişindeki çıkış dosyalarının (ve zaman damgalarının) diskteki dosyaların zaman damgalarıyla tam olarak eşleştiğini tespit ederse bir derleme adımını atlar. Giriş dosyalarında, çıkış dosyalarında veya komutun kendisinde yapılan herhangi bir değişiklik, derleme adımını yeniden yürütür.

Doğru artımlı derlemeleri kullanan kullanıcılara sağladığı avantaj: Kafa karışıklığı nedeniyle daha az zaman kaybı. (Ayrıca, gerekli veya önleyici olsun, make clean kullanımının neden olduğu yeniden oluşturma işlemlerini beklemek için daha az zaman harcarsınız.)

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

Resmi olarak, beklenen tüm çıkış dosyaları mevcut olduğunda ve içerikleri, oluşturulmaları için gereken adımlar veya kurallarda belirtildiği gibi 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 derleme aracını başarıyla tamamlayana kadar tutarsız kalır. Bu durum yalnızca geçici olduğu ve derleme aracı çalıştırılarak tutarlılık sağlandığı için istikrarsız tutarsızlık olarak tanımlanır.

Zararlı olan başka bir tutarsızlık türü de sabit tutarsızlıktır. Derleme kararlı bir tutarsız duruma ulaşırsa derleme aracının tekrar tekrar başarılı şekilde çağrılması tutarlılığı geri getirmez: Derleme "takılır" ve çıkışlar yanlış kalır. Make (ve diğer derleme araçları) kullanıcılarının make clean türünü kullanmalarının başlıca nedeni kararlı tutarsız durumlardır. Derleme aracının bu şekilde başarısız olduğunu öğrenmek (ve ardından bu durumdan kurtulmak) zaman alıcı ve can sıkıcı olabilir.

Kavramsal olarak, tutarlı bir derleme elde etmenin en basit yolu, önceki tüm derleme çıktılarını atmak ve baştan başlamaktır: Her derlemeyi temiz bir derleme yapın. Bu yaklaşımın pratik olması için çok zaman aldığı açıktır (belki de sürüm mühendisleri için hariç). 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 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çınmada yetersizdir. Buna karşılık Bazel şu garantiyi sunar: Hiçbir düzenleme yapmadığınız bir derleme aracı çağrısı başarılı bir şekilde tamamlandı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 hiçbir garanti vermez. Ancak sonraki derlemenin sonuçlarının tutarlılığı geri getireceğini garanti eder.)

Tüm garantilerde olduğu gibi, bazı küçük yazılar da vardır: Bazel ile kararlı bir tutarsız duruma 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ı inceleyeceğimizi garanti edemeyiz. Ancak derleme aracının normal veya "makul" kullanımından kaynaklanan tüm kararlı tutarsız durumları inceleyip düzeltmek için elimizden geleni yapacağız.

Bazel ile ilgili tutarsız bir durum tespit ederseniz lütfen hatayı bildirin.

Korumalı alanda yürütme

Bazel, işlemlerin hermetik ve doğru şekilde çalışmasını sağlamak için korumalı alanlar kullanır. Bazel, spawn'ları (genel anlamda işlemler) yalnızca aracın görevini yerine getirmek için ihtiyaç duyduğu minimum dosya grubunu içeren korumalı alanlarda çalıştırır. Şu anda korumalı alan, CONFIG_USER_NS seçeneği etkinleştirilmiş Linux 3.12 veya daha yeni sürümlerde ve macOS 10.11 veya daha yeni sürümlerde çalışır.

Sisteminizde korumalı alan desteklenmiyorsa Bazel, derlemelerin hermetik olmasının garanti edilmediği ve ana sistemi bilinmeyen şekillerde etkileyebileceği konusunda sizi uyarmak için bir uyarı yazdırır. Bu uyarıyı devre dışı bırakmak için Bazel'e --ignore_unsupported_sandboxing işaretini 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. Bu, /proc/sys/kernel/unprivileged_userns_clone dosyasına bakılarak kontrol edilebilir: Dosya mevcutsa ve 0 içeriyorsa kullanıcı ad alanlarının sudo sysctl kernel.unprivileged_userns_clone=1 ile etkinleştirilmesi mümkündür.

Bazen 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'e benzer bir mesaj gösteren bir hatadır. Bu durumda, --strategy=Genrule=standalone ile başlayan genrules kuralları ve --spawn_strategy=standalone ile başlayan diğer kurallar için korumalı alanı devre dışı bırakmayı deneyin. Ayrıca, sorunu inceleyip sonraki bir sürümde düzeltme sunabilmemiz için lütfen sorun takipçimizde bir hata bildirin ve hangi Linux dağıtımını kullandığınızı belirtin.

Derlemenin aşamaları

Bazel'de derleme üç farklı aşamada gerçekleşir. Kullanıcı olarak bu aşamalar arasındaki farkları anlamak, derlemeyi kontrol eden seçenekler hakkında bilgi edinmenize yardımcı olur (Aşağıya bakın).

Yükleme aşaması

İlki, ilk hedefler için gerekli tüm BUILD dosyalarının ve bu dosyaların bağımlılıkların geçişli 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 çalıştırıldıktan sonra ilk derleme için, dosya sisteminden birçok BUILD dosyası yüklendiğinden yükleme aşaması genellikle birkaç saniye sürer. Sonraki derlemelerde, özellikle BUILD dosyası değişmediyse yükleme çok hızlı gerçekleşir.

Bu aşamada bildirilen hatalar şunlardır: paket bulunamadı, hedef bulunamadı, BUILD dosyasında söz dizimi 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ğrulamasını, derleme bağımlılık grafiğinin oluşturulmasını ve derlemenin her adımında tam olarak ne tür bir çalışmanın yapılacağının belirlenmesini içerir.

Yükleme gibi analiz de tamamı hesaplandığında birkaç saniye sürer. Ancak Bazel, bir derlemeden sonraki derlemeye kadar olan bağımlılık grafiğini önbelleğe alır ve yalnızca gerekli olanları yeniden analiz eder. Bu da paketlerin önceki derlemeden beri değişmediği durumlarda artımlı derlemeleri son derece hızlı hale getirebilir.

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ı.

Bazel bu aşamada gereksiz dosya G/Ç işlemlerinden kaçındığı ve yapılacak işi belirlemek için yalnızca BUILD dosyalarını okuduğu için yükleme ve analiz aşamaları hızlıdır. Bu durum, Bazel'in yükleme aşamasının üzerine uygulanan sorgu komutu gibi analiz araçları için Bazel'i iyi bir temel haline getirir.

Yürütme aşamasında

Derlemenin üçüncü ve son aşaması yürütmedir. Bu aşamada, derlemedeki her bir adımın çıktılarının girişleriyle tutarlı olması sağlanır. Gerekirse derleme/bağlama/vb. araçları yeniden çalıştırılır. Bu adımda derleme işleminin büyük bir kısmı gerçekleşir. Büyük bir derleme işlemi birkaç saniyeden bir saatin üzerine kadar sürebilir. Bu aşamada bildirilen hatalar şunlardır: eksik kaynak dosyalar, bazı derleme işlemleri tarafından yürütülen bir araçtaki hatalar veya bir aracın beklenen çıkış grubunu üretememesi.