Platformlar

Sorun bildir Kaynağı göster

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ıyor. 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ılabilen belirli kaynakları temsil eden ve 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, bir platformun hizmet edebileceği üç rolün farkındadır:

  • Ana Makine - Bazel'ın kendisinin çalıştığı platform.
  • Yürütme: Derleme araçlarının, orta ve nihai çıktılar üretmek için derleme işlemlerini yürüttüğü bir platform.
  • Hedef: Nihai çıkışın yer aldığı ve çalıştırıldığı bir platform.

Bazel, platformlarla ilgili 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 çalıştırılabilir bir Linux derleme.

  • Ç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.

  • Çok platformlu derlemeler: 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 ise belirli bir boyut için yeni bir değer oluşturur. Bunlar birlikte bir sıralamayı ve olası değerlerini etkili bir şekilde tanımlar. Örneğin, bir BUILD dosyasının aşağıdaki snippet'i, sistemin glibc sürümü için iki olası değere sahip 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 etiketle referans verilir ve olağan görünürlük denetimlerine tabidirler. Görünürlük izin veriyorsa mevcut bir kısıtlama ayarını bunun için kendi değerinizi tanımlayarak genişletebilirsiniz.

platform kuralı, belirli kısıtlama değeri seçeneklerinin bulunduğu yeni bir platformu kullanıma sunuyor. Aşağıdaki örnek linux_x86 adlı bir platform oluşturur ve 2.25 glibc sürümüyle x86_64 mimarisinde bir Linux işletim sistemi çalıştıran tüm ortamları açıklar. (Bazel'in yerleşik kısıtlamaları hakkında daha fazla bilgi edinmek 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

Ekosistemin tutarlı olmasını 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. Bunların hepsi https://github.com/bazelbuild/platforms adresinde bulunmaktadır.

Bazel, aşağıdaki özel platform tanımıyla gönderilir: @local_config_platform//:host. Bu, otomatik olarak algılanan ana makine platformu değeridir ve Bazel'in ç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 @local_config_platform//:host değerine ayarlanır
    • @local_config_platform, ana işletim sistemi ve CPU'yu algılayıp platform hedefine yazan bir depo kuralı tarafından desteklenen bir depodur.
    • Ayrıca @local_config_platform//:constraints.bzl oluşturur. Bu dizi, diğer BUILD ve Starlark dosyalarında kullanılabilecek HOST_CONSTRAINTS adlı bir diziyi ortaya çıkarır.
  • --platforms - varsayılan olarak ana makine platformuna ayarlanır
    • Bu, başka işaret ayarlanmadığında hedef platformun @local_config_platform//:host olduğu anlamına gelir.
    • --platforms yerine --host_platform ayarlanırsa --host_platform değeri hem ana makine hem de hedef platform olur.

Uyumsuz hedefler atlanıyor

Belirli bir hedef platform için uygulama oluştururken o platformda hiçbir zaman çalışmayacak hedefleri atlamanız genellikle tercih edilir. Örneğin, Windows cihaz sürücünüz //... ile bir Linux makinesinde derleme yaparken çok sayıda derleyici hatası oluşturur. 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 sınırlandırılmış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 derlemek için uyumludur ve diğer öğelerle uyumlu değildir. Uyumsuzluk geçişlidir. Geçişli olarak uyumsuz bir hedefe bağlı olan hedeflerin kendisi uyumsuz olarak kabul edilir.

Hedefler ne zaman atlanır?

Hedefler, uyumsuz oldukları kabul edildiğinde atlanır ve hedef kalıbı genişletmesi kapsamında derlemeye dahil edilir. Örneğin, aşağıdaki iki çağrı, hedef kalıbı genişletmesinde bulunan tüm uyumsuz hedefleri atlar.

$ bazel build --platforms=//:myplatform //...
$ bazel build --platforms=//:myplatform //:all

Komut satırında --expand_test_suites ile birlikte test_suite belirtilmişse test_suite içindeki uyumsuz testler de 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 uygun hedefler sessizce atlanır.

Daha ifade edilmiş kısıtlamalar

Kısıtlamaları ifade etme konusunda daha fazla esneklik için hiçbir platformun karşılamadığı @platforms//:incompatible constraint_value kullanın.

Daha karmaşık kısıtlamaları ifade etmek için select()'i @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 açıklama şu şekilde yorumlanabilir:

  1. macOS hedeflenirken hedefte hiçbir kısıtlama yoktur.
  2. Linux hedeflenirken hedefte hiçbir kısıtlama yoktur.
  3. Aksi takdirde, hedefte @platforms//:incompatible kısıtlaması olur. @platforms//:incompatible herhangi bir platformun parçası olmadığından hedef, uyumsuz kabul edilir.

Kısıtlamalarınızı daha okunabilir hale getirmek için skylib selects.with_or() özelliğini kullanın.

Ters uyumluluğu da 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 kullanarak uyumsuz hedefler tespit ediliyor

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 hedeflerin etiketleri 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.