Platformlar

Sorun bildir Kaynağı görüntüleyin Nightly · 7.4 . 7.3 · 7.2 · 7.1 · 7.0 · 6.5

Bazel, bağlayıcılar ve derleyiciler gibi derleme araçlarının birçok farklı sürümünü kullanarak çeşitli donanımlarda, işletim sistemlerinde ve sistem yapılandırmalarında kod oluşturabilir ve test edebilir. Bazel, bu karmaşıklığı yönetmeye yardımcı olmak için kısıtlar ve platformlar kavramını kullanır. Kısıt, derleme veya üretim ortamlarının farklı olabileceği bir boyuttur (ör. CPU mimarisi, GPU'nun varlığı veya yokluğu ya da sisteme yüklenmiş bir derleyicinin sürümü). Platform, bazı ortamlarda mevcut olan belirli kaynakları temsil eden, bu kısıtlamalar için adlandırılmış bir seçenekler koleksiyonudur.

Ortamın platform olarak modellenmesi, Bazel'in 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 işleyebileceği üç rolün farkındadır:

  • Ana makine: Bazel'in çalıştığı platform.
  • Yürütme: Derleme araçlarının ara ve nihai çıkışlar oluşturmak için derleme işlemlerini yürüttüğü bir platformdur.
  • Hedef: Son çıktının bulunduğu ve çalıştırıldığı platform.

Bazel, platformlarla ilgili aşağıdaki derleme senaryolarını destekler:

  • Tek platformlu derlemeler (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 dosya derleme.

  • Çapraz derleme derlemeleri: Ana makine ve yürütme platformları aynıdır ancak hedef platform farklıdır. Örneğin, MacBook Pro'da macOS çalıştıran bir iOS uygulaması oluşturma.

  • Çoklu platform derlemeleri: Ana makine, yürütme ve hedef platformların hepsi farklıdır.

Kısıtlamaları ve platformları tanımlama

Platformlar için olası seçenekler alanı, BUILD dosyalarındaki constraint_setting ve constraint_value kuralları kullanılarak tanımlanır. constraint_setting yeni bir boyut oluşturur. constraint_value ise belirli bir boyut için yeni bir değer oluşturur. Birlikte enum ve olası değerlerini etkili bir şekilde tanımlarlar. Örneğin, aşağıdaki BUILD dosyası snippet'inde, sistemin glibc sürümü için iki olası değer içeren bir kısıtlama sunulmaktadır.

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 genel görünürlük kontrollerine tabidir. Görünürlük izin veriyorsa kendi değerinizi tanımlayarak mevcut bir kısıtlama ayarını genişletebilirsiniz.

platform kuralı, belirli kısıtlama değeri seçenekleri içeren yeni bir platform sunar. Aşağıdaki kod, linux_x86 adlı bir platform oluşturur ve 2.25 glibc sürümüne sahip bir x86_64 mimarisinde Linux işletim sistemi çalıştıran tüm ortamları tanımladığını belirtir. (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 yararlı kısıtlamalar ve platformlar

Ekosistemin tutarlı kalması için Bazel ekibi, en popüler CPU mimarileri ve işletim sistemleri için kısıtlama tanımları içeren bir depo tutar. Bunların hepsi https://github.com/bazelbuild/platforms adresinde bulunmaktadır.

Bazel, aşağıdaki özel platform tanımı ile birlikte gönderilir: @platforms//host (@bazel_tools//tools:host_platform olarak adlandırılır). Bu, otomatik olarak algılanan ana makine platform değeridir. 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 makineyi ve hedef platformları belirtebilirsiniz:

  • --host_platform: Varsayılan olarak @bazel_tools//tools:host_platform değerine ayarlanır.
    • Bu hedef, ana makine işletim sistemini ve CPU'yu algılayıp platform hedefini yazan bir depo kuralıyla desteklenen @platforms//host olarak adlandırılmıştır.
    • Diğer BUILD ve Starlark dosyalarında kullanılabilecek HOST_CONSTRAINTS adlı bir diziyi gösteren @platforms//host:constraints.bzl de vardır.
  • --platforms: Varsayılan olarak ana makine platformu kullanılır
    • Bu, başka işaret ayarlanmadığında hedef platformun @platforms//host olduğu anlamına gelir.
    • --platforms yerine --host_platform ayarlandıysa --host_platform değeri hem ana makine hem de hedef platformdur.

Uyumsuz hedefleri atlama

Belirli bir hedef platform için reklam oluştururken, genellikle o platformda hiçbir zaman çalışmayacak hedeflerin atlanması önerilir. Örneğin, Windows cihaz sürücünüz //... ile Linux makinede derleme yaparken büyük olasılıkla çok sayıda derleyici hatası oluşturacaktır. Bazel'e, kodunuzun hangi hedef platform kısıtlamalarına sahip olduğunu bildirmek için target_compatible_with özelliğini kullanın.

Bu özelliğin en basit kullanımı, bir hedefi tek bir platformla kısıtlamaktır. Hedef, tüm kısıtlamaları karşılamayan platformlar için oluşturulmaz. Aşağıdaki örnekte win_driver_lib.cc, 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 derleme için uyumludur ve diğer tüm sistemlerle uyumlu değildir. Uyumsuzluk geçişlidir. Geçiş yoluyla uyumsuz bir hedefe bağlı olan tüm hedeflerin uyumsuz olduğu kabul edilir.

Hedefler ne zaman atlanır?

Hedefler, uyumlu olmadığı kabul edildiğinde ve hedef kalıp genişletmesinin bir parçası olarak derlemeye dahil edildiğinde atlanır. Ö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 uyumlu olmayan testler de test_suite, komut satırında --expand_test_suites ile belirtilirse benzer şekilde atlanır. Diğer bir deyişle, komut satırındaki test_suite hedefleri :all ve ... gibi davranır. --noexpand_test_suites kullanılması genişletmeyi önler ve uyumsuz testlere sahip test_suite hedeflerin de uyumsuz olmasına neden olur.

Komut satırında uyumlu olmayan bir hedefin açıkça belirtilmesi hata mesajına ve başarısız derlemeye neden olur.

$ 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 etkinse uyumlu olmayan açık hedefler sessizce atlanır.

Daha fazla ifade gücü

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 @platforms//:incompatible ile birlikte select() kullanın. Örneğin, temel VEYA mantığını uygulamak için kullanın. Aşağıdakiler, macOS ve Linux ile uyumlu ancak başka platformlarla uyumlu bir kitaplık değildir.

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 ifade şu şekilde yorumlanabilir:

  1. macOS hedeflenirken hedefte kısıtlama bulunmaz.
  2. Linux'u hedeflerken hedefte kısıtlama yoktur.
  3. Aksi takdirde hedefte @platforms//:incompatible kısıtlaması vardır. @platforms//:incompatible herhangi bir platformun parçası olmadığı için hedef uyumlu değildir.

Kısıtlamalarınızı daha okunaklı hale getirmek için skylib'in selects.with_or() aracını kullanın.

Ters uyumluluğu da benzer ş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 hedefleri algılama

Uyumsuz hedefleri uyumlu olanlardan ayırt etmek için bazel cquery'ın Starlark çıkış biçimindeki IncompatiblePlatformProvider değerini kullanabilirsiniz.

Bu, uyumlu olmayan hedefleri filtrelemek için kullanılabilir. Aşağıdaki örnekte yalnızca uyumlu hedeflerin etiketleri yazdırılı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.