Platformlarla Geliştirme

Bazel, platformları ve araç zincirlerini modelleme için gelişmiş destek sunar. Bunu gerçek projelerle entegre etmek için kod sahipleri, kural koruyucuları ve temel Bazel geliştiricileri arasında dikkatli bir işbirliği gerekir.

Bu sayfada, platformların amacı özetlenmiş ve bu platformlarla nasıl uygulama geliştirileceği gösterilmiştir.

Özet: Bazel'in platform 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 uyduğunu öğrenmek için aşağıdaki bölümü okuyun.

Daha resmi belgeler için bkz:

Arka plan

Platformlar ve araç zincirleri, yazılım projelerinin farklı makineleri hedefleme ve doğru dil araçlarıyla derleme şeklini standartlaştırmak için kullanıma sunulmuştur.

Bu, Bazel'e nispeten yeni bir yeniliktir. Bu proje, dil koruyucuların zaten bu işlemi gelişigüzel ve uyumsuz yöntemlerle yaptığı gözleminden ilham almıştır. Ö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. Geçmişte bu tür girişimler, garip ve yanlış derlemelere 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, ç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'ler tam da bu amaçla geliştirilmiştir.

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 nedenle, tüm projelerin ve bağımlılıkların düzgün şekilde çalışmasını sağlamak için dikkatli bir taşıma sırası gerekir.

Örneğin, Bazel'in C++ Kuralları platformları destekler. Ancak Apple kuralları bunu yapmaz. C++ projeniz Apple'ı dikkate almıyor olabilir. Ancak bazı platformlar bu durumdan etkilenmeyebilir. Bu nedenle, tüm C++ derlemeleri için platformları dünya genelinde 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, aşağıdakileri ifade eder:

  1. Projenizin kullandığı kurallar, //:myplatform'ten 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 size bağlı projeler //:myplatform'i destekliyor ya projeniz eski API'leri (--crosstool_top gibi) destekliyor.
  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. İlgili tüm projelerin select()'ları, //:myplatform tarafından ima edilen 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şıldığı anda eski API'ler kaldırılacaktır. Bu durumda, projeler platform ve araç zinciri seçerken standart olarak bu yöntemi kullanacaktır.

Platformları kullanmalı mıyım?

Yalnızca bir projeyi derlemek veya çapraz derlemek istiyorsanız projenin resmi dokümanlarını incelemeniz 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 mi yoksa erkenden kaydolmayı mı tercih edeceğiniz, ö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ç zincirleri 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 platformlarda select() doğru olmaya devam eder.
  • Daha basit kullanıcı deneyimi. Tüm projeler: --platforms=//:myplatform Komut satırında dile özgü birden fazla işarete gerek yoktur.
  • Daha basit dil tasarımı. Tüm diller, araç zincirlerini tanımlamak, araç zincirlerini kullanmak ve bir platform için doğru araç zincirini seçmek üzere ortak bir API'yi paylaşır.
  • Hedef platformla uyumlu olmayan hedefler, derleme ve test aşamasında atlanabilir.

Maliyetler

  • Henüz platformları desteklemeyen bağımlı projeler, sizinle otomatik olarak çalışmayabilir.
  • Cihazların çalışması için ek geçici bakım gerekebilir.
  • Yeni ve eski API'lerin birlikte kullanılması, karışıklığın önüne geçmek için daha dikkatli kullanıcı rehberliği gerektirir.
  • OS ve CPU gibi ortak mülkler için standart tanımlar hâlâ gelişiyor ve ilk aşamada ek katkılar gerekebilir.
  • Dile özgü araç zincirlerinin standart tanımları hâlâ gelişme aşamasındadır ve bu tanımlar için önceden ekstra katkı gerekebilir.

API incelemesi

platform, constraint_value hedeften oluşan bir koleksiyondur:

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

constraint_value, makine mülküdür. Aynı "tür"deki 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, Starlark kuralı'dır. Özellikleri, bir dilin araçlarını (compiler = "//mytoolchain:custom_gcc" gibi) bildirir. 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.

Kullanılabilir 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 yöneticileri, araç zincirlerini tanımlamalı ve kullanıcıların erişimine açmalıdır (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). Genellikle 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ştan desteklemeniz gerekir. Bu sayede, platform API'si daha yaygın hale geldikçe kurallarınız otomatik olarak diğer kurallar ve projelerle uyumlu hale gelir ve değer kazanır.

Sık kullanılan platform özellikleri

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

Örneğin, Uygulamam'da constraint_value üzerinde @myapp//cpus:arm ve OrtakKitaplığım'da @commonlib//constraints:arm üzerinde birer select() varsa bu uygulamalar, "etkinleştir" 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, @local_config_platform//:host konumunda otomatik olarak oluşturulur. Bu nedenle, açıkça tanımlamanız gerekmez. 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 bilgi için #7260 ve C++ araç zincirlerini yapılandırma başlıklı makaleyi inceleyin.

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 nedenle, platformlara taşınan 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. Daha fazla bilgi için Tasarım dokümanı'na bakın.

Eski işaretleri kullanmaya devam ediyorsanız 7849 numaralı sorun bölümündeki taşıma sürecini uygulayın.

Yapay Zeka

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ı, henüz Apple araç zincirlerini seçmek için platformları desteklemiyor.

Ayrıca, C++ araç zincirini ayarlamak için eski --crosstool_top sürümünü kullandıkları için platform tarafından etkinleştirilen C++ bağımlılıkları da desteklenmez. 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 üzere platformları kullanın. Adım adım açıklamalı iyi bir kılavuz için araç zinciri belgelerini inceleyin.

select()

Projeler constraint_value hedeflerinde select() olabilir ancak platformları tamamlayamaz. Bu, select()'lerin mümkün olduğunca çok sayıda makineyi desteklemesi için tasarlanmıştır. ARM'ye özel kaynaklar içeren bir kitaplık, daha ayrıntılı bir açıklamaya gerek 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'te seçim yapmanıza eşdeğerdir:

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

Daha fazla bilgiyi burada bulabilirsiniz.

--cpu, --crosstool_top vb. cihazlardaki select'ler --platforms'ı anlamı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 işaretli bölümlerini değiştirir. Projenizde --cpu, --crossstool_top veya diğer eski işaretleri ayarlayan bir geçiş kullanılıyorsa --platforms değerini 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 penceresi boyunca her iki stili de desteklemek için platform eşlemelerini kullanmanız gerekir.

Platformları günümüzde kullanma

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 etkinleştirin (varsa) ve önemsediğiniz projelerin çalışıp çalışmadığını görmek için gereken tüm testleri 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 bu, geçişlerin bozuk olmadığı durumlarda 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, eski sürümün desteğinin sonlandırıldığı süre boyunca platform destekli ve eski sürüm destekli mantığın aynı derlemede birlikte 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

Taşıma zaman çizelgesi hakkında genel destek ve sorular için bazel-discuss@googlegroups.com adresiyle veya ilgili kuralların sahipleriyle iletişime geçin.

Platform/toolchain API'lerinin tasarımı ve gelişimi hakkında tartışmalar için bazel-dev@googlegroups.com ile iletişime geçin.

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