Bazel; bağlayıcılar ve derleyiciler gibi derleme araçlarının birçok farklı sürümünü kullanarak çeşitli donanımlar, işletim sistemleri ve sistem yapılandırmalarında kod oluşturup test edebilir. Bazel, bu karmaşıklığı yönetmeye yardımcı olmak için kısıtlamalar ve platformlar kavramlarını kullanır. Kısıtlama; CPU mimarisi, GPU'nun olup olmaması veya sistem tarafından yüklü derleyicinin sürümü gibi derleme veya üretim ortamlarının farklı olabileceği bir boyuttur. Platform, bazı ortamlarda kullanılabilir olan belirli kaynakları temsil eden bu kısıtlamalar için adlandırılmış bir seçenek koleksiyonudur.
Ortamın platform olarak modellenmesi, Bazel'ın derleme işlemleri için uygun araç zincirlerini otomatik olarak seçmesine yardımcı olur. Platformlar, yapılandırılabilir özellikler yazmak için config_setting kuralıyla birlikte de kullanılabilir.
Bazel, platformda hizmet verebilecek üç rolü tanır:
- Ana makine - Bazel'ın kendisinin çalıştırıldığı platform.
- Yürütme: Derleme araçlarının, ara ve nihai çıktılar üretmek için derleme işlemlerini yürüttüğü platform.
- Hedef - Nihai çıkışın yer aldığı ve yürütüldüğü platform.
Bazel, platformlarla ilgili olarak aşağıdaki oluşturma senaryolarını destekler:
Tek platform derlemeleri (varsayılan): Ana makine, yürütme ve hedef platformlar aynıdır. Örneğin, Intel x64 CPU üzerinde çalışan Ubuntu'da yürütülebilir bir Linux oluşturma.
Çapraz derleme derlemeleri: Ana makine ve yürütme platformları aynı ancak hedef platform farklıdır. Örneğin, macOS'te MacBook Pro'da çalışan bir iOS uygulaması oluşturabilirsiniz.
Çoklu platform derlemeleri: Ana makine, yürütme ve hedef platformlar birbirinden farklıdır.
Kısıtlamaları ve platformları tanımlama
Platformlar için olası seçim alanı, BUILD
dosyalarındaki constraint_setting
ve constraint_value
kuralları kullanılarak tanımlanır.
constraint_setting
yeni bir boyut oluştururken constraint_value
belirli bir boyut için yeni bir değer oluşturur. Birlikte bir enum ve olası değerlerini etkili bir şekilde tanımlarlar. Örneğin, bir BUILD
dosyasının aşağıdaki snippet'i, sistemin glibc sürümü için iki olası değerle bir kısıtlama sunar.
constraint_setting(name = "glibc_version")
constraint_value(
name = "glibc_2_25",
constraint_setting = ":glibc_version",
)
constraint_value(
name = "glibc_2_26",
constraint_setting = ":glibc_version",
)
Kısıtlamalar ve değerleri, çalışma alanındaki farklı paketlerde tanımlanabilir. Bunlara etikete göre referans verilir ve bunlar genel görünürlük denetimlerine tabidir. Görünürlük izin veriyorsa mevcut bir kısıtlama ayarı için kendi değerinizi tanımlayarak bu ayarı genişletebilirsiniz.
platform
kuralı, belirli kısıtlama değeri seçenekleriyle yeni bir platform sunar. Aşağıda linux_x86
adlı bir platform oluşturulmuştur ve bu platformun, 2.25 glibc sürümüyle bir x86_64 mimarisi üzerinde Linux işletim sistemi çalıştıran tüm ortamların açıklandığı belirtilmektedir. (Bazel'ın yerleşik kısıtlamaları hakkında daha fazla bilgi için aşağıya bakın.)
platform(
name = "linux_x86",
constraint_values = [
"@platforms//os:linux",
"@platforms//cpu:x86_64",
":glibc_2_25",
],
)
Genel olarak faydalı kısıtlamalar ve platformlar
Ekosistem tutarlılığı sağlamak için Bazel ekibi en popüler CPU mimarileri ve işletim sistemleri için sınırlı tanımlar içeren bir depoya sahiptir. Bu platformların hepsi https://github.com/bazelbuild/platforms adresinde bulunmaktadır.
Bazel, aşağıdaki özel platform tanımıyla sunulur: @platforms//host
(diğer adı @bazel_tools//tools:host_platform
). Bu, otomatik olarak algılanan ana makine platformu değeridir ve Bazel'ın çalıştığı sistem için otomatik olarak algılanan platformu temsil eder.
Derleme için platform belirtme
Aşağıdaki komut satırı işaretlerini kullanarak bir derleme için ana makine ve hedef platformları belirtebilirsiniz:
--host_platform
- varsayılan olarak@bazel_tools//tools:host_platform
değerine ayarlanır- Bu hedefin diğer adı
@platforms//host
olan ve ana makine işletim sistemi ile CPU'yu algılayıp platform hedefini yazan bir depo kuralı tarafından desteklenir. - Ayrıca, diğer BUILD ve Starlark dosyalarında kullanılabilecek
HOST_CONSTRAINTS
adlı bir diziyi açığa çıkaran@platforms//host:constraints.bzl
vardır.
- Bu hedefin diğer adı
--platforms
: Varsayılan olarak ana makine platformuna ayarlanır- Bu, başka işaret ayarlanmadığında hedef platformun
@platforms//host
olduğu anlamına gelir. --platforms
yerine--host_platform
ayarlanırsa--host_platform
hem ana makine hem de hedef platform olur.
- Bu, başka işaret ayarlanmadığında hedef platformun
Uyumsuz hedefler atlanıyor
Belirli bir hedef platform için geliştirme yaparken, o platformda hiçbir zaman çalışmayacak hedefleri atlamak genellikle tercih edilir. Örneğin, Windows cihaz sürücünüz //...
ile bir Linux makinesinde derleme yaparken muhtemelen çok sayıda derleyici hatası oluşturacaktır. Bazel'a kodunuzda hangi hedef platform kısıtlamalarının olduğunu bildirmek için target_compatible_with
özelliğini kullanın.
Bu özelliğin en basit kullanımı, hedefi tek bir platformla kısıtlar.
Hedef, tüm kısıtlamaları karşılamayan herhangi bir platform için oluşturulmaz. Aşağıdaki örnekte, win_driver_lib.cc
değeri 64 bit Windows ile kısıtlanmıştır.
cc_library(
name = "win_driver_lib",
srcs = ["win_driver_lib.cc"],
target_compatible_with = [
"@platforms//cpu:x86_64",
"@platforms//os:windows",
],
)
:win_driver_lib
yalnızca 64 bit Windows ile derlemeye uygundur ve başka hiçbir sistemle uyumlu değildir. Uyumsuzluk durumu geçişlidir. Geçişli olarak uyumsuz bir hedefe bağımlı olan hedeflerin kendileri uyumsuz olarak kabul edilir.
Hedefler ne zaman atlanır?
Hedefler, uyumsuz olduklarında atlanır ve hedef kalıbı genişletmesinin parçası olarak derlemeye dahil edilir. Örneğin, aşağıdaki iki çağrı, hedef kalıp genişletmesinde bulunan tüm uyumsuz hedefleri atlar.
$ bazel build --platforms=//:myplatform //...
$ bazel build --platforms=//:myplatform //:all
test_suite
içindeki uyumsuz testler, komut satırında --expand_test_suites
ile birlikte test_suite
belirtilmişse benzer şekilde atlanır.
Diğer bir deyişle, komut satırındaki test_suite
hedefleri :all
ve ...
gibi davranır. --noexpand_test_suites
kullanmak, genişletmeyi engeller ve uyumsuz testlere sahip test_suite
hedeflerinin de uyumsuz olmasına neden olur.
Komut satırında uyumsuz bir hedefin açıkça belirtilmesi, hata mesajıyla ve başarısız derlemeyle sonuçlanır.
$ bazel build --platforms=//:myplatform //:target_incompatible_with_myplatform
...
ERROR: Target //:target_incompatible_with_myplatform is incompatible and cannot be built, but was explicitly requested.
...
FAILED: Build did NOT complete successfully
--skip_incompatible_explicit_targets
etkinleştirilirse uyumsuz olan açık hedefler sessizce atlanır.
Daha etkili kısıtlamalar
Kısıtlamaları ifade etme konusunda daha fazla esneklik için hiçbir platformun karşılamadığı @platforms//:incompatible
constraint_value
yöntemini kullanın.
Daha karmaşık kısıtlamaları ifade etmek için select()
etiketini @platforms//:incompatible
ile birlikte kullanın. Örneğin, temel VEYA mantığını uygulamak için bunu kullanın. Aşağıda, macOS ve Linux ile uyumlu olan ancak başka platformlarla uyumlu olmayan bir kitaplık belirtilmiştir.
cc_library(
name = "unixish_lib",
srcs = ["unixish_lib.cc"],
target_compatible_with = select({
"@platforms//os:osx": [],
"@platforms//os:linux": [],
"//conditions:default": ["@platforms//:incompatible"],
}),
)
Yukarıdaki yorum şu şekilde yorumlanabilir:
- macOS hedeflenirken hedefte herhangi bir kısıtlama olmaz.
- Linux hedeflenirken hedefte hiçbir kısıtlama olmaz.
- Aksi takdirde, hedefin
@platforms//:incompatible
kısıtlaması olur.@platforms//:incompatible
hiçbir platforma dahil olmadığından hedef uyumsuz olarak kabul edilir.
Kısıtlamalarınızı daha okunabilir hale getirmek için skylib selects.with_or()
özelliğini kullanın.
Ters uyumluluğu benzer bir şekilde ifade edebilirsiniz. Aşağıdaki örnekte, ARM hariç her şeyle uyumlu bir kitaplık açıklanmaktadır.
cc_library(
name = "non_arm_lib",
srcs = ["non_arm_lib.cc"],
target_compatible_with = select({
"@platforms//cpu:arm": ["@platforms//:incompatible"],
"//conditions:default": [],
}),
)
bazel cquery
kullanılarak uyumsuz hedefler algılanıyor
Uyumsuz hedefleri uyumlulardan ayırt etmek için bazel cquery
uygulamasının Starlark çıkış biçiminde IncompatiblePlatformProvider
kullanabilirsiniz.
Bu özellik, uyumsuz hedefleri filtrelemek için kullanılabilir. Aşağıdaki örnekte yalnızca uyumlu hedeflere ilişkin etiketler yazdırılmaktadır. Uyumsuz hedefler yazdırılmaz.
$ cat example.cquery
def format(target):
if "IncompatiblePlatformProvider" not in providers(target):
return target.label
return ""
$ bazel cquery //... --output=starlark --starlark:file=example.cquery
Bilinen sorunlar
Uyumsuz hedefler görünürlük kısıtlamalarını yoksayar.