Platformlarla Geliştirme

Bazel, platformları ve araç zincirlerini modelleme konusunda gelişmiş destek sunar. Bu özelliği gerçek projelerle entegre etmek için kod sahipleri, kural bakımcıları ve temel Bazel geliştiricileri arasında dikkatli bir işbirliği gerekir.

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

Çok kısa özet: Bazel'in platform 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. Derlemelerinizin hangi kategorilere uygun olduğunu öğrenmek için aşağıdaki bilgileri inceleyin.

Daha resmi belgeler için aşağıdaki kaynaklara bakın:

Arka plan

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

Bu, Bazel'e nispeten yeni eklenen bir özelliktir. Bu özellik, dil bakımcılarının bunu zaten geçici ve uyumsuz şekillerde yaptığını gözlemleyerek geliştirildi. Örneğin, C++ kuralları, derlemenin hedef CPU'sunu ve C++ araç zincirini ayarlamak için --cpu ve --crosstool_top kullanır. Bunların hiçbiri "platform"u doğru şekilde modellemiyor. Geçmişte bu tür girişimler, garip ve yanlış yapılarla sonuçlanmıştır. Bu işaretler, kendi bağımsız arayüzünü --java_toolchain ile geliştiren Java derlemesini de kontrol etmez.

Bazel, büyük, çok dilli ve çok platformlu projeler için tasarlanmıştır. Bu durum, dil ve proje birlikte çalışabilirliğini teşvik eden net API'ler de dahil olmak üzere bu kavramların daha ilkeli bir şekilde desteklenmesini gerektirir. Bu yeni API'ler bu amaçla geliştirilmiştir.

Taşıma

Platform ve araç zinciri API'leri yalnızca projeler bunları gerçekten kullandığında çalışır. Projenin kural mantığı, araç zincirleri, bağımlılıkları ve select()'ları bunları desteklemesi gerektiğinden bu işlem kolay değildir. Tüm projelerin ve bağımlılıklarının doğru şekilde çalışmaya devam etmesi için dikkatli bir taşıma sırası gerekir.

Örneğin, Bazel'in C++ kuralları platformları destekler. Ancak Apple Kuralları geçerli değildir. C++ projeniz Apple'ı önemsemiyor olabilir. Ancak diğerleri etkinleştirilebilir. Bu nedenle, platformların tüm C++ derlemeleri için genel olarak etkinleştirilmesi henüz güvenli değildir.

Bu sayfanın geri kalanında bu taşıma sırası ve projelerinizin nasıl ve ne zaman dahil edilebileceği açıklanmaktadır.

Hedef

Bazel'in platform taşıma işlemi, tüm projeler aşağıdaki şekilde oluşturulduğunda tamamlanır:

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

Bu durumda:

  1. Projenizin kullandığı kurallar, //:myplatform'dan doğru araç zincirlerini çıkarabilir.
  2. Projenizin bağımlılıklarının kullandığı kurallar, //:myplatform'dan doğru araç zincirlerini çıkarabilir.
  3. Sizinkine bağlı olan projeler //:myplatform'ı destekliyor veya projeniz eski API'leri (ör. --crosstool_top) destekliyor olmalıdır.
  4. //:myplatform referansları [common declarations][Common Platform Declaration]{: .external} CPU, OS ve projeler arası otomatik uyumluluğu destekleyen diğer genel kavramlar.
  5. İlgili tüm projelerselect()in//:myplatform ile belirtilen makine özelliklerini anlıyor olması gerekir.
  6. //:myplatform, net ve yeniden kullanılabilir bir yerde tanımlanır: Platform projenize özelse projenizin deposunda, aksi takdirde bu platformu kullanabilecek tüm projelerin bulabileceği bir yerde.

Bu hedefe ulaşılır ulaşılmaz eski API'ler kaldırılacaktır. Bu durumda, projeler platformları ve araç zincirlerini standart bir şekilde seçecek.

Platformları kullanmalı mıyım?

Yalnızca bir proje oluşturmak veya çapraz derlemek istiyorsanız projenin resmi belgelerini incelemeniz gerekir.

Proje, dil veya araç zinciri sorumlusuysanız yeni API'leri desteklemek isteyebilirsiniz. Genel taşıma işleminin tamamlanmasını bekleyip beklemeyeceğiniz veya erken kaydolup kaydolmayacağınız, özel değer / maliyet ihtiyaçlarınıza bağlıdır:

Değer

  • select() veya --cpu gibi sabit kodlanmış işaretler yerine tam olarak ilgilendiğiniz özelliklerde araç zincirleri seçebilirsiniz. Örneğin, birden fazla CPU aynı talimat grubunu destekleyebilir.
  • Daha doğru derlemeler. Yukarıdaki örnekte select() ile --cpu eşleşiyorsa ve aynı talimat grubunu destekleyen yeni bir CPU eklerseniz select() yeni CPU'yu tanımaz. Ancak platformlardaki select() doğru olmaya devam ediyor.
  • Daha basit bir kullanıcı deneyimi. Tüm projeler şunları anlar: --platforms=//:myplatform. Komut satırında birden fazla dile özgü işaret kullanmanıza 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 kullanır.
  • Hedef platformla uyumlu olmayan hedefler, derleme ve test aşamasında atlanabilir.

Maliyetler

  • Henüz platformları desteklemeyen bağımlı projeler, sizinkilerle otomatik olarak çalışmayabilir.
  • Bu özelliklerin çalışması için ek geçici bakım gerekebilir.
  • Yeni ve eski API'lerin birlikte kullanılması, kafa karışıklığını önlemek için kullanıcılara daha dikkatli rehberlik edilmesini gerektirir.
  • Ortak özellikler (ör. OS ve CPU) için standart tanımlar hâlâ geliştirilmektedir ve başlangıçta ek katkılar gerekebilir.
  • Dile özgü araç zincirlerinin kanonik tanımları gelişmeye devam etmektedir ve ilk katkılar için ek çaba gerekebilir.

API incelemesi

platform, constraint_value hedef koleksiyonudur:

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

constraint_value, makine özelliğidir. 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ı (ör. compiler = "//mytoolchain:custom_gcc") bildirir. Sağlayıcıları, bu bilgileri bu araçlarla oluşturulması gereken kurallara iletir.

Araç zincirleri, constraint_value makinelerinin hedefleyebileceği (target_compatible_with = ["@platforms//os:linux"]) ve araçlarının çalışabileceği (exec_compatible_with = ["@platforms//os:mac"]) makineleri bildirir.

$ bazel build //:myproject --platforms=//:myplatform oluşturulurken Bazel, derleme makinesinde çalışabilen ve //:myplatform için ikili dosyalar oluşturabilen bir araç zincirini otomatik olarak seçer. Bu işleme toolchain çözümü adı verilir.

Kullanılabilir araç zincirleri kümesi, WORKSPACE ile register_toolchains 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 başlıca kurallarının tamamı platformlara taşınıyor. Ancak bu işlem biraz zaman alabilir. Bunun üç temel nedeni vardır:

  1. Kural mantığı, yeni toolchain API'den (ctx.toolchains) araç bilgilerini almak ve --cpu ile --crosstool_top gibi eski ayarları okumayı durdurmak için güncellenmelidir. Bu işlem oldukça basittir.

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

    Platform tanımları da gereklidir (Bazel'in çalıştığı makine için derleme yapmıyorsanız). Genellikle projeler kendi platformlarını tanımlamalıdır.

  3. Mevcut projeler taşınmalıdır. select() ve geçişler de taşınmalıdır. En büyük zorluk budur. Bu durum, özellikle çok dilli projelerde zordur (tüm diller --platforms okuyamıyorsa proje başarısız olabilir).

Yeni bir kural grubu tasarlıyorsanız en başından itibaren platformları desteklemeniz gerekir. Bu sayede kurallarınız otomatik olarak diğer kurallar ve projelerle uyumlu hale gelir. Platform API'si daha yaygın hale geldikçe bu uyumluluğun değeri artar.

Ortak platform özellikleri

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

Örneğin, MyApp, constraint_value @myapp//cpus:arm üzerinde select()'ye sahipse ve SomeCommonLib, @commonlib//constraints:arm üzerinde select()'ye sahipse bunlar, "arm" modlarını uyumsuz ölçütlerle tetikler.

Genel olarak yaygın olan özellikler @platforms deposunda (bu nedenle, yukarıdaki örnek için standart etiket @platforms//cpu:arm olur) bildirilir. Dile özgü yaygın özellikler, ilgili dillerin depolarında bildirilmelidir.

Varsayılan platformlar

Genel olarak proje sahipleri, oluşturmak 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, yerel derleme makinesini temsil eden platform değerini varsayılan olarak kullanır. Bu, @local_config_platform//:host konumunda otomatik olarak oluşturulduğundan açıkça tanımlamanıza gerek yoktur. Yerel makinenin OS ve CPU değerlerini, @platforms içinde belirtilen constraint_value değerleriyle eşler.

C++

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

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

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

yerine eski sürümü kullanıyorsanız:

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

Projeniz tamamen C++ ile yazılmışsa ve C++ ile yazılmamış projeler tarafından kullanılmıyorsa select'larınız ve geçişleriniz uyumlu olduğu sürece platformları güvenle kullanabilirsiniz. Daha fazla bilgi için #7260 ve C++ araç zincirlerini yapılandırma başlıklı makalelere bakın.

Bu mod varsayılan olarak etkin değildir. Bunun nedeni, Apple projelerinin hâlâ --cpu ve --crosstool_top ile C++ bağımlılıklarını yapılandırmasıdır (örnek). Bu nedenle, bu durum Apple kurallarının platformlara taşınması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şaretlerini nasıl kullanacağınızı öğrenmek için Bazel ve Java kılavuzuna bakın. Daha fazla bilgi için Tasarım belgesine bakın.

Hâlâ eski işaretleri kullanıyorsanız 7849 numaralı sorundaki 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 özellik varsayılan olarak etkin değildir. Ancak taşıma işlemi hızla ilerliyor.

Apple

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 kullandıklarından platformda etkinleştirilen C++ bağımlılıklarını da desteklemezler. Bu işlem taşınana kadar, Apple projelerini platform eşlemeleri ile platform özellikli C++ ile karıştırabilirsiniz (örnek).

Diğer diller

Yeni bir dil için kurallar tasarlıyorsanız dilinizin araç zincirlerini seçmek üzere platformları kullanın. İyi bir kılavuz için araç zincirleri belgelerine bakın.

select()

Projeler select() constraint_value hedeflerinde ancak platformlarda tamamlanamaz. Bu, select()'nın mümkün olduğunca çok sayıda makineyi desteklemesi için kasıtlı olarak yapılmıştır. ARM'a özgü kaynakların bulunduğu bir kitaplık, daha ayrıntılı bilgi vermeyi gerektiren bir neden olmadığı sürece ARM destekli tüm makineleri desteklemelidir.

Bir veya daha fazla constraint_value seçmek için:

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

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

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

Daha fazla bilgiyi burada bulabilirsiniz.

--cpu, --crosstool_top vb. cihazlardaki select, --platforms'ı anlamıyor. Projenizi platformlara taşırken bunları constraint_values biçimine 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ı bölümlerindeki işaretleri değiştirir. Projenizde --cpu, --crossstool_top veya diğer eski işaretleri ayarlayan bir geçiş kullanılıyorsa --platforms 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" } olarak dönüştürmeniz veya taşıma penceresi boyunca her iki stili de desteklemek için platform eşlemelerini kullanmanız gerekir.

Platformları kullanma

Yalnızca bir proje oluşturmak veya çapraz derlemek istiyorsanız projenin resmi belgelerini incelemeniz gerekir. Platformlarla nasıl ve ne zaman entegrasyon yapılacağına, bunun ne gibi bir değer sunacağına dil ve proje sorumluları karar verir.

Proje, dil veya araç zinciri sorumlusuysanız ve derlemenizde varsayılan olarak platformlar kullanılmıyorsa (global geçişi beklemek dışında) üç seçeneğiniz vardır:

  1. Projenizin dilleri için "platformları kullan" işaretini etkinleştirin (varsa) ve ilgilendiğiniz projelerin çalışıp çalışmadığını görmek için gerekli testleri yapın.

  2. Önem verdiğiniz projeler hâlâ --cpu ve --crosstool_top gibi eski işaretlere bağlıysa bunları --platforms ile birlikte kullanın:

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

    Bu yöntemin bakım maliyeti vardır (ayarların eşleştiğinden manuel olarak emin olmanız gerekir). Ancak bu, beklenmedik geçişler olmadığında çalışır.

  3. --cpu tarzı ayarları ilgili platformlarla, platformları da --cpu tarzı ayarlarla eşleyerek her iki stili de desteklemek için platform eşlemeleri yazın.

Platform eşlemeleri

Platform eşlemeleri, platform destekli ve eski sistem destekli mantığın, eski sistemin desteğinin sonlandırılma süreci boyunca aynı derlemede birlikte bulunmasına olanak tanıyan geçici bir API'dir.

Platform eşlemesi, platform() ile karşılık gelen bir eski işaretler kümesi arasındaki veya bunun tersi yöndeki 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, hem platform tabanlı hem de eski tüm ayarların geçişler de dahil olmak üzere derleme boyunca tutarlı bir şekilde uygulanmasını sağlamak için bu özelliği kullanır.

Bazel, varsayılan olarak eşlemeleri çalışma alanınızın kök dizinindeki platform_mappings dosyasından okur. Ayrıca --platform_mappings=//:my_custom_mapping da ayarlayabilirsiniz.

Tüm ayrıntılar için buraya bakın.

Sorular

Genel destek ve taşıma zaman çizelgesiyle ilgili sorularınız için bazel-discuss@googlegroups.com adresinden 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: