Platformlarla Geliştirme

Bazel, platformları ve araç zincirlerini modelleme konusunda gelişmiş destek sunar. Bunu 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.

Ö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ış derlemelere neden olmuştur. 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 durum, dil ve proje birlikte çalışabilirliğini teşvik eden net API'ler de dahil olmak üzere bu kavramlar için daha ilkeli bir destek 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 formla oluşturulduğunda tamamlanır:

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

Bu şu anlama gelir:

  1. Projenizin kullandığı kurallar, //:myplatform ile doğru araç zincirlerini çıkarabilir.
  2. Projenizin bağımlılıklarının kullandığı kurallar, //:myplatform öğesinden doğru araç zincirlerini çıkarabilir.
  3. Sizinkine bağlı olan projeler //:myplatform veya projeniz eski API'leri (ör. --crosstool_top) destekliyor.
  4. //:myplatform, OS ve otomatik proje uyumluluğunu destekleyen diğer genel kavramlara ilişkin [ortak bildirimler][Common Platform Declaration]{: .external} CPU referansları.
  5. İlgili tüm projelerselect()s //:myplatform tarafından belirtilen makine özelliklerini anlıyor.
  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 kalır.
  • Daha basit bir kullanıcı deneyimi. Tüm projeler şunları anlıyor: --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şmektedir 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 hedeflerinin bir 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'ları hedefleyebilecekleri (target_compatible_with = ["@platforms//os:linux"]) ve araçlarının çalışabileceği (exec_compatible_with = ["@platforms//os:mac"]) makineler olarak 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ü denir.

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şir. Bazel'in başlıca kurallarının tamamı platformlara taşınıyor. Ancak bu işlem biraz zaman alacaktır. 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 okuyamıyorsa proje başarısız olabilir --platforms).

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.

Yaygın 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() içeriyorsa ve SomeCommonLib, @commonlib//constraints:arm üzerinde select() içeriyorsa bunlar, "kurma" 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. Dilde yaygın olan özellikler, ilgili dillerin depolarında bildirilmelidir.

Varsayılan platformlar

Genel olarak proje sahipleri, hangi tür makineler oluşturmak istediklerini açıklamak için açık platformlar tanımlamalıdır. Bunlar daha sonra --platforms ile tetiklenir.

--platforms ayarlanmadığında Bazel, yerel derleme makinesini temsil eden bir 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) ayarını yaptığı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 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 --cpu ve --crosstool_top ile C++ bağımlılıklarını yapılandırmaya devam etmesidir (örnek). Bu nedenle, bu durum Apple'ın platformlara taşınan 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ş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 büyük ölçüde tamamlandı.

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 toolchain belgelerine bakın.

select()

Projeler select() constraint_value hedeflerinde ancak tam 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ü kaynaklara sahip bir kitaplık, daha spesifik 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. üzerindeki select'lar --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.

Bir proje, dil veya araç zinciri sorumlusuysanız ve derlemeniz varsayılan olarak platformları kullanmı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 ve tam tersi şekilde 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üresi 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ündeki platform_mappings dosyasından okur. --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: