Bazel ile program oluşturun

Sorun bildirme Kaynağı görüntüleme Nightly · 7.4 .

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 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 standart hale getirin.
  • 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 döker.
  • help: Komutlar veya dizin için yardımı 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 için sürüm bilgilerini yazdırır.

Yardım alma

  • bazel help command: command için baskı yardımı ve seçenekleri.
  • 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 gerçekleştirir. En sık kullanılanlar bazel build ve bazel test. bazel help kullanarak çevrimiçi yardım mesajlarına göz atabilirsiniz.

Tek 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 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 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ı belirledikten sonra 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, 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 ç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ği için 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 çok 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, 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 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 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 paketlerdeki tüm kural hedefleri.
//foo/...:* foo dizininin altındaki tüm paketlerdeki tüm hedefler (kurallar ve dosyalar).
//foo/...:all-targets foo dizininin altındaki tüm paketlerdeki tüm hedefler (kurallar ve dosyalar).
//... Çalışma alanındaki paketlerdeki tüm hedefler. Buna harici depolar'daki hedefler dahil değildir.
//:all Çalışma alanının kökünde bir "BUILD" dosyası varsa üst düzey paketteki tüm hedefler.

// ile başlamayan hedef kalıplar, geçerli çalışma 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ı, ç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 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), 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 hedef kalıpların bir listesini 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. 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 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ğ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. Bazel'in bu test hedeflerini derlemesini/test etmesini istiyorsanız bu tür test hedeflerini komut satırında açık hedef kalıplarıyla 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ı indirir ve bunların sembolleriyle bağlantı kurar. 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. Derlemeler sırasında yeni bağımlılıkların eklenmesini engellemek isterseniz --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 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.

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

fetch, bağımlılıkları getirilecek 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ı almak için şu komutu çalıştırın:

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. 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. 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ının bulunduğundan eminse, yani indirme isteğinde belirtilen dosyanın SHA256 toplamına sahipse ve bu karmaya sahip bir dosya önbellekteyse önbellekten bir giriş alınır. Bu nedenle, her bir harici dosya için bir karma belirtmek, güvenlik açısından iyi bir fikir olmanın yanı sıra gereksiz indirmelerden de kaçınmaya yardımcı olur.

Her önbelleğe alma isabeti sonrasında, önbelleğe alınan 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). Artık yayında olmayan bir dosyanın kopyasını içerebileceği için önbellek hiçbir zaman otomatik olarak temizlenmez.

Dağıtım dosyası dizinleri

Dağıtım dizini, gereksiz indirmeleri önlemek için kullanılan başka bir Bazel mekanizmasıdır. Bazel, depo önbelleğinden önce dağıtım dizinlerinde arama yapar. 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 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 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 ö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 gizli bağımlılıklar, tüm WORKSPACE bağımlılıkları için tedarikçi firmanız olsa 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 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. Ö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 dolaylı çalışma zamanı bağımlılıklarını içeren tarball'u derleyin:

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, 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, kullanıcı veya derleme aracı tarafından sağlanan harici veya ortam verileridir: 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 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. Böylece iki yapılandırma tanımlayabiliriz: Derleme sırasında çalışan araçlar derlemek için kullanılan ana makine yapılandırması ve en nihayetinde istediğiniz ikili projeyi oluşturmak için kullanılan hedef yapılandırma (veya istek yapılandırması, ancak çoğu zaman "hedef yapılandırma" diyelim, ancak bu kelimenin zaten birçok anlamı olsa da) kullanın.

Genellikle hem istenen derleme hedefinin (//foo:bin) hem de ana makine araçlarından bir veya daha fazlasının (örneğin bazı temel kitaplıklar) ön koşulu olan çok sayıda kitaplık bulunur. Bu tür kitaplıklar, biri ana makine yapılandırması, biri de hedef yapılandırma için olmak üzere iki kez oluşturulmalıdır. 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ürseniz muhtemelen açıklama budur.

Bazel, ana makine yapılandırmasını seçmek için --distinct_host_configuration seçeneğine bağlı olarak iki yöntemden birini kullanır. Bu boole seçeneği biraz güçsüzdür ve bu ayar, derlemelerinizin hızını iyileştirebilir (veya kötüleştirebilir).

--distinct_host_configuration=false

Bu seçenek yanlış olduğunda ana makine ve istek yapılandırmaları aynıdır: derleme sırasında gereken tüm araçlar, hedef programlarla tam olarak aynı şekilde derlenir. Bu ayar, tek bir derleme sırasında hiçbir kitaplığın iki kez oluşturulmasına gerek olmadığı anlamına gelir.

Ancak bu, istek yapılandırmanızda yapılan herhangi bir değişikliğin ana makine yapılandırmanızı da etkileyeceği ve tüm araçların yeniden oluşturulmasına neden olacağı ve bu durumda araç çıkışına bağlı tüm öğelerin de yeniden oluşturulması gerektiği anlamına gelir. Bu nedenle, örneğin, derlemeler arasında bir bağlayıcı seçeneğini değiştirmek, tüm araçların yeniden bağlanmasına ve ardından bunları kullanan tüm işlemlerin yeniden yürütülmesine neden olabilir. Bu da çok büyük bir yeniden derlemeye yol açar.

--distinct_host_configuration=true (varsayılan)

Bu seçenek Doğru değerine ayarlanırsa ana makine ve istek için aynı yapılandırmayı kullanmak yerine tamamen farklı bir ana makine yapılandırması kullanılır. Ana makine yapılandırması, hedef yapılandırmadan aşağıdaki gibi 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 belirtilen değerleri kullanın: --compiler, --use_ijars ve --host_crosstool_top kullanılıyorsa ana makine 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).
  • Hata ayıklama bilgilerini yürütülebilir dosyalardan ve paylaşılan kitaplıklardan 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 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 ana makine yapılandırması seçmenin tercih edilmesinin birçok nedeni vardır. Bazılarından bahsetmek çok ezoterik olsa da ikisine değinmek gerekiyor.

Ö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 derlemelerdeki ana makine ve istek yapılandırmalarını ayrıştırarak, daha önce açıklandığı gibi istek yapılandırmasındaki 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.

Bununla birlikte, belirli derlemelerde bu seçenek bir engel olabilir. Özellikle, yapılandırma değişikliklerinin nadiren yapıldığı (özellikle belirli Java derlemeleri) ve hem ana makine hem de hedef yapılandırmalarda oluşturulması gereken kod miktarının büyük olduğu derlemeler faydalı olmayabilir.

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

Bazel projesinin birincil hedeflerinden biri, doğru artımlı yeniden derlemeleri sağlamaktır. Önceki derleme araçları (özellikle Make tabanlı 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. 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, Make işlemi sonlandırılırsa benzer bir durum ortaya çıkabilir.

Bazel, bu ve benzeri 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ş 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şi için çı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 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ılara sağladığı avantaj: Kafa karışıklığı nedeniyle daha az zaman kaybı. (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

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, derleme durumunun tutarsız olduğu söylenir ve derleme aracını başarılı bir şekilde tamamlayana kadar bu durum tutarlı olmaz. Bu 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ımlıyoruz.

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 yazmasının başlıca nedeni kararlı tutarsız durumlardır. Derleme aracının bu şekilde başarısız olduğunu keşfetmek (ve sonra onu kurtarmak) 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ın pratik olamayacak kadar zaman alıcı olduğu açıktır (belki de 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ığı 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ı 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.

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. 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. 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 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 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 hedeflerin 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 ş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 tamamı 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 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ütme aşamasıdır. 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 zamanının büyük bölümünü harcar. Büyük bir derleme için birkaç saniye ile bir saatten fazla bir süre arasında değişir. 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.