Bazel, platform ve araç zincirlerini modellemek için gelişmiş bir desteğe sahiptir. Bunun gerçek projelerle entegre edilmesi için kod sahipleri, kural sorumluları ve temel Bazel geliştiricileri arasında dikkatli bir iş birliği gerekir.
Bu sayfada, platformların amacı özetlenmekte ve platformlarla nasıl geliştirme yapılacağı gösterilmektedir.
tl;dr: Bazel'in platformu 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 denk geldiğini görmek için aşağıdaki bölümü okuyun.
Daha resmi belgeler için bkz:
Arka plan
Yazılım projelerinin farklı makineleri hedeflemesini ve doğru dil araçlarıyla derleme şeklini standartlaştırmak için platformlar ve araç zincirleri kullanıma sunuldu.
Bu, Bazel'e nispeten yeni bir yeniliktir. Dil sorumlularının zaten bunu anlık ve uyumsuz şekillerde yaptığı gözlemi bu duruma ilham verdi. Ö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. Tarihi buna yönelik girişimler tuhaf ve yanlış yapılara 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 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'lerin amacı da bu.
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, tüm projelerin ve bağımlılıklarının doğru şekilde çalışmaya devam edebilmesi için dikkatli bir taşıma sırası gerektirir.
Örneğin, Bazel'in C++ Kuralları, platformları destekler. Ancak Apple Kuralları öyle değildir. C++ projeniz Apple'ı önemsemiyor olabilir. Diğerleri de olabilir. 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, 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 anlama gelir:
- Projenizin kullandığı kurallar,
//:myplatform
öğesinden doğru araç zincirlerini çıkarabilir. - Projenizin bağımlılıklarının kullandığı kurallar,
//:myplatform
öğesinden doğru araç zincirlerini tahmin edebilir. - Ya sizinkine bağlı projeler
//:myplatform
ya da projenizde eski API'ler (--crosstool_top
gibi) destekleniyor. //:myplatform
, projeler arası otomatik uyumluluğu destekleyenCPU
,OS
ve diğer genel kavramlara ait [ortak bildirimler][Ortak Platform Bildirimi]{: .external} referansını gösteriyor.- Alakalı tüm projelerin
select()
'leri,//:myplatform
tarafından belirtilen makine özelliklerini anlar. //: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şılır edilmez eski API'ler kaldırılacaktır. Platform ve araç zincirleri projelerinde standart olarak bu şekilde seçilir.
Platformları kullanmalı mıyım?
Sadece proje oluşturmak ya da çapraz derlemek istiyorsanız projenin resmi belgelerine uymanız 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 veya geçiş işlemini erkenden etkinleştirme, ö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ülklerdeselect()
özelliğini kullanabilir veya araç zincirlerini seçebilirsiniz. Örneğin, birden fazla CPU aynı talimat grubunu destekleyebilir.- Daha doğru derlemeler. Yukarıdaki örnekte
--cpu
içinselect()
işlemi gerçekleştirirseniz aynı talimat grubunu destekleyen yeni bir CPU eklersenizselect()
yeni CPU'yu tanıyamaz. Ancak platformlardakiselect()
metriği doğru olmaya devam ediyor. - Daha basit kullanıcı deneyimi. Tüm projeler aşağıdaki hususları anlar:
--platforms=//:myplatform
. Komut satırında birden fazla dile özgü işaretlere gerek yoktur. - Daha basit dil tasarımı. Tüm dillerde araç zincirlerini tanımlamak, araç zincirlerini kullanmak ve platform için doğru araç zincirini seçmek için ortak bir API kullanılır.
- Hedef platformla uyumlu olmayan hedefler, derleme ve test aşamasında atlanabilir.
Maliyetler
- Henüz platformları desteklemeyen bağımlı projeler sizin projenizle otomatik olarak çalışmayabilir.
- Cihazların çalışması için ek geçici bakım gerekebilir.
- Yeni ve eski API'lerin birlikte var olması, karışıklığı önlemek için daha dikkatli bir kullanıcı rehberliği gerektirir.
OS
veCPU
gibi yaygın özelliklerin standart tanımları gelişmeye devam ettiği için başlangıçda ekstra katkı yapılması gerekebilir.- Dile özgü araç zincirlerine yönelik standart tanımlar hâlâ gelişme aşamasında olduğundan başlangıç aşamasında 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ün" değerleri 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, bir dilin araçlarını (compiler =
"//mytoolchain:custom_gcc"
gibi) bildirir. Aracın 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.
Mevcut 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:
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.Araç zinciri sorumluları, araç zincirlerini tanımlamalı ve kullanıcılar için erişilebilir hale getirmelidir (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). Genel olarak projeler kendi platformlarını tanımlamalıdır.
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şından itibaren desteklemeniz gerekir. Bu, kurallarınızı otomatik olarak diğer kural ve projelerle uyumlu hale getirir ve platform API'si daha yaygın hale geldikçe değeri artırır.
Sık kullanılan platform özellikleri
Projelerde ortak olan OS
ve CPU
gibi platform özellikleri standart ve merkezi bir yerde tanımlanmalıdır. Bu, projeler arası ve diller arası
uyumluluğu teşvik eder.
Örneğin, MyApp'da constraint_value
@myapp//cpus:arm
için bir select()
varsa ve MyApp'de select()
varsa
@commonlib//constraints:arm
bunlar "arm" 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 değer, @local_config_platform//:host
konumunda otomatik olarak oluşturulduğundan açıkça tanımlamaya gerek yoktur. 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 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). Bu, platformlara geçiş yapan 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. Ek bilgi için Tasarım belgesine bakın.
Eski işaretleri kullanmaya devam ediyorsanız Sorun #7849'da belirtilen taşıma işlemini uygulayın.
Android
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ı, Apple araç zincirlerini seçmek için platformları henüz desteklememektedir.
Ayrıca, C++ araç zincirini ayarlamak için eski --crosstool_top
kullandığı için platform özellikli C++ bağımlılıklarını da desteklemezler. Bu özellik taşınana kadar, Apple projelerini platorm özellikli C++ ile platform eşlemeleri ile birlikte kullanabilirsiniz (örnek).
Diğer diller
- Bazel'in Rust kuralları, platformları tam olarak destekler.
- Bazel'ın Go kuralları, platformları tam olarak destekler (ayrıntılar).
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ı iyi bir kılavuz için araç zinciri belgelerini inceleyin.
select()
Projeler constraint_value
hedefler üzerinde select()
işlemi gerçekleştirebilir ancak platformları tamamlayamaz. Bu işlem, select()
'ların mümkün olduğunca çok çeşitli makineleri desteklemesi için bilerek yapılır. ARM
'a özgü kaynaklara sahip bir kitaplık, daha ayrıntılı olması için bir neden 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
uygulamasında 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
anlaşılmı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
bazı kısımlarını değiştirir. Projenizde --cpu
, --crossstool_top
veya diğer eski işaretleri ayarlayan bir geçiş kullanılıyorsa --platforms
yazan 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.
Günümüzde platformlar nasıl kullanılır?
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):
Projenizin dilleri için "platformları kullan" işaretini (varsa) kullanın ve sizin için önemli olan projelerin işe yarayıp yaramadığını görmek için ihtiyacınız olan her şeyi yapın.
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 geri geçişlerin yapılmadığı durumlarda bu yöntem işe yarayacaktır.
--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 kullanımdan kaldırma dönemi boyunca aynı derlemede bir arada 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
Genel destek almak ve taşıma zaman çizelgesiyle ilgili sorularınız için bazel-discuss@googlegroups.com adresiyle veya ilgili kuralların sahipleriyle iletişime geçebilirsiniz.
Platform/araç zinciri API'lerinin tasarımı ve evrimi ile ilgili tartışmalar için bazel-dev@googlegroups.com ile iletişime geçin.