Platformlar

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

Bazel, bağlayıcılar ve derleyiciler gibi birçok farklı derleme aracı sürümünü kullanarak çeşitli donanımlarda, işletim sistemlerinde 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 kavramını kullanır. Kısıtlama, derleme veya üretim ortamlarının farklılık gösterebileceği bir boyuttur. Örneğin, CPU mimarisi, GPU'nun varlığı veya yokluğu ya da sisteme yüklenmiş bir derleyicinin sürümü. Platform, bu kısıtlamalar için adlandırılmış bir seçenekler koleksiyonudur ve belirli bir ortamda kullanılabilen kaynakları temsil eder.

Ortamı platform olarak modellemek, 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 hizmet verebileceği üç rolü tanır:

  • Ana makine: Bazel'in kendisinin üzerinde çalıştığı platform.
  • Yürütme: Ara ve son çıktıları oluşturmak için derleme araçlarının derleme işlemlerini yürüttüğü bir platform.
  • Hedef: Son çıktının bulunduğu ve yürütü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'da çalışan Ubuntu'da yürütülebilir bir Linux dosyası oluşturma.

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

  • Çok platformlu derlemeler: Ana makine, yürütme ve hedef platformların tümü farklıdır.

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

Platformlar için olası seçeneklerin 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, aşağıdaki BUILD dosyası snippet'i, sistemin glibc sürümü için iki olası değer içeren bir kısıtlama getirir.

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. Etiketlere göre referans verilir ve normal görünürlük denetimlerine tabidir. Görünürlük izin veriyorsa mevcut bir kısıtlama ayarını, kendi değerinizi tanımlayarak genişletebilirsiniz.

platform kuralı, belirli kısıtlama değeri seçeneklerine sahip yeni bir platformu kullanıma sunar. Aşağıdaki ifade, linux_x86 adlı bir platform oluşturur ve 2.25 glibc sürümüyle 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 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ılığını korumak için Bazel ekibi, en popüler CPU mimarileri ve işletim sistemleri için kısıtlama tanımlarının bulunduğu bir depo tutar. Bunların tümünü https://github.com/bazelbuild/platforms adresinde bulabilirsiniz.

Bazel, aşağıdaki özel platform tanımıyla birlikte gelir: @local_config_platform//:host. Bu, otomatik olarak algılanan ana makine platformu değeridir. Bazel'in üzerinde ç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 @local_config_platform//:host değerine ayarlanır.
    • @local_config_platform, ana makine işletim sistemini ve CPU'yu algılayıp platform hedefini yazan bir depo kuralıdır.
    • Ayrıca, diğer BUILD ve Starlark dosyalarında kullanılabilecek HOST_CONSTRAINTS adlı bir diziyi kullanıma sunan @local_config_platform//:constraintz.bzl oluşturur.
  • --platforms - varsayılan olarak ana makine platformu kullanılır
    • Bu, başka bir işaret ayarlanmadığında hedef platformun @local_config_platform//:host olduğu anlamına gelir.
    • --host_platform ayarlanmışsa ve --platforms ayarlanmamışsa --host_platform değeri hem ana makine hem de hedef platform olur.

Uyumsuz hedefleri atlama

Belirli bir hedef platform için geliştirme yaparken, söz konusu platformda hiçbir zaman çalışmayacak hedefleri atlamak genellikle istenir. Örneğin, //... ile Linux makinesinde derleme yaparken Windows cihaz sürücünüzün çok sayıda derleyici hatası oluşturması muhtemeldir. Kodunuzun hangi hedef platform kısıtlamalarına sahip olduğunu Bazel'e bildirmek için target_compatible_with özelliğini kullanın.

Bu özelliğin en basit kullanımı, hedefi tek bir platformla sınırlar. Hedef, kısıtlamaların tümünü karşılamayan hiçbir platform 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 oluşturmaya uygundur ve diğer tüm sistemlerle uyumsuzdur. Uyumsuzluk geçişlidir. Uyumsuz bir hedefe geçişli olarak bağlı olan tüm hedefler de uyumsuz kabul edilir.

Hedefler ne zaman atlanır?

Hedefler, uyumsuz olarak kabul edildiklerinde ve hedef kalıbı genişletme kapsamında derlemeye dahil edildiklerinde atlanır. Örneğin, aşağıdaki iki çağırma işlemi, 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 test_suite --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 kullanmak genişletmeyi engeller ve uyumsuz testlere sahip test_suite hedeflerinin de uyumsuz olmasına neden olur.

Komut satırında açıkça uyumsuz bir hedef belirtmek hata mesajına ve başarısız bir 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 uyumsuz açık hedefler sessizce atlanır.

Daha etkileyici kısıtlamalar

Kısıtlamaları ifade etmede 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() ile @platforms//:incompatible öğesini birlikte kullanın. Örneğin, temel VEYA mantığını uygulamak için kullanın. Aşağıdaki işaret, macOS ve Linux ile uyumlu olan ancak diğer platformlarla uyumlu olmayan bir kitaplığı gösterir.

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

  1. macOS hedeflenirken hedefte kısıtlama yoktur.
  2. Linux hedeflenirken 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 uyumsuz kabul edilir.

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

Ters uyumluluğu da benzer şekilde ifade edebilirsiniz. Aşağıdaki örnekte, ARM dışında 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 tespit etme

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

Bu, uyumsuz 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.