Platformlar

Sorun bildirin Kaynağı göster

Bazel, bağlayıcı ve derleyici gibi derleme araçlarının birçok farklı sürümünü kullanarak çeşitli donanım, işletim sistemleri ve sistem yapılandırmaları üzerinde kod oluşturup test edebilir. Bazel, bu karmaşıklığı yönetmeye yardımcı olmak için sınırlamalar ve platformlar kavramına sahiptir. Kısıtlama; CPU mimarisi, GPU'nun olup olmaması veya sistem tarafından yüklenmiş derleyici sürümü gibi derleme ya da üretim ortamlarının farklılık gösterebileceği boyuttur. 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 üretmek için derleme işlemlerini yürüttüğü bir platformdur.
  • Hedef: Nihai çıkışın yer aldığı ve yürütüldüğü platformdur.

Bazel, platformlarla ilgili olarak 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.

  • Derlemeler arası derlemeler: Ana makine ve yürütme platformları aynıdır ancak hedef platform farklıdır. Örneğin, macOS'te MacBook Pro üzerinde bir iOS uygulaması derleyebiliriz.

  • Ç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ında 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, 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 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ı paketler genelinde tanımlanabilir. Bunlara etiket tarafından 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çenekleriyle yeni bir platform sunar. Aşağıdaki komut linux_x86 adında bir platform oluşturur ve bu platformun, 2.25 glibc sürümüne sahip x86_64 mimarisi üzerinde Linux işletim sistemi çalıştıran tüm ortamları tanımladığı belirtilmektedir. (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ılığını sağlamak amacıyla Bazel ekibi, en popüler CPU mimarileri ve işletim sistemleri için kısıtlı tanımlar içeren bir depoya sahip. Bunların hepsi https://github.com/bazelbuild/platforms adresinde bulunmaktadır.

Bazel şu ö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 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 dizi sunan @local_config_platform//:constraintz.bzl oluşturur.
  • --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 değil --host_platform ayarlanırsa --host_platform değeri hem ana makine hem de hedef platformdur.

Uyumlu olmayan 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 bir Linux makinesinde geliştirme yaparken muhtemelen çok fazla derleyici hatası oluşturur. Bazel'a kodunuzda hangi hedef platform kısıtlamaları 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. Tüm kısıtlamaları karşılamayan hiçbir platform için hedef oluşturulmaz. Aşağıdaki örnekte win_driver_lib.cc sürümü 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 sürümleriyle uyumludur ve diğer sürümlerle uyumlu değildir. Uyumsuzluk geçişlidir. Geçişli olarak uyumsuz bir hedefe bağlı olan tüm hedefler uyumsuz olarak kabul edilir.

Hedefler ne zaman atlanır?

Uyumsuz oldukları kabul edilen hedefler atlanır ve hedef kalıp genişletmesi kapsamında derlemeye dahil edilir. Örneğin, aşağıdaki iki çağrı, hedef kalıp genişletmesinde bulunan 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 test_suite belirtilirse benzer şekilde atlanır. Başka 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 açıkça uyumsuz bir hedef belirlemek, 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 etkinleştirilirse uyumsuz uygunsuz hedefler sessizce atlanır.

Daha fazla ifade gücü

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

Daha karmaşık kısıtlamaları ifade etmek için select() ile @platforms//:incompatible birlikte 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 olmayan bir kitaplıktır.

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 aşağıdaki gibi yorumlanabilir:

  1. macOS hedeflenirken hedefte kısıtlama bulunmaz.
  2. Linux'u hedeflerken hedefte kısıtlama yoktur.
  3. Aksi takdirde, hedef @platforms//:incompatible kısıtlamasına sahip olur. @platforms//:incompatible herhangi bir platformun parçası olmadığı için hedef uyumsuz olarak değerlendirilir.

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

Ters uyumluluğu benzer bir şekilde ifade edebilirsiniz. Aşağıdaki örnekte, ARM haricindeki her şeyle uyumlu bir kitaplık gösterilmektedir.

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 uyumlu olmayan hedefler algılanıyor

Uyumsuz hedefleri uyumlu hedeflerden ayırt etmek için bazel cquery öğesinin Starlark çıkış biçiminde IncompatiblePlatformProvider öğesini kullanabilirsiniz.

Bu, uyumlu olmayan hedefleri filtrelemek için kullanılabilir. Aşağıdaki örnekte yalnızca uyumlu hedeflere ait etiketler 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.