Platformlarla Geliştirme

Sorun bildirme Kaynağı görüntüleme Nightly · 8.0 7.4 . 7.3 · 7.2 · 7.1 · 7.0 · 6.5

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. Sonunda tüm derlemeler platforma dayalı olacak. Derlemelerinizin nereye uyduğunu öğrenmek için aşağıdaki bölümü okuyun.

Daha resmi dokümanlar için şu makalelere bakın:

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 yakın zamanda eklenmiştir. 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'sunu ve C++ araç zincirini ayarlamak için --cpu ve --crosstool_top öğelerini kullanır. Bu iki seçenek de "platform"u doğru şekilde 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 ve çok platformlu projeler için tasarlanmıştır. Bu nedenle, 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 gerekiyor. Bu yeni API'ler tam da 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()'lerinin bunları desteklemesi gerektiğinden bu durum önemsiz değildir. 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 bu taşıma sırası ve projelerinizin bu sürece 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 derlendiğinde 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'ten doğru araç zincirlerini çıkarabilir.
  3. Ya size bağlı projeler //:myplatform'i destekliyor ya projeniz eski API'leri (--crosstool_top gibi) destekliyor.
  4. //:myplatform, CPU, OS ve otomatik projeler arası uyumluluğu destekleyen diğer genel kavramların [common declarations][Common Platform Declaration]{: .external} referanslarını içerir.
  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 bulabileceği bir yerde.

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 yöneticisiyseniz yeni API'leri desteklemek isteyeceksiniz. Genel taşıma işleminin tamamlanmasını bekleyip beklemeyeceğiniz veya özelliği erken etkinleştirip etkinleştirmeyeceğiniz, değer / maliyet ihtiyaçlarınıza bağlıdır:

Değer

  • --cpu gibi sabit kodlu işaretçiler yerine select() veya ilgilendiğiniz tam özelliklerde araç zincirleri seçebilirsiniz. Örneğin, birden fazla CPU aynı talimat grubunu destekleyebilir.
  • Daha doğru derlemeler. Yukarıdaki örnekte select() yerine --cpu kullanırsanız ve 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.
  • Bu özelliklerin çalışmasını sağlamak 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ç zincirleri için standart tanımlar hâlâ gelişmekte olup ilk aşamada ek katkılar gerekebilir.

API incelemesi

platform, constraint_value hedeflerinin bir koleksiyonudur:

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) tanımlar. 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ıştırılabileceği (exec_compatible_with = ["@platforms//os:mac"]) makinelerin constraint_value'lerini belirtir.

Bazel, $ bazel build //:myproject --platforms=//:myplatform'ü derlediğinde derleme makinesinde çalışabilecek ve //:myplatform için ikili dosyalar derleyebilecek bir araç zinciri otomatik olarak seçer. Buna araç zinciri çözümü denir.

Mevcut araç zinciri grubu, register_toolchains ile WORKSPACE'e veya --extra_toolchains ile komut satırına kaydedilebilir.

Daha ayrıntılı bilgi için burayı inceleyin.

Durum

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

  1. Kural mantığı, yeni araç zinciri API'sinden (ctx.toolchains) araç bilgisi almak ve --cpu ile --crosstool_top gibi eski ayarları okumayı durdurmak için güncellenmelidir. Bu işlem oldukça 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 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 yapmadığınız sürece). Genel olarak, projeler kendi platformlarını tanımlamalıdır.

  3. Mevcut projeler taşınmalıdır. select()'ler ve geçişler de taşınmalıdır. Bu en büyük zorluktur. Özellikle çok dilli projeler için zordur (tüm diller okunamazsa --platforms 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.

Ortak 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 OrtakKütüphanem'de @commonlib//constraints:arm üzerinde birer select() varsa bu uygulamalar, "etkinleştir" modlarını uyumsuz ölçütlerle tetikler.select()

Dünya genelinde ortak özellikler @platforms deposunda belirtilir (bu nedenle, yukarıdaki örneğin standart etiketi @platforms//cpu:arm'dır). Dilde ortak özellikler, ilgili dillerin depolarında belirtilmelidir.

Varsayılan platformlar

Genellikle proje sahipleri, uygulamalarını hangi tür makinelere yönelik olarak oluşturmak istediklerini açıklamak için açık platformlar tanımlamalıdır. Ardından bunlar --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şturulur. Bu nedenle, açıkça tanımlamanız gerekmez. Yerel makinenin OS ve CPU öğelerini @platforms içinde tanımlanan constraint_value öğeleriyle eşler.

C++

Bazel'in C++ kuralları, --incompatible_enable_cc_toolchain_resolution değerini belirlediğinizde (#7260) araç zincirlerini seçmek için platformları kullanır.

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

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

yerine:

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

Projeniz saf C++ ise ve C++ dışındaki projelere bağımlı değilse 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ı makaleyi inceleyin.

Bu mod varsayılan olarak etkin değildir. Bunun nedeni, Apple projelerinin C++ bağımlılıklarını hâlâ --cpu ve --crosstool_top ile yapılandırmasıdır (ö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şaretlerini nasıl kullanacağınızı öğrenmek için Bazel ve Java kılavuzunu inceleyin. Daha fazla bilgi için Tasarım dokümanı'na bakın.

Eski işaretleri kullanmaya devam ediyorsanız Sayı 7849'daki taşıma sürecini uygulayın.

Yapay Zeka

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

Bu özellik varsayılan olarak etkin değildir. Ancak taşıma işlemi 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 işlem tamamlanana kadar, platform eşlemelerini kullanarak Apple projelerini platform destekli 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 açıklama için araç zinciri dokümanlarına bakın.

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 bilinçli olarak yapılı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:

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, taşıma aralığı boyunca her iki stili de desteklemek için bunları constraint_values olarak dönüştürmeniz veya platform eşlemelerini kullanmanız gerekir.

Geçişler

Starlark geçişleri, derleme grafiğinizin işaretlenmiş 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" } olarak dönüştürmeniz veya taşıma aralığı boyunca her iki stili de desteklemek için platform eşlemelerini kullanmanız gerekir.

Platformları günümüzde kullanma

Yalnızca bir projeyi derlemek veya çapraz derlemek istiyorsanız projenin resmi dokümanlarını incelemeniz gerekir. Platformlarla nasıl ve ne zaman entegre edileceğini ve bunun ne gibi bir değer sunacağını belirlemek dil ve projeyi koruyan kişilere bağlıdır.

Proje, dil veya araç zinciri yöneticisiyseniz ve derlemeniz varsayılan olarak platformları kullanmıyorsa üç seçeneğiniz vardır (genel 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. Ö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=...

    Bunun bazı bakım maliyetleri 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ını ilgili platformlarla eşleyerek ve bunun tersini yaparak 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() ile ilgili eski işaretler grubunun veya bunun tersinin bir eşlemesidir. Ö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 dahil olmak üzere derleme boyunca tutarlı bir şekilde uygulanmasını sağlamak için bunu kullanır.

Bazel varsayılan olarak çalışma alanı kök dizininizdeki platform_mappings dosyasından eşlemeleri okur. --platform_mappings=//:my_custom_mapping ayarını da yapabilirsiniz.

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/araç zinciri 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: