Platformlarla Geliştirme

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

Bu sayfada platformların amacı özetlenmekte ve platformlarla nasıl oluşturulacağı gösterilmektedir.

tl;dr: Bazel'in platformu ve araç zinciri API'leri kullanılabilir ancak tüm dil kuralları, select() ve diğer eski referanslar güncellenene kadar her yerde çalışmaz. Bu çalışmalar sürekli devam ediyor. Sonunda tüm derlemeler platform tabanlı olacak. Yapılarınızın nereye sığacağını görmek 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 eklemedir. Dil yaratıcılarının zaten bunu anlık, uyumsuz şekillerde yaptığı gözleminden ilham aldı. Örneğin, C++ kuralları bir derlemenin hedef CPU'sunu ve C++ araç zincirini belirlemek için --cpu ve --crosstool_top öğelerini kullanır. Bunların hiçbiri bir "platform"u doğru şekilde modellemez. Geçmişte bu yönde girişimler, garip ve hatalı derlemelere neden oldu. Bu işaretler, --java_toolchain ile kendi bağımsız arayüzünü geliştiren Java derlemesini de kontrol etmez.

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

Taşıma

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

Örneğin, Bazel'in C++ Kuralları destek platformları. Ancak Apple Kuralları geçerli değildir. C++ projeniz Apple'ı önemsemiyor olabilir. Ancak diğerleri de kullanabilir. 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 bu taşıma sırası ve projelerinizin nasıl ve ne zaman bu listeye dahil edilebileceği açıklanmaktadır.

Hedef

Tüm projeler şu formla derlendiğinde Bazel'in platforma geçişi tamamlanır:

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

Bu durum, şu anlama gelir:

  1. Projenizin kullandığı kurallar, //:myplatform kaynağından doğru araç zincirlerini tahmin edebilir.
  2. Projenizin bağımlılıklarının kullandığı kurallar, //:myplatform kaynağından doğru araç zincirlerini tahmin edebilir.
  3. Sizinki projelere bağlı projeler //:myplatform ya da eski API'leri destekliyor olabilir (--crosstool_top gibi).
  4. //:myplatform, CPU, OS ve projeler arası otomatik uyumluluğu destekleyen diğer genel kavramlara ait [ortak bildirim][Ortak Platform Beyanı]{: .external} değerine referansta bulunur.
  5. Tüm ilgili projelerin select()ları //:myplatform politikasında belirtilen makine özelliklerini anlar.
  6. //:myplatform, açık ve yeniden kullanılabilir bir yerde tanımlanır: Platform projenize özelse projenizin deposunda, aksi takdirde bu platformu kullanan tüm projelerin bulabileceği bir yerde olmalıdır.

Bu hedefe ulaşılır ulaşılmaz eski API'ler kaldırılacaktır. Bu, projelerde platform ve araç zinciri seçmek için kullanılan standart yöntemdir.

Platformları kullanmalı mıyım?

Sadece bir proje derlemek veya çapraz derlemek istiyorsanız projenin resmi belgelerine uymanız gerekir.

Proje, dil veya araç zinciri geliştiricisiyseniz zamanla yeni API'leri desteklemek isteyeceksiniz. Genel taşıma işleminin tamamlanmasını bekleme ya da erkenden etkinleştirme işlemi, belirli değer / maliyet gereksinimlerinize bağlıdır:

Değer

  • select() özelliğini kullanabilir veya --cpu gibi sabit kodlu işaretler yerine, tam olarak ilgilendiğiniz özelliklerde araç zincirlerini seçebilirsiniz. Örneğin, birden fazla CPU aynı talimat grubunu destekleyebilir.
  • Daha doğru derlemeler. Yukarıdaki örnekte --cpu kullanarak select() işlemini gerçekleştirip aynı talimat grubunu destekleyen yeni bir CPU eklerseniz select(), yeni CPU'yu tanıyamaz. Ancak platformlardaki select() değeri geçerliliğini koruyor.
  • Daha basit kullanıcı deneyimi. Tüm projelerde şu hususlar anlaşılmaktadır: --platforms=//:myplatform. Komut satırında birden fazla dile özgü işaret yapılmasına gerek yoktur.
  • Daha basit dil tasarımı. Tüm dillerde araç zincirlerini tanımlamak, araç zincirlerini kullanmak ve bir platform için doğru araç zincirini seçmek için ortak bir API kullanılır.
  • Hedefler, hedef platformla uyumlu değilse oluşturma ve test aşamasında atlanabilir.

Maliyetler

  • Henüz platformları desteklemeyen bağımlı projeler, sizinkiyle otomatik olarak çalışmayabilir.
  • Cihazların çalışmasını sağlamak için geçici olarak ek bakım gerekebilir.
  • Yeni ve eski API'lerin bir arada kullanılabilir olması, karışıklığı önlemek için daha dikkatli kullanıcı rehberliği gerektirir.
  • OS ve CPU gibi yaygın özelliklerin standart tanımları gelişmeye devam etmektedir ve bunlar için ek başlangıç katkıları gerekebilir.
  • Dile özgü araç zincirlerinin standart tanımları gelişmeye devam etmektedir ve bunlar için başlangıç için 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"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 ayrıntılı bilgi için buraya göz atın.

Durum

Mevcut platform desteği dillere göre değişiklik gösterir. Bazel'in tüm temel kuralları platformlara taşınıyor. Ancak bu süreç zaman alacaktır. Bunun başlıca üç nedeni vardır:

  1. Yeni araç zinciri API'sinden (ctx.toolchains) araç bilgilerini almak ve --cpu ile --crosstool_top gibi eski ayarları okumayı bırakmak için kural mantığı güncellenmelidir. Bu işlem oldukça basittir.

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

    Platform tanımları da gereklidir (bazel aynı makine için derleme yapmıyorsanız). Projeler genellikle kendi platformlarını tanımlamalıdır.

  3. Mevcut projelerin taşınması gerekir. select() ve geçiş işlemlerinin de taşınması gerekir. En büyük zorluk bu. Bu, özellikle çok dilli projeler için zordur (tüm diller --platforms okuyamadığında başarısız olabilir).

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

Yaygın platform özellikleri

Projelerde yaygın olarak kullanılan OS ve CPU gibi platform mülkleri standart ve merkezi bir yerde bildirilmelidir. Bu, projeler arası ve diller arası uyumluluğu teşvik eder.

Örneğin, MyApp'in constraint_value @myapp//cpus:arm üzerinde bir select() ve SomeCommonLib'de @commonlib//constraints:arm üzerinde select() varsa bunlar uyumsuz kriterlerle "arma" modlarını tetikler.

Genel olarak yaygın olarak kullanılan özellikler @platforms deposunda beyan edilir (bu nedenle yukarıdaki örnek için standart etiket @platforms//cpu:arm şeklindedir). Ortak dil özellikleri, ilgili dillerin deposunda bildirilmelidir.

Varsayılan platformlar

Genel olarak proje sahipleri, derleme yapmak 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 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.

C++

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

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=...

Projeniz sadece C++ ise ve C++ olmayan projelere bağımlı değilse 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). Yani bu, platformlara taşınan Apple kurallarına bağlıdır.

Java

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

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

Yapılandırma bayraklarının nasıl kullanılacağını öğrenmek için Bazel ve Java kılavuzuna bakın. Ek bilgi için Tasarım dokümanına bakın.

Hâlâ eski işaretleri kullanıyorsanız Sorun 7849'daki taşıma sürecini uygulayın.

Android

Bazel'in Android kuralları, --incompatible_enable_android_toolchain_resolution ayarını yaptığınızda araç zincirlerini seçmek için platformları kullanır.

Bu ayar varsayılan olarak etkin değildir. Ancak taşıma süreci çok iyi gidiyor.

elma

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

Ayrıca, C++ araç zincirini ayarlamak için eski --crosstool_top kullandığı için platform özellikli C++ bağımlılıklarını da desteklemez. Bu taşınana kadar Apple projelerini platorm özellikli C++ ile platform eşlemeleriyle 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ı kılavuz için araç zinciri belgelerine bakın.

select()

Projeler constraint_value hedeflerinde select() içerebilir ancak platformlarda tamamını tamamlayamaz. Bu, select() öğelerinin mümkün olduğunca çok çeşitli makineyi desteklemesi için tasarlanmıştır. ARM özelliğine özel kaynaklara sahip bir kitaplık, daha belirgin olmak için bir neden olmadığı sürece ARM destekli tüm 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 penceresi aracılığıyla 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 penceresi boyunca her iki stili de desteklemek için platform eşlemelerini kullanmanız gerekir.

Platformlar bugün nasıl kullanılır?

Sadece bir proje derlemek veya çapraz derlemek istiyorsanız projenin resmi belgelerine uymanız gerekir. Platformlarla nasıl ve ne zaman entegre edileceğini ve bunun hangi değeri sunacağını belirlemek dil ve proje sorumlularına bağlıdır.

Proje, dil veya araç zinciri sorumlusuysanız ve derlemeniz varsayılan olarak platform kullanmıyorsa üç seçeneğiniz vardır (genel taşımayı beklemenin dışında):

  1. Projenizin dillerine (varsa) yönelik "platformları kullan" işaretini çevirin ve ilgilendiğiniz projelerin çalışıp çalışmadığını görmek için ihtiyacınız olan her şeyi test edin.

  2. Sizin için önemli olan projeler hâlâ --cpu ve --crosstool_top gibi eski işaretleri kullanıyorsa 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, geri dönüş geçişleri olmadığında işe yarar.

  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, yeni platformun kullanımdan kaldırma dönemi boyunca aynı derlemede birlikte kullanılmasını sağlayan geçici bir API'dir.

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 --apple_platform_type=macos" to "//platform:macos".
  --cpu=darwin
  --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.

Tüm ayrıntılar için buraya göz atın.

Sorular

Genel destek almak ve geçiş zaman çizelgesiyle ilgili sorularınız için bazel-discuss@googlegroups.com adresiyle 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@googlegroups.com ile iletişime geçin.

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