Platformlara Geçiş

Sorun bildir Kaynağı göster

Bazel, çok mimarili ve çapraz derlenmiş derlemeler için platformları ve araç zincirlerini modelleme konusunda gelişmiş desteğe sahiptir.

Bu sayfada, bu desteğin durumu özetlenmektedir.

Şuna da bakabilirsiniz:

Durum

C++

C++ kuralları, --incompatible_enable_cc_toolchain_resolution ayarlandığında araç zincirlerini seçmek için platformları kullanır.

Bu, bir C++ projesini şunlarla yapılandırabileceğiniz anlamına gelir:

bazel build //:my_cpp_project --platforms=//:myplatform

eski yerine:

bazel build //:my_cpp_project` --cpu=... --crosstool_top=...  --compiler=...

Bu, Bazel 7.0'da varsayılan olarak etkinleştirilir (#7260).

C++ projenizi platformlarla test etmek için Projenizi Taşıma ve C++ araç zincirlerini yapılandırma bölümlerine bakın.

Java

Java kuralları, araç zincirlerini seçmek için platformları kullanır.

Bu özellik, eski --java_toolchain, --host_java_toolchain, --javabase ve --host_javabase işaretlerinin yerini alır.

Ayrıntılar için Java ve Bazel'e bakın.

Android

Android kuralları, --incompatible_enable_android_toolchain_resolution ayarlandığında araç zincirlerini seçmek için platformları kullanır.

Bu sayede bir Android projesini şunlarla yapılandırabilirsiniz:

bazel build //:my_android_project --android_platforms=//:my_android_platform

(--android_crosstool_top, --android_cpu ve --fat_apk_cpu gibi eski işaretler yerine) kullanabilirsiniz.

Bu, Bazel 7.0'da varsayılan olarak etkinleştirilir (#16285).

Android projenizi platformlarla test etmek için Projenizi Taşıma sayfasını inceleyin.

elma

Apple kuralları platformları desteklemez ve henüz desteklenmek üzere planlanmamıştır.

Platform API'lerini Apple derlemeleriyle kullanmaya devam edebilirsiniz (örneğin, Apple kuralları ve tamamen C++ ile derleme yaparken) platform eşlemeleriyle yine de kullanabilirsiniz.

Diğer diller

Bir dil kuralı grubunuz varsa destek eklemek için Kural grubunuzu taşıma başlıklı makaleyi inceleyin.

Arka plan

Platformlar ve araç zincirleri, yazılım projelerinin farklı mimarileri hedefleme ve çapraz derleme yapma şeklini standartlaştırmak için kullanıma sunulmuştur.

Bu da, dil yöneticilerinin bunu anlık, uyumsuz yollarla zaten yaptığı gözleminden ilham vermiştir. Örneğin, C++ kuralları bir hedef CPU ve araç zinciri tanımlamak için --cpu ve --crosstool_top kullanmıştır. Bunların hiçbiri bir "platform"u doğru modellemez. Bu garip ve yanlış derlemelere neden oldu.

Java, Android ve diğer diller benzer amaçlar için kendi bayraklarını geliştirdi ve bu bayrakların hiçbiri birbiriyle birlikte çalıştı. Bu da diller arası derlemeleri kafa karıştırıcı ve karmaşık hale getiriyordu.

Bazel, çok dilli, büyük projeler için tasarlanmıştır. Bu, bu kavramların daha prensiplerle desteklenmesini ve net bir standart API'yi gerektiriyor.

Taşıma gerekli

Yeni API'ye yükseltmek için iki işlem yapmanız gerekir: API'yi yayınlamak ve kullanmak için kural mantığını yükseltmek.

İlki tamamlandı, ancak ikincisi devam ediyor. Dile özgü platformların ve araç zincirlerinin tanımlanmasını, dil mantığının --crosstool_top gibi eski işaretler yerine yeni API aracılığıyla araç zincirlerini okumasını ve config_setting öğelerinin eski işaretler yerine yeni API'yi seçmesini sağlamak buna dahildir.

Bu çalışma basittir ancak her dilde ayrı bir çaba sarf edilmesini gerektirir ve proje sahiplerine yapılacak değişikliklere karşı testler yapmaları için uyarı verilir.

Bu nedenle söz konusu geçiş süreci devam ediyor.

Hedef

Tüm projeler şu formla derlendiğinde bu taşıma işlemi tamamlanır:

bazel build //:myproject --platforms=//:myplatform

Bu durum, şu anlama gelir:

  1. Projenizin kuralları, //:myplatform için doğru araç zincirlerini seçer.
  2. Projenizin bağımlılıkları //:myplatform için doğru araç zincirlerini seçiyor.
  3. //:myplatform, CPU, OS ve diğer genel, dilden bağımsız özelliklerin yaygın bildirimlerine referans veriyor
  4. Tüm ilgili select() öğeleri //:myplatform ile düzgün şekilde eşleşiyor.
  5. //:myplatform, açık ve erişilebilir bir yerde tanımlanır: Platform projenize özelse projenizin deposunda veya tüm tüketen projelerin bulabileceği ortak bir yerse

--cpu, --crosstool_top ve --fat_apk_cpu gibi eski işaretler güvenli olur olmaz kullanımdan kaldırılacak ve kaldırılacaktır.

Sonuç olarak, mimarileri yapılandırmanın tek yolu bu olacaktır.

Projenizi taşıma

Platformları destekleyen dillerle derleme yapıyorsanız derlemeniz zaten aşağıdaki gibi bir çağrı ile çalışır:

bazel build //:myproject --platforms=//:myplatform

Ayrıntılı bilgi için Durum'a ve dilinize ait dokümanlara bakın.

Bir dil, platform desteğini etkinleştirmek için işaret gerektiriyorsa bu işareti de ayarlamanız gerekir. Ayrıntılar için Durum bölümüne bakın.

Projenizin oluşturulması için aşağıdakileri kontrol etmeniz gerekir:

  1. //:myplatform mevcut olmalıdır. Farklı projeler farklı makineleri hedeflediğinden platformları tanımlamak genellikle proje sahibinin sorumluluğundadır. Varsayılan platformlar bölümüne bakın.

  2. Kullanmak istediğiniz araç zincirleri bulunmalıdır. Stok araç zincirleri kullanılıyorsa dil sahipleri, araç zincirlerini nasıl kaydedeceklerine dair talimatlara yer vermelidir. Kendi özel araç zincirlerinizi yazıyorsanız bunları WORKSPACE veya --extra_toolchains üzerinden register gerekir.

  3. select()'ler ve yapılandırma geçişleri doğru şekilde çözümlenmelidir. select() ve Geçişler konularına bakın.

  4. Derlemeniz, platformları destekleyen ve desteklemeyen dilleri bir araya getiriyorsa eski dillerin yeni API ile çalışmasına yardımcı olacak platform eşlemelerine ihtiyacınız olabilir. Ayrıntılar için Platform eşlemeleri bölümüne bakın.

Hâlâ sorun yaşıyorsanız destek için bize ulaşın.

Varsayılan platformlar

Proje sahipleri, derlemek istedikleri mimarileri açıklamak için açık platformlar tanımlamalıdır. Bunlar daha sonra --platforms ile tetiklenir.

--platforms ayarlanmadığında Bazel varsayılan olarak yerel derleme makinesini temsil eden bir platform olur. Bu parametre, @local_config_platform//:host konumunda otomatik olarak oluşturulur. Bu nedenle, açıkça tanımlamaya gerek yoktur. Yerel makinenin OS ve CPU değerlerini @platforms içinde tanımlanan constraint_value ile eşler.

select()

Projeler constraint_value hedeflerinde select() içerebilir ancak platformlarda tamamını tamamlayamaz. Bu kasıtlı olarak yapılır. Böylece select() mümkün olduğunca çeşitli makineleri destekler. ARM özelliğine özel kaynaklara sahip bir kitaplık, daha belirgin olmak için bir neden olmadığı sürece ARM destekli tüm makineleri desteklemelidir.

Bir veya daha fazla constraint_value seçmek için şunları kullanın:

config_setting(
    name = "is_arm",
    constraint_values = [
        "@platforms//cpu:arm",
    ],
)

Bu, --cpu ürününde geleneksel olarak seçim yapmaya eşdeğerdir:

config_setting(
    name = "is_arm",
    values = {
        "cpu": "arm",
    },
)

Ayrıntılı bilgiyi burada bulabilirsiniz.

--cpu, --crosstool_top vb. üzerindeki selectler --platforms dilini anlamıyor. Projenizi platformlara taşırken bunları constraint_values biçimine dönüştürmeniz veya taşıma sırasında her iki stili de desteklemek için platform eşlemelerini kullanmanız gerekir.

Geçişler

Starlark geçişleri değişiklikleri, yapı grafiğinizin bazı bölümlerini işaretler. Projeniz --cpu, --crossstool_top veya diğer eski işaretleri ayarlayan bir geçiş kullanıyorsa --platforms yönergesini okuyan kurallar bu değişiklikleri görmez.

Projenizi platformlara taşırken return { "//command_line_option:cpu": "arm" } gibi değişiklikleri return { "//command_line_option:platforms": "//:my_arm_platform" } biçimine dönüştürmeniz veya taşıma sırasında her iki stili de desteklemek için platform eşlemelerini kullanmanız gerekir.

Kural grubunuz taşınıyor

Bir kural grubunuz varsa ve platformları desteklemek istiyorsanız şunları yapmanız gerekir:

  1. Araç zinciri API'si ile kural mantığının araç zincirlerini çözmesini sağlayın. Toolchain API'yi (ctx.toolchains) inceleyin.

  2. İsteğe bağlı: Taşıma testi sırasında kural mantığının, araç zincirlerini yeni API veya --crosstool_top gibi eski işaretler aracılığıyla alternatif olarak çözebilmesi için bir --incompatible_enable_platforms_for_my_language işareti tanımlayın.

  3. Platform bileşenlerini oluşturan ilgili özellikleri tanımlayın. Yaygın platform özellikleri bölümünü inceleyin

  4. Standart araç zincirleri tanımlayın ve kuralınızın kayıt talimatları aracılığıyla kullanıcıların bunlara erişebilmesini sağlayın (ayrıntılar)

  5. select() ve yapılandırma geçişlerinin platformları desteklediğinden emin olun. En büyük zorluk bu. Bu, özellikle çok dilli projeler için zordur (tüm diller --platforms okuyamazsa bu başarısız olabilir).

Platformları desteklemeyen kurallarla karıştırmanız gerekiyorsa boşluğu kapatmak için platform eşlemelerine ihtiyacınız olabilir.

Yaygın platform özellikleri

OS ve CPU gibi diller arası yaygın platform özellikleri @platforms içinde beyan edilmelidir. Bu; paylaşımı, standartlaştırmayı ve diller arası uyumluluğu teşvik eder.

Kurallarınıza benzersiz özellikler, kuralınızın deposunda bildirilmelidir. Bu sayede, kurallarınızın sorumlu olduğu belirli kavramlar üzerinde net bir sahiplik sahibi olabilirsiniz.

Kurallarınız özel amaçlı işletim sistemleri veya CPU'lar kullanıyorsa bunlar, @platforms yerine kuralınızın deposunda bildirilmelidir.

Platform eşlemeleri

Platform eşlemeleri, platforma duyarlı mantığın aynı derlemedeki eski mantıkla birleştirilmesini sağlayan geçici bir API'dir. Bu yalnızca farklı taşıma zaman aralıklarındaki uyumsuzlukları gidermeyi amaçlayan sade bir araçtır.

Platform eşlemesi, platform() öğesinin karşılık gelen eski işaret grubuyla eşlenmesi veya tam tersinin eşlenmesidir. Örneğin:

platforms:
  # Maps "--platforms=//platforms:ios" to "--cpu=ios_x86_64 --apple_platform_type=ios".
  //platforms:ios
    --cpu=ios_x86_64
    --apple_platform_type=ios

flags:
  # Maps "--cpu=ios_x86_64 --apple_platform_type=ios" to "--platforms=//platforms:ios".
  --cpu=ios_x86_64
  --apple_platform_type=ios
    //platforms:ios

  # Maps "--cpu=darwin_x86_64 --apple_platform_type=macos" to "//platform:macos".
  --cpu=darwin_x86_64
  --apple_platform_type=macos
    //platforms:macos

Bazel, hem platform tabanlı hem de eski tüm ayarların, geçişler de dahil olmak üzere derleme boyunca tutarlı bir şekilde uygulanmasını garanti etmek için bunu kullanır.

Varsayılan olarak Bazel, çalışma alanı kök dizininizdeki platform_mappings dosyasındaki eşlemeleri okur. Ayrıca şunu da ayarlayabilirsiniz: --platform_mappings=//:my_custom_mapping.

Ayrıntılar için platform eşlemeleri tasarımını inceleyin.

API incelemesi

platform, constraint_value hedeften oluşan bir koleksiyondur:

platform(
    name = "myplatform",
    constraint_values = [
        "@platforms//os:linux",
        "@platforms//cpu:arm",
    ],
)

constraint_value bir makine özelliğidir. Aynı "tür"e ait değerler ortak bir constraint_setting altında gruplandırılır:

constraint_setting(name = "os")
constraint_value(
    name = "linux",
    constraint_setting = ":os",
)
constraint_value(
    name = "mac",
    constraint_setting = ":os",
)

toolchain bir Starlark kuralıdır. Özellikleri, dilin araçlarını (compiler = "//mytoolchain:custom_gcc" gibi) tanımlar. Özelliğin sağlayıcıları, bu bilgileri bu araçlarla oluşturulması gereken kurallara iletir.

Araç zincirleri, hedefleyebilecekleri (target_compatible_with = ["@platforms//os:linux"]) ve araçlarının çalışabileceği (exec_compatible_with = ["@platforms//os:mac"]) makinelerin constraint_value sayısını tanımlar.

Bazel, $ bazel build //:myproject --platforms=//:myplatform derlerken otomatik olarak derleme makinesinde çalışabilecek ve //:myplatform için ikili programlar oluşturabilecek bir araç zinciri seçer. Bu, araç zinciri çözünürlüğü olarak bilinir.

Kullanılabilir araç zincirleri grubu, WORKSPACE içinde register_toolchains ile veya komut satırında --extra_toolchains ile kaydedilebilir.

Daha fazla bilgiyi burada bulabilirsiniz.

Sorular

Genel destek almak ve taşıma zaman çizelgesiyle ilgili sorularınız için bazel-speak veya uygun kuralların sahipleriyle iletişime geçin.

Platform/araç zinciri API'lerinin tasarımı ve gelişimiyle ilgili tartışmalar için bazel-dev ile iletişime geçin.

Aşağıdaki kaynakları da incelemenizi öneririz: