Bazel ile program oluşturun

Sorun bildir Kaynağı görüntüle Nightly · 8.3 · 8.2 · 8.1 · 8.0 · 7.6

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

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

Bazel'i çalıştırmak için temel çalışma alanı dizininize veya alt dizinlerinden herhangi birine gidip bazel yazın. Yeni bir çalışma alanı oluşturmanız gerekiyorsa oluşturma 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 sürecinin dahili durumunu boşaltır.
  • help: Komutlarla ilgili yardım veya dizin yazdırılı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 uygulama yükler.
  • query: Bağımlılık grafiği sorgusunu 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 ile ilgili yardım ve seçenekleri yazdırır.
  • bazel helpstartup_options: Bazel'i barındıran JVM'ye yönelik seçenekler.
  • bazel helptarget-syntax: Hedefleri belirtme söz dizimini açıklar.
  • bazel help info-keys: Bilgi komutu tarafından kullanılan anahtarların listesini gösterir.

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

Tek bir hedef oluşturma

Derleme başlatabilmek için ç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ıp oluşturmak istediğiniz hedefi girin.

bazel build //foo

//foo oluşturma 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 bildirilmiş bağımlılıklar, doğrudan hedefin BUILD dosyasında listelenen dosyalar ve geçişli bağımlılıklar (hedefinizin bağımlılıklarının BUILD dosyalarında listelenen dosyalar) 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, derleyicileri ve derlemenin diğer araçlarını yürütür.

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

Derlemenin sonunda Bazel, hangi hedeflerin istendiğini, başarılı bir şekilde 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 ç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 null build'dir. 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ı bir derleme gerçekleştirir.

Birden fazla 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ındaki bağımlılıkları bildirmek gibi tek tek hedefleri belirtmek için kullanılırken Bazel'in hedef kalıpları birden fazla hedefi belirtir. Hedef kalıpları, hedef grupları için etiket söz diziminin genelleştirilmiş halidir ve joker karakterler kullanır. En basit durumda, geçerli etiketlerin tümü geçerli hedef kalıplardır ve tam olarak bir hedef kümesini tanımlar.

// 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 Paketteki tüm kural hedefleri foo/bar.
//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ünde bir "BUILD" dosyası varsa üst düzey paketteki tüm kural hedefleri.

// ile başlamayan hedef desenler, mevcut çalışma dizinine göre çözümlenir. Bu örneklerde, çalışma dizininin foo olduğu varsayılı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 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, çalışma alanının kök dizininde oluşturulan kolaylık sembolik bağlantıları gibi çıkış tabanının altını işaret edenler hariç, yinelemeli hedef kalıpları için dizin sembolik bağlantıları takip edilir.

Ayrıca Bazel, aşağıdaki gibi adlandırılmış bir dosya içeren herhangi bir dizinde yinelemeli 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 üzerinde bir joker karakterdir ve foo dizininin altındaki tüm paketleri yinelemeli olarak gösterir (paket yolunun tüm kökleri için). :all, bir paketteki tüm kurallarla eşleşen hedefler üzerinde bir joker karakterdir. Bu ikisi foo/...:all şeklinde birleştirilebilir ve her iki joker karakter de kullanıldığında foo/... şeklinde kısaltılabilir.

Ayrıca, :* (veya :all-targets), 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. Örneğin, java_binary kurallarıyla ilişkili _deploy.jar dosyaları.

Bu, :*'nın :all'ün üst kümesi olduğunu gösterir. Bu söz dizimi kafa karıştırıcı olsa da _deploy.jar gibi derleme hedeflerinin istenmediği normal derlemelerde :all joker karakterinin kullanılmasına olanak tanır.

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, genellikle Bash dosya adı genişletme 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, hedef kalıpların listesini bağımsız değişken olarak kabul eder ve hepsi, ön ek olumsuzlama operatörü -'ye uyar. Bu, bir dizi hedefi önceki bağımsız değişkenlerle belirtilen kümeden çıkarmak için kullanılabilir. Bu durumda sıranın önemli olduğunu unutmayın. Örneğin,

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

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

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

, "foo altındaki tüm hedefleri foo/bar altındakiler hariç 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.)

Ancak bu şekilde hedefleri çıkarma işleminin, oluşturulmamış hedeflerin bağımlılıkları olabileceğinden, hedeflerin oluşturulmayacağını garanti etmediğini belirtmek önemlidir. Örneğin, diğerlerinin yanı sıra //foo/bar:api öğesine bağlı bir //foo:all-apis hedefi varsa //foo/bar:api, //foo:all-apis öğesinin oluşturulması kapsamında 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 bunları oluşturmasını/test etmesini istiyorsanız komut satırında bu tür test hedeflerini açık hedef kalıplarıyla belirtmeniz gerekir. Bunun aksine, bazel query bu tür bir filtrelemeyi otomatik olarak gerçekleştirmez (bu, bazel query'nın amacını bozar).

Harici bağımlılıklar getiriliyor

Varsayılan olarak Bazel, derleme sırasında harici bağımlılıkları indirir ve sembolik bağlantı oluşturur. Ancak bu durum, yeni harici bağımlılıklar eklendiğinde bildirim almak veya bağımlılıkları "önceden getirmek" (ör. internete bağlı olmayacağınız bir uçuş öncesinde) istediğiniz için istenmeyebilir. 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 dizini 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çerli olur .

Derlemeler 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 getirebilirsiniz. Derleme sırasında getirme işlemine izin vermezseniz bazel fetch komutunu çalıştırmanız gerekir:

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

Bu komut çalıştırıldıktan sonra MODULE.bazel dosyasında değişiklik yapılana kadar tekrar çalıştırmanız gerekmez.

fetch, bağımlılıkları getirmek için hedeflerin listesini alır. Örneğin, bu komut //foo:bar ve //bar:baz öğelerini oluşturmak 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 sürümlerde, Bzlmod etkinse 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) çalışma alanınızın kök dizininde bulunuyorsa bazel fetch komutunu çalıştırmanız gerekmez. Ancak çalışma alanı dizini dışında bir şey kullanıyorsanız Bazel, bazel fetch komutunu çalıştırmadan önce bazel build komutunu otomatik olarak çalıştırır.

Depo önbelleği

Bazel, aynı dosya farklı çalışma alanlarında gerekse veya harici bir deponun tanımı değişmiş olsa bile aynı dosyayı birden çok 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 depodaki tüm indirilen dosyaları ö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ğundan eminse (yani indirme isteğinde belirtilen dosyanın SHA256 toplamı varsa ve bu karma değerine sahip bir dosya önbellekteyse) önbellekten bir giriş alınır. Bu nedenle, her harici dosya için karma belirtmek yalnızca güvenlik açısından iyi bir fikir değildir. Aynı zamanda gereksiz indirmeleri önlemeye de yardımcı olur.

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

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

Kullanımdan kaldırıldı: Çevrimdışı derleme için depo önbelleğini kullanmak tercih edilir.

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

--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 dosyanın karması, indirme isteğinde belirtilen karmayla aynıysa bu tür bir dizinden dosya alınır. Bu yalnızca dosya karması depo kuralı bildiriminde belirtilmişse çalışır.

Dosya adıyla ilgili koşul, doğruluğu sağlamak için gerekli olmasa da belirtilen dizin başına aday dosya sayısını bire düşürür. Bu sayede, bu tür bir dizindeki dosya sayısı çok fazla olsa bile dağıtım dosyaları dizinlerini belirtmek verimli olmaya devam eder.

Bazel'i internet bağlantısı olmayan bir ortamda çalıştırma

Bazel'in ikili boyutunu küçük tutmak için Bazel'in örtülü bağımlılıkları ilk kez çalıştırılı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ı paketlenmez ve yalnızca Android projeleri oluşturulurken getirilir.

Ancak, tüm harici bağımlılıklarınızı satıcıdan almış olsanız bile, bu örtülü bağımlılıklar Bazel'i internet bağlantısı olmayan 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 önceki Bazel sürümleriyle) hazırlayabilir ve ardından bunları çevrimdışı bir yaklaşımla hava boşluklu ortama aktarabilirsiniz.

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

Depo önbelleğini hazırlamak için --repository_cache işaretini kullanın. Bu işlemi, her yeni Bazel ikili sürümü için bir kez yapmanız gerekir. Çünkü örtülü bağımlılıklar her sürümde farklı olabilir.

Bu bağımlılıkları hava boşluklu ortamınızın dışında getirmek 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ını getirmek için şu komutu çalıştırın:

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

Hâlâ eski WORKSPACE dosyasına güveniyorsanız yerleşik WORKSPACE bağımlılıklarını getirmek için şu komutu çalıştırın:

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 iletin. Kolaylık sağlaması için bunu .bazelrc girişi olarak ekleyebilirsiniz:

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

Ayrıca, BCR'yi yerel olarak klonlamanız ve yerel kopyanızı işaretlemek için --registry işaretini kullanmanız da gerekebilir. Bu sayede Bazel'in internet üzerinden BCR'ye erişmesi engellenir. .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ümlerinde)

Dağıtım dizinini hazırlamak için --distdir işaretini kullanın. Bu işlemi, her yeni Bazel ikili sürümü için bir kez yapmanız gerekir. Çünkü örtülü bağımlılıklar her sürümde farklı olabilir.

Bu bağımlılıkları hava boşluklu ortamınızın dışında oluşturmak için önce Bazel kaynak ağacını doğru sürümde kullanıma alı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 örtülü çalışma zamanı bağımlılıklarını içeren tarball'u oluşturun:

bazel build @additional_distfiles//:archives.tar

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

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 sağlaması için bunu .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. Birinci tür, projenizin BUILD dosyalarında depolanan temel 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 seçimi, derleme ve bağlantı seçenekleri ile diğer araç zinciri yapılandırma seçenekleri. Çevresel verilerin eksiksiz bir kümesine yapılandırma diyoruz.

Belirli bir derlemede birden fazla yapılandırma olabilir. 64 bit mimari için //foo:bin yürütülebilir dosyası oluşturduğunuz ancak iş istasyonunuzun 32 bit makine olduğu çapraz derlemeyi düşünün. Açıkça görülüyor ki derleme, 64 bit yürütülebilir dosyalar oluşturabilen bir araç zinciri kullanılarak //foo:bin oluşturulmasını gerektirecek. Ancak derleme sisteminin, derleme sırasında kullanılan çeşitli araçları da (ör. kaynaktan oluşturulan ve daha sonra örneğin bir genrule'da kullanılan araçlar) oluşturması gerekiyor. Bunların da iş istasyonunuzda çalışacak şekilde oluşturulması gerekiyor. Bu nedenle, 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 nihayetinde istediğiniz ikili dosyayı oluşturmak için kullanılan hedef yapılandırması (veya istek yapılandırması, ancak bu kelime zaten birçok anlama sahip olsa da daha sık "hedef yapılandırması" diyoruz).

Genellikle, hem istenen derleme hedefi (//foo:bin) hem de bir veya daha fazla yürütülebilir araç için ön koşul olan birçok kitaplık vardır. Örneğin, bazı temel kitaplıklar. Bu tür kitaplıklar iki kez oluşturulmalıdır: bir kez yürütülebilir yapılandırma için, bir kez de hedef yapılandırma için. Bazel, her iki varyantın da oluşturulmasını ve türetilmiş dosyaların karışmayı önlemek için ayrı tutulmasını sağlar. Genellikle bu tür hedefler, birbirinden bağımsız oldukları için eşzamanlı olarak oluşturulabilir. 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).
  • İstek yapılandırmasında belirtilen seçeneklerin değerlerini kullanın: --compiler, --use_ijars ve --host_crosstool_top kullanılıyorsa --host_cpu değeri, yürütme yapılandırması için Çapraz Araç'ta default_toolchain araması yapmak üzere 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ı istek yapılandırması tarafından kullanılan konumdan farklı özel bir konuma yerleştirin.
  • İkili dosyaların derleme verileriyle damgalanmasını engeller (--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 olabilir. En önemlisi:

İlk olarak, gereksiz kısımları çıkarılmış ve optimize edilmiş ikili dosyaları kullanarak araçları bağlama ve yürütme için harcanan süreyi, araçların kapladığı disk alanını ve dağıtılmış derlemelerdeki ağ G/Ç süresini azaltırsınız.

İkincisi, tüm derlemelerde yürütme ve istek yapılandırmalarını birbirinden ayırarak, istek yapılandırmasında yapılan küçük değişikliklerden (ör. bağlayıcı seçeneklerini değiştirme) kaynaklanacak çok maliyetli yeniden derlemeleri önleyebilirsiniz.

Artımlı yeniden derlemeleri düzeltme

Bazel projesinin temel hedeflerinden biri, doğru artımlı yeniden derlemeler sağlamaktır. Özellikle Make tabanlı olan önceki derleme araçları, artımlı derlemeleri uygularken birkaç hatalı varsayımda bulunur.

İlk olarak, dosyaların zaman damgaları tekdüze şekilde artar. Bu durum genellikle geçerli olsa da bu varsayımın ihlal edilmesi çok kolaydır. Bir dosyanın önceki bir düzeltmesine senkronize edilmesi, dosyanın değiştirilme zamanının azalmasına neden olur. Make tabanlı sistemler yeniden oluşturulmaz.

Daha genel olarak, Make dosyalarındaki değişiklikleri 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 make clean kullanarak önceki derlemenin geçersiz çıkışlarını manuel olarak atmanız 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şı dayanıklı değildir. Make'in mevcut yürütülmesi başarısız olsa da Make'in sonraki çağrılması, kısaltılmış çıkış dosyasının geçerli olduğunu (girişlerinden daha yeni olduğu için) körü körüne varsayar ve yeniden oluşturulmaz. Benzer şekilde, Make işlemi sonlandırılırsa da benzer bir durum oluşabilir.

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 bu derleme adımına ait giriş dosyaları kümesinin (ve bunların zaman damgalarının) ve bu derleme adımına ait derleme komutunun veritabanındaki bir girişle tam olarak eşleştiğini ve veritabanı girişine ait çıkış dosyaları kümesinin (ve bunların zaman damgalarının) diskteki dosyaların zaman damgalarıyla tam olarak eşleştiğini bulursa bir derleme adımını atlar. Giriş dosyalarında, çıkış dosyalarında veya komutta 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ılar için avantajı: kafa karışıklığı nedeniyle daha az zaman kaybı. (Ayrıca, gerekli olsun veya olmasın, make clean kullanımı nedeniyle yeniden oluşturma işlemlerinin tamamlanmasını beklemek için daha az zaman harcanır.)

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 kurallar tarafından belirtildiği gibi doğru olduğunda derlemenin durumunu tutarlı olarak tanımlarız. Bir kaynak dosyayı düzenlediğinizde derlemenin durumu tutarsız olarak adlandırılır ve derleme aracını bir sonraki başarılı tamamlamaya kadar tutarsız kalır. Bu durum yalnızca geçici olduğundan ve derleme aracı çalıştırılarak tutarlılık geri yüklendiğinden kararsız tutarsızlık olarak tanımlanır.

Zararlı olan başka bir tutarsızlık türü daha vardır: Kararlı tutarsızlık. Derleme kararsız bir duruma ulaşırsa derleme aracının tekrar tekrar başarılı bir şekilde çağrılması tutarlılığı geri getirmez: Derleme "takılır" ve çıkışlar yanlış kalır. Kararsız tutarsız durumlar, Make (ve diğer derleme araçları) kullanıcılarının make clean yazmasının temel nedenidir. Derleme aracının bu şekilde başarısız olduğunu keşfetmek (ve ardından bu durumdan kurtulmak) zaman alıcı ve çok sinir bozucu olabilir.

Tutarlı bir derleme elde etmenin kavramsal olarak en basit yolu, önceki tüm derleme çıktılarını silip baştan başlamaktır. Yani her derlemeyi temiz bir derleme haline getirmektir. Bu yaklaşım, pratik olması için çok fazla zaman gerektirir (belki yayın mühendisleri hariç). Bu nedenle, derleme aracının tutarlılıktan ödün vermeden artımlı derlemeler yapabilmesi gerekir.

Artımlı bağımlılık analizini doğru şekilde yapmak zordur ve yukarıda açıklandığı gibi, diğer birçok derleme aracı artımlı derlemeler sırasında kararlı olmayan tutarsız durumları önleme konusunda başarısız olur. Buna karşılık Bazel, aşağıdaki garantiyi sunar: Derleme aracı başarılı bir şekilde çağrıldıktan sonra ve siz herhangi bir düzenleme yapmadıysanız derleme tutarlı bir durumda olur. (Kaynak dosyalarınızı derleme sırasında düzenlerseniz Bazel, mevcut derlemenin sonucunun tutarlılığı konusunda garanti vermez. Ancak bu işlem, sonraki derlemenin sonuçlarının tutarlılığı geri yükleyeceğini garanti eder.)

Tüm garantilerde olduğu gibi, Bazel'in kararsız bir duruma girmesine neden olabilecek bazı bilinen yöntemler vardır. Artımlı bağımlılık analizinde hata bulmaya yönelik kasıtlı girişimlerden kaynaklanan bu tür sorunları inceleyeceğimizi garanti etmiyoruz. Ancak derleme aracının normal veya "makul" kullanımından kaynaklanan tüm kararsız tutarsız durumları inceleyip düzeltmek için elimizden geleni yapacağız.

Bazel'de 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 sanal alanları kullanır. Bazel, yalnızca aracın işini yapması için gereken minimum dosya grubunu içeren sanal ortamlarda spawns (kabaca: işlemler) çalıştırır. Şu anda sanal alan, CONFIG_USER_NS seçeneği etkinleştirilmiş Linux 3.12 veya daha yeni sürümlerde ve macOS 10.11 ya da daha yeni sürümlerde çalışmaktadır.

Sisteminiz sanal alan oluşturmayı desteklemiyorsa Bazel, derlemelerin hermetik olmasının 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 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ışıdır. Bu, dosya /proc/sys/kernel/unprivileged_userns_clone incelenerek kontrol edilebilir: Dosya varsa ve 0 içeriyorsa kullanıcı ad alanları sudo sysctl kernel.unprivileged_userns_clone=1 ile etkinleştirilebilir.

Bazı durumlarda, sistem kurulumu nedeniyle Bazel korumalı alanı kuralları yürütemez. Belirti genellikle namespace-sandbox.c:633: execvp(argv[0], argv): No such file or directory benzeri bir mesajın çıktısını veren bir hatadır. Bu durumda, --strategy=Genrule=standalone ile genrules için ve --spawn_strategy=standalone ile diğer kurallar için korumalı alanı devre dışı bırakmayı deneyin. Ayrıca, sorunu inceleyip sonraki bir sürümde düzeltme sağlayabilmemiz için lütfen sorun izleyicimizde 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 farkı anlamak, derlemeyi kontrol eden seçenekler hakkında bilgi edinmenizi sağlar (aşağıya bakın).

Yükleme aşaması

Birincisi, ilk hedefler ve bunların geçişli bağımlılık kapanımları için gerekli tüm BUILD dosyalarının yüklendiği, ayrıştırıldığı, değerlendirildiği ve önbelleğe alındığı yükleme aşamasıdır.

Bazel sunucusu başlatıldıktan sonraki ilk derleme için yükleme aşaması genellikle birçok BUILD dosyası dosya sisteminden yüklendiğinden birkaç saniye sürer. Sonraki derlemelerde, özellikle BUILD dosyalarında değişiklik yapılmadıysa yükleme çok hızlı gerçekleşir.

Bu aşamada bildirilen hatalar arasında şunlar yer alır: paket bulunamadı, hedef bulunamadı, BUILD dosyasındaki sözcüksel 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ı, derleme bağımlılığı grafiğinin oluşturulmasını ve derlemenin her adımında tam olarak hangi işin yapılacağının 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 yapması gerekenleri yeniden analiz eder. Bu da paketler önceki derlemeden bu yana değişmediyse artımlı derlemeleri son derece hızlı hale getirebilir.

Bu aşamada bildirilen hatalar arasında şunlar yer alır: uygunsuz bağımlılıklar, bir kurala verilen geçersiz girişler ve kurala özgü tüm hata mesajları.

Bazel, bu aşamada gereksiz dosya G/Ç'sinden kaçındığı için yükleme ve analiz aşamaları hızlıdır. Yapılacak işi belirlemek için yalnızca BUILD dosyalarını okur. Bu durum, tasarım gereğidir ve Bazel'i analiz araçları için iyi bir temel haline getirir. Örneğin, yükleme aşamasının üzerinde uygulanan Bazel'in query komutu gibi.

Yürütme aşaması

Geliştirme sürecinin üçüncü ve son aşaması uygulamadır. Bu aşamada, derlemedeki her adımın çıkışlarının girişleriyle tutarlı olması sağlanır ve gerektiğinde derleme/bağlama/vb. araçları yeniden çalıştırılır. Bu adımda derleme, zamanının büyük bir kısmını harcar. Bu süre, birkaç saniyeden büyük bir derleme için bir saati aşan bir süreye kadar değişebilir. Bu aşamada bildirilen hatalar arasında şunlar yer alır: kaynak dosyaların eksik olması, bazı derleme işlemleri tarafından yürütülen bir araçtaki hatalar veya bir aracın beklenen çıktı grubunu oluşturamaması.