Platformlarla Geliştirme

Sorun bildirin Kaynağı göster

Bazel, platform ve araç zincirlerini modellemek için gelişmiş bir desteğe sahiptir. Bunun gerçek projelerle entegre edilmesi için kod sahipleri, kural sorumluları ve temel Bazel geliştiricileri arasında dikkatli bir iş birliği gerekir.

Bu sayfada, platformların amacı özetlenmekte ve platformlarla nasıl geliştirme yapılacağı gösterilmektedir.

tl;dr: Bazel'in platformu ve araç zinciri API'leri kullanılabilir ancak tüm dil kuralları, select()'ler ve diğer eski referanslar güncellenene kadar her yerde çalışmaz. Bu çalışmalar sürekli devam ediyor. Bu sürecin sonunda tüm derlemeler platform tabanlı olacak. Derlemelerinizin nereye denk geldiğini görmek için aşağıdaki bölümü okuyun.

Daha resmi belgeler için bkz:

Arka plan

Yazılım projelerinin farklı makineleri hedeflemesini ve doğru dil araçlarıyla derleme şeklini standartlaştırmak için platformlar ve araç zincirleri kullanıma sunuldu.

Bu, Bazel'e nispeten yeni bir yeniliktir. Dil sorumlularının zaten bunu anlık ve uyumsuz şekillerde yaptığı gözlemi bu duruma ilham verdi. Örneğin, C++ kuralları bir derlemenin hedef CPU ve C++ araç zincirini ayarlamak için --cpu ve --crosstool_top kullanır. Bunların ikisi de bir "platform" modellemez. Tarihi buna yönelik girişimler tuhaf ve yanlış yapılara neden oldu. Bu işaretler, --java_toolchain ile kendi bağımsız arayüzünü geliştiren Java derlemesini de kontrol etmez.

Bazel büyük, çok dilli ve çok platformlu projeler için tasarlanmıştır. Bu doğrultuda, dil ve projenin birlikte çalışabilirliğini teşvik eden net API'ler dahil olmak üzere bu kavramlar için daha ilkeli destek gerekir. Bu yeni API'lerin amacı da bu.

Taşıma

Platform ve araç zinciri API'leri yalnızca projeler gerçekten bunları kullandığında çalışır. Bu önemsiz değildir çünkü projenin kural mantığı, araç zincirleri, bağımlılıkları ve select()'ları bunları desteklemelidir. Bu, tüm projelerin ve bağımlılıklarının doğru şekilde çalışmaya devam edebilmesi için dikkatli bir taşıma sırası gerektirir.

Örneğin, Bazel'in C++ Kuralları, platformları destekler. Ancak Apple Kuralları öyle değildir. C++ projeniz Apple'ı önemsemiyor olabilir. Diğerleri de olabilir. Bu nedenle, platformları tüm C++ derlemeleri için küresel olarak etkinleştirmek henüz güvenli değildir.

Bu sayfanın geri kalanında, söz konusu taşıma sırası ve projelerinizin nasıl ve ne zaman sığabileceği açıklanmaktadır.

Hedef

Tüm projeler şu formla derlendiğinde Bazel'in platform taşıma işlemi tamamlanır:

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

Bu anlama gelir:

  1. Projenizin kullandığı kurallar, //:myplatform öğesinden doğru araç zincirlerini çıkarabilir.
  2. Projenizin bağımlılıklarının kullandığı kurallar, //:myplatform öğesinden doğru araç zincirlerini tahmin edebilir.
  3. Ya sizinkine bağlı projeler //:myplatform ya da projenizde eski API'ler (--crosstool_top gibi) destekleniyor.
  4. //:myplatform, projeler arası otomatik uyumluluğu destekleyen CPU, OS ve diğer genel kavramlara ait [ortak bildirimler][Ortak Platform Bildirimi]{: .external} referansını gösteriyor.
  5. Alakalı tüm projelerin select()'leri, //:myplatform tarafından belirtilen makine özelliklerini anlar.
  6. //:myplatform, net ve yeniden kullanılabilir bir yerde tanımlanır. Platform projenize özgüyse projenizin deposunda, aksi takdirde bu platformu kullanabilecek tüm projelerin bir yerde bulabileceği bir yerde tanımlanır.

Bu hedefe ulaşılır edilmez eski API'ler kaldırılacaktır. Platform ve araç zincirleri projelerinde standart olarak bu şekilde seçilir.

Platformları kullanmalı mıyım?

Sadece proje oluşturmak ya da çapraz derlemek istiyorsanız projenin resmi belgelerine uymanız gerekir.

Proje, dil veya araç zinciri bakım sorumlusuysanız zaman içinde yeni API'leri desteklemek isteyebilirsiniz. Genel geçişin tamamlanmasını beklemeyi veya geçiş işlemini erkenden etkinleştirme, özel değer / maliyet ihtiyaçlarınıza bağlıdır:

Değer

  • --cpu gibi sabit kodlu işaretler yerine tam olarak ilgilendiğiniz mülklerde select() özelliğini kullanabilir veya araç zincirlerini seçebilirsiniz. Örneğin, birden fazla CPU aynı talimat grubunu destekleyebilir.
  • Daha doğru derlemeler. Yukarıdaki örnekte --cpu için select() işlemi gerçekleştirirseniz aynı talimat grubunu destekleyen yeni bir CPU eklerseniz select() yeni CPU'yu tanıyamaz. Ancak platformlardaki select() metriği doğru olmaya devam ediyor.
  • Daha basit kullanıcı deneyimi. Tüm projeler aşağıdaki hususları anlar: --platforms=//:myplatform. Komut satırında birden fazla dile özgü işaretlere gerek yoktur.
  • Daha basit dil tasarımı. Tüm dillerde araç zincirlerini tanımlamak, araç zincirlerini kullanmak ve platform için doğru araç zincirini seçmek için ortak bir API kullanılır.
  • Hedef platformla uyumlu olmayan hedefler, derleme ve test aşamasında atlanabilir.

Maliyetler

  • Henüz platformları desteklemeyen bağımlı projeler sizin projenizle otomatik olarak çalışmayabilir.
  • Cihazların çalışması için ek geçici bakım gerekebilir.
  • Yeni ve eski API'lerin birlikte var olması, karışıklığı önlemek için daha dikkatli bir kullanıcı rehberliği gerektirir.
  • OS ve CPU gibi yaygın özelliklerin standart tanımları gelişmeye devam ettiği için başlangıçda ekstra katkı yapılması gerekebilir.
  • Dile özgü araç zincirlerine yönelik standart tanımlar hâlâ gelişme aşamasında olduğundan başlangıç aşamasında ekstra katkılar gerekebilir.

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ün" değerleri 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, bir dilin araçlarını (compiler = "//mytoolchain:custom_gcc" gibi) bildirir. Aracın sağlayıcıları bu bilgileri, bu araçlarla derlemesi gereken kurallara iletir.

Araç zincirleri, hedefleyebilecekleri (target_compatible_with = ["@platforms//os:linux"]) makinelerin constraint_value'larını ve araçlarının çalabileceği (exec_compatible_with = ["@platforms//os:mac"]) makineleri belirtir.

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

Mevcut araç zincirleri grubu, WORKSPACE bölümüne register_toolchains ile veya komut satırına --extra_toolchains ile kaydedilebilir.

Daha ayrıntılı bilgi için buraya göz atın.

Durum

Mevcut platform desteği diller arasında değişiklik gösterir. Bazel'ın tüm önemli kuralları platformlara taşınıyor. Ancak bu işlem zaman alır. Bunun üç ana nedeni vardır:

  1. Yeni araç zinciri API'sinden (ctx.toolchains) araç bilgilerini almak ve --cpu ile --crosstool_top gibi eski ayarları okumayı durdurmak için kural mantığının güncellenmesi gerekir. Bu nispeten basittir.

  2. Araç zinciri sorumluları, araç zincirlerini tanımlamalı ve kullanıcılar için erişilebilir hale getirmelidir (GitHub depolarında ve WORKSPACE girişlerinde). Bu, teknik olarak basittir ancak kolay bir kullanıcı deneyimi sağlamak için akıllı bir şekilde organize edilmesi gerekir.

    Platform tanımları da gereklidir (Bazel'in çalıştığı makine için derleme yapmadığınız sürece). Genel olarak projeler kendi platformlarını tanımlamalıdır.

  3. Mevcut projeler taşınmalıdır. select() ve geçişlerin de taşınması gerekir. En büyük zorluk bu. Bu, özellikle çok dilli projeler için zordur (tüm diller --platforms okunamıyorsa bu işlem başarısız olabilir).

Yeni bir kural grubu tasarlıyorsanız platformları başından itibaren desteklemeniz gerekir. Bu, kurallarınızı otomatik olarak diğer kural ve projelerle uyumlu hale getirir ve platform API'si daha yaygın hale geldikçe değeri artırır.

Sık kullanılan platform özellikleri

Projelerde ortak olan OS ve CPU gibi platform özellikleri standart ve merkezi bir yerde tanımlanmalıdır. Bu, projeler arası ve diller arası uyumluluğu teşvik eder.

Örneğin, MyApp'da constraint_value @myapp//cpus:arm için bir select() varsa ve MyApp'de select() varsa @commonlib//constraints:arm bunlar "arm" modlarını uyumsuz ölçütlerle tetikler.

Genel olarak yaygın özellikler @platforms deposunda tanımlanır (yani yukarıdaki örnek için standart etiket @platforms//cpu:arm şeklindedir). Dilde yaygın özellikler, ilgili dillerin depolarında bildirilmelidir.

Varsayılan platformlar

Genel olarak proje sahipleri, derlemek istedikleri makine türlerini tanımlamak 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 değerini alır. Bu değer, @local_config_platform//:host konumunda otomatik olarak oluşturulduğundan açıkça tanımlamaya gerek yoktur. Yerel makinenin OS ve CPU öğelerini @platforms içinde tanımlanan constraint_value'lerle eşler.

C++

Bazel'in C++ kuralları, aşağıdakileri ayarladığınızda araç zincirlerini seçmek için platformları kullanır: --incompatible_enable_cc_toolchain_resolution (#7260).

Bu, bir C++ projesini aşağıdaki öğelerle yapılandırabileceğiniz anlamına gelir:

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

yeni bir sürüm oluşturun:

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

Projeniz tamamen C++ ise ve C++ dışı projelere dayanmıyorsa select ve geçişleriniz uyumlu olduğu sürece platformları güvenli bir şekilde kullanabilirsiniz. Daha fazla yardım için #7260 ve C++ araç zincirlerini yapılandırma bölümlerine bakın.

Bu mod varsayılan olarak etkin değildir. Bunun nedeni, Apple projelerinin C++ bağımlılıklarını --cpu ve --crosstool_top ile yapılandırmaya devam etmesidir (örnek). Bu, platformlara geçiş yapan Apple kurallarına bağlıdır.

Java

Bazel'in Java kuralları platformları kullanır.

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

Yapılandırma işaretlerinin nasıl kullanılacağını öğrenmek için Bazel ve Java kılavuzuna bakın. Ek bilgi için Tasarım belgesine bakın.

Eski işaretleri kullanmaya devam ediyorsanız Sorun #7849'da belirtilen taşıma işlemini uygulayın.

Android

Bazel'in Android kuralları, --incompatible_enable_android_toolchain_resolution özelliğini ayarladığınızda araç zincirlerini seçmek için platformları kullanır.

Bu özellik, varsayılan olarak etkin değildir. Ancak taşıma devam ediyor.

elma

Bazel'in Apple kuralları, Apple araç zincirlerini seçmek için platformları henüz desteklememektedir.

Ayrıca, C++ araç zincirini ayarlamak için eski --crosstool_top kullandığı için platform özellikli C++ bağımlılıklarını da desteklemezler. Bu özellik taşınana kadar, Apple projelerini platorm özellikli C++ ile platform eşlemeleri ile birlikte kullanabilirsiniz (örnek).

Diğer diller

Yeni bir dil için kurallar tasarlıyorsanız dilinizin araç zincirlerini seçmek için platformları kullanın. Adım adım açıklamalı iyi bir kılavuz için araç zinciri belgelerini inceleyin.

select()

Projeler constraint_value hedefler üzerinde select() işlemi gerçekleştirebilir ancak platformları tamamlayamaz. Bu işlem, select()'ların mümkün olduğunca çok çeşitli makineleri desteklemesi için bilerek yapılır. ARM'a özgü kaynaklara sahip bir kitaplık, daha ayrıntılı olması için bir neden olmadığı sürece tüm ARM destekli makineleri desteklemelidir.

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

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

Bu, geleneksel olarak --cpu uygulamasında seçim yapmaya eşdeğerdir:

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

Daha fazla bilgiyi burada bulabilirsiniz.

--cpu, --crosstool_top vb. üzerindeki select'lar --platforms anlaşılmıyor. Projenizi platformlara taşırken bunları constraint_values'e dönüştürmeniz veya taşıma penceresi boyunca her iki stili de desteklemek için platform eşlemelerini kullanmanız gerekir.

Geçişler

Starlark geçişleri, derleme grafiğinizin bazı kısımlarını değiştirir. Projenizde --cpu, --crossstool_top veya diğer eski işaretleri ayarlayan bir geçiş kullanılıyorsa --platforms yazan 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 penceresi boyunca her iki stili de desteklemek için platform eşlemelerini kullanmanız gerekir.

Günümüzde platformlar nasıl kullanılır?

Sadece proje oluşturmak ya da çapraz derlemek istiyorsanız projenin resmi belgelerine uymanız gerekir. Platformlarla nasıl ve ne zaman entegrasyon yapılacağını ve bunun ne gibi bir değer sunacağını belirlemek, dil ve proje sorumlularına bağlıdır.

Proje, dil veya araç zinciri bakım sorumlusuysanız ve derlemeniz varsayılan olarak platformları kullanmıyorsa üç seçeneğiniz vardır (global taşıma işlemini beklemenin yanı sıra):

  1. Projenizin dilleri için "platformları kullan" işaretini (varsa) kullanın ve sizin için önemli olan projelerin işe yarayıp yaramadığını görmek için ihtiyacınız olan her şeyi yapın.

  2. Sizin için önemli olan projeler hâlâ --cpu ve --crosstool_top gibi eski flag'lere bağlıysa bunları --platforms ile birlikte kullanın:

    bazel build //:my_mixed_project --platforms==//:myplatform --cpu=... --crosstool_top=...
    

    Bunun bir miktar bakım maliyeti vardır (ayarların eşleştiğinden manuel olarak emin olmanız gerekir). Ancak geri geçişlerin yapılmadığı durumlarda bu yöntem işe yarayacaktır.

  3. --cpu stili ayarları ilgili platformlarla (veya tam tersi) eşleyerek her iki stili de desteklemek için platform eşlemeleri yazın.

Platform eşlemeleri

Platform eşlemeleri, platform destekli ve eski destekli mantığın kullanımdan kaldırma dönemi boyunca aynı derlemede bir arada var olmasını sağlayan geçici bir API'dir.

Platform eşlemesi, platform() öğesinin karşılık gelen bir eski işaret grubuna veya tersine eşlemedir. Ö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 --apple_platform_type=macos" to "//platform:macos".
  --cpu=darwin
  --apple_platform_type=macos
    //platforms:macos

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

Varsayılan olarak Bazel, çalışma alanı kökünüzdeki platform_mappings dosyasından eşlemeleri okur. Ayrıca --platform_mappings=//:my_custom_mapping değerini de ayarlayabilirsiniz.

Tüm ayrıntıları burada bulabilirsiniz.

Sorular

Genel destek almak ve taşıma zaman çizelgesiyle ilgili sorularınız için bazel-discuss@googlegroups.com adresiyle veya ilgili kuralların sahipleriyle iletişime geçebilirsiniz.

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

Şunlara da bakabilirsiniz: