Bazel memiliki dukungan canggih untuk memodelkan platform dan toolchain. Mengintegrasikannya dengan project nyata memerlukan kerja sama yang cermat antara pemilik kode, pemelihara aturan, dan developer Bazel inti.
Halaman ini merangkum tujuan platform dan menunjukkan cara membangun dengan platform tersebut.
Singkatnya: API platform dan toolchain Bazel tersedia, tetapi tidak akan berfungsi di mana pun hingga semua aturan bahasa, select()
s, dan referensi lama lainnya diperbarui. Hal ini akan terus dilakukan. Pada akhirnya, semua build akan berbasis platform.
Baca di bawah untuk melihat kecocokan build Anda.
Untuk dokumentasi yang lebih formal, lihat:
Latar belakang
Platform dan toolchain diperkenalkan untuk menstandardisasi cara project software menargetkan berbagai mesin dan mem-build dengan alat bahasa yang tepat.
Ini adalah tambahan yang relatif baru di Bazel. Fitur ini
terinspirasi
oleh pengamatan bahwa pengelola bahasa sudah melakukannya dengan cara ad
hoc yang tidak kompatibel. Misalnya, aturan C++ menggunakan --cpu
dan --crosstool_top
untuk menetapkan CPU target build dan toolchain C++. Keduanya tidak memodelkan "platform" dengan benar. Upaya sebelumnya untuk melakukannya menyebabkan build yang canggung dan tidak akurat.
Flag ini juga tidak mengontrol kompilasi Java, yang mengembangkan antarmuka independennya sendiri dengan --java_toolchain
.
Bazel ditujukan untuk project besar, multi-bahasa, dan multi-platform. Hal ini memerlukan dukungan yang lebih berprinsip untuk konsep ini, termasuk API yang jelas yang mendorong interoperabilitas bahasa dan project. Inilah fungsi API baru ini.
Migrasi
API platform dan toolchain hanya berfungsi saat project benar-benar menggunakannya. Hal ini tidak mudah karena logika aturan, toolchain, dependensi, dan select()
project harus mendukungnya. Hal ini memerlukan urutan migrasi yang cermat
agar semua project dan dependensinya tetap berfungsi dengan benar.
Misalnya, Aturan C++ Bazel mendukung platform. Namun, Aturan Apple tidak. Project C++ Anda mungkin tidak memerlukan Apple. Namun, yang lain mungkin tidak. Jadi, platform belum aman untuk diaktifkan secara global untuk semua build C++.
Bagian selanjutnya dari halaman ini menjelaskan urutan migrasi ini serta cara dan waktu project Anda dapat menyesuaikannya.
Sasaran
Migrasi platform Bazel selesai saat semua project dibangun dengan formulir:
bazel build //:myproject --platforms=//:myplatform
Hal ini berarti:
- Aturan yang digunakan project Anda dapat menyimpulkan toolchain yang benar dari
//:myplatform
. - Aturan yang digunakan dependensi project Anda dapat menyimpulkan toolchain yang benar dari
//:myplatform
. - Baik project yang bergantung pada project Anda mendukung
//:myplatform
atau project Anda mendukung API lama (seperti--crosstool_top
). - Referensi
//:myplatform
[common declarations][Common Platform Declaration]{: .external} dariCPU
,OS
, dan konsep generik lainnya yang mendukung kompatibilitas lintas project otomatis. - Semua project yang relevan
select()
s memahami properti mesin yang tersirat dalam//:myplatform
. //:myplatform
ditentukan di tempat yang jelas dan dapat digunakan kembali: di repo project Anda jika platformnya unik untuk project Anda, atau di tempat yang dapat ditemukan oleh semua project yang mungkin menggunakan platform ini.
API lama akan dihapus segera setelah sasaran ini tercapai. Kemudian, cara ini akan menjadi cara standar project memilih platform dan toolchain.
Haruskah saya menggunakan platform?
Jika hanya ingin membuat atau mengompilasi silang project, Anda harus mengikuti dokumentasi resmi project.
Jika Anda adalah pengelola project, bahasa, atau toolchain, Anda pada akhirnya akan ingin mendukung API baru. Apakah Anda menunggu hingga migrasi global selesai atau memilih ikut serta lebih awal bergantung pada kebutuhan nilai / biaya spesifik Anda:
Nilai
- Anda dapat
select()
atau memilih toolchain pada properti yang Anda inginkan, bukan flag yang dikodekan secara permanen seperti--cpu
. Misalnya, beberapa CPU dapat mendukung set instruksi yang sama. - Lebih banyak build yang benar. Jika Anda
select()
dengan--cpu
dalam contoh di atas, lalu menambahkan CPU baru yang mendukung set instruksi yang sama,select()
akan gagal mengenali CPU baru. Namun,select()
di platform tetap akurat. - Pengalaman pengguna yang lebih sederhana. Semua project memahami:
--platforms=//:myplatform
. Tidak perlu beberapa flag khusus bahasa di command line. - Desain bahasa yang lebih sederhana. Semua bahasa menggunakan API umum untuk menentukan toolchain, menggunakan toolchain, dan memilih toolchain yang tepat untuk platform.
- Target dapat dilewati dalam fase build dan pengujian jika tidak kompatibel dengan platform target.
Biaya
- Project dependen yang belum mendukung platform mungkin tidak otomatis berfungsi dengan project Anda.
- Agar dapat berfungsi, pemeliharaan sementara tambahan mungkin diperlukan.
- Koeksistensi API baru dan lama memerlukan panduan pengguna yang lebih cermat untuk menghindari kebingungan.
- Definisi kanonis untuk properti umum seperti
OS
danCPU
masih terus berkembang dan mungkin memerlukan kontribusi awal tambahan. - Definisi kanonis untuk toolchain khusus bahasa masih terus berkembang dan mungkin memerlukan kontribusi awal tambahan.
Peninjauan API
platform
adalah kumpulan
target constraint_value
:
platform(
name = "myplatform",
constraint_values = [
"@platforms//os:linux",
"@platforms//cpu:arm",
],
)
constraint_value
adalah properti
mesin. Nilai dengan "jenis" yang sama dikelompokkan dalam
constraint_setting
yang sama:
constraint_setting(name = "os")
constraint_value(
name = "linux",
constraint_setting = ":os",
)
constraint_value(
name = "mac",
constraint_setting = ":os",
)
toolchain
adalah aturan Starlark. Atributnya mendeklarasikan alat bahasa (seperti compiler =
"//mytoolchain:custom_gcc"
). Penyedianya meneruskan informasi ini ke aturan yang perlu dibuat dengan alat ini.
Rangkaian alat mendeklarasikan constraint_value
mesin yang dapat
ditargetkan
(target_compatible_with = ["@platforms//os:linux"]
) dan mesin yang dapat
menjalankan alatnya
(exec_compatible_with = ["@platforms//os:mac"]
).
Saat mem-build $ bazel build //:myproject --platforms=//:myplatform
, Bazel
akan otomatis memilih toolchain yang dapat berjalan di mesin build dan
mem-build biner untuk //:myplatform
. Hal ini dikenal sebagai penyelesaian toolchain.
Kumpulan toolchain yang tersedia dapat didaftarkan di WORKSPACE
dengan
register_toolchains
atau di
command line dengan --extra_toolchains
.
Lihat di sini untuk mengetahui informasi selengkapnya.
Status
Dukungan platform saat ini bervariasi di antara berbagai bahasa. Semua aturan utama Bazel dipindahkan ke platform. Namun, proses ini akan memakan waktu. Hal ini dilakukan karena tiga alasan utama:
Logika aturan harus diperbarui untuk mendapatkan info alat dari toolchain API baru (
ctx.toolchains
) dan berhenti membaca setelan lama seperti--cpu
dan--crosstool_top
. Proses ini relatif mudah.Pengelola toolchain harus menentukan toolchain dan membuatnya dapat diakses oleh pengguna (di repositori GitHub dan entri
WORKSPACE
). Hal ini secara teknis mudah dilakukan, tetapi harus diatur secara cerdas untuk mempertahankan pengalaman pengguna yang mudah.Definisi platform juga diperlukan (kecuali jika Anda membangun untuk mesin yang sama dengan tempat Bazel berjalan). Secara umum, project harus menentukan platformnya sendiri.
Project yang ada harus dimigrasikan.
select()
dan transisi juga harus dimigrasikan. Inilah tantangan terbesarnya. Hal ini sangat sulit untuk project multi-bahasa (yang dapat gagal jika semua bahasa tidak dapat membaca--platforms
).
Jika mendesain set aturan baru, Anda harus mendukung platform sejak awal. Tindakan ini akan otomatis membuat aturan Anda kompatibel dengan aturan dan project lain, dengan nilai yang meningkat seiring dengan makin banyaknya penggunaan API platform.
Properti platform umum
Properti platform seperti OS
dan CPU
yang umum di seluruh project harus dideklarasikan di tempat terpusat yang standar. Hal ini mendorong kompatibilitas lintas project
dan lintas bahasa.
Misalnya, jika MyApp memiliki select()
di constraint_value
@myapp//cpus:arm
dan SomeCommonLib memiliki select()
di
@commonlib//constraints:arm
, keduanya akan memicu mode "arm" dengan kriteria
yang tidak kompatibel.
Properti umum global dideklarasikan di repositori
@platforms
(sehingga label kanonis untuk contoh di atas adalah @platforms//cpu:arm
).
Properti umum bahasa harus dideklarasikan di repositori masing-masing
bahasa.
Platform default
Secara umum, pemilik proyek harus menentukan
platform eksplisit untuk menjelaskan jenis
mesin yang ingin mereka bangun. Kemudian, fungsi ini dipicu dengan
--platforms
.
Jika --platforms
tidak ditetapkan, Bazel akan menggunakan platform
secara default yang merepresentasikan mesin build lokal. Ini dibuat secara otomatis di @local_config_platform//:host
sehingga tidak perlu didefinisikan secara eksplisit. Memetakan OS
dan CPU
komputer lokal dengan constraint_value
yang dideklarasikan di @platforms
.
C++
Aturan C++ Bazel menggunakan platform untuk memilih toolchain saat Anda menetapkan
--incompatible_enable_cc_toolchain_resolution
(#7260).
Artinya, Anda dapat mengonfigurasi project C++ dengan:
bazel build //:my_cpp_project --platforms=//:myplatform
bukan versi lama:
bazel build //:my_cpp_project` --cpu=... --crosstool_top=... --compiler=...
Jika project Anda adalah C++ murni dan tidak bergantung pada project non-C++, Anda dapat menggunakan platform dengan aman selama select
dan
transisi Anda kompatibel. Lihat
#7260 dan
Mengonfigurasi toolchain C++ untuk panduan selengkapnya.
Mode ini tidak diaktifkan secara default. Hal ini karena project Apple
masih mengonfigurasi dependensi C++ dengan --cpu
dan --crosstool_top
(contoh). Jadi, hal ini bergantung pada aturan Apple yang dimigrasikan ke platform.
Java
Aturan Java Bazel menggunakan platform.
Flag ini menggantikan flag lama --java_toolchain
, --host_java_toolchain
,
--javabase
, dan --host_javabase
.
Untuk mempelajari cara menggunakan flag konfigurasi, lihat panduan Bazel dan Java. Untuk informasi tambahan, lihat Dokumen desain.
Jika Anda masih menggunakan tanda lama, ikuti proses migrasi di Masalah #7849.
Android
Aturan Android Bazel menggunakan platform untuk memilih toolchain saat Anda menyetel
--incompatible_enable_android_toolchain_resolution
.
Fitur ini tidak diaktifkan secara default. Namun, migrasi sudah berjalan lancar.
Apple
Aturan Apple Bazel belum mendukung platform untuk memilih toolchain Apple.
Mereka juga tidak mendukung dependensi C++ yang diaktifkan platform karena menggunakan
--crosstool_top
lama untuk menyetel toolchain C++. Hingga dimigrasikan, Anda dapat menggabungkan project Apple dengan C++ yang diaktifkan platform dengan pemetaan platform
(contoh).
Bahasa lainnya
- Aturan Rust Bazel sepenuhnya mendukung platform.
- Aturan Go Bazel sepenuhnya mendukung platform (detail).
Jika Anda mendesain aturan untuk bahasa baru, gunakan platform untuk memilih toolchain bahasa Anda. Lihat dokumentasi toolchain untuk mengetahui panduan yang baik.
select()
Project dapat select()
di
target constraint_value
, tetapi tidak dapat diselesaikan di
platform. Hal ini disengaja agar select()
s mendukung sebanyak mungkin jenis komputer. Library dengan sumber khusus ARM
harus mendukung semua mesin yang didukung ARM
, kecuali ada alasan untuk lebih spesifik.
Untuk memilih satu atau beberapa constraint_value
, gunakan:
config_setting(
name = "is_arm",
constraint_values = [
"@platforms//cpu:arm",
],
)
Hal ini setara dengan memilih secara tradisional di --cpu
:
config_setting(
name = "is_arm",
values = {
"cpu": "arm",
},
)
Lihat detail selengkapnya di sini.
select
di --cpu
, --crosstool_top
, dll. tidak memahami --platforms
. Saat
memigrasikan project ke platform, Anda harus mengonversinya ke
constraint_values
atau menggunakan pemetaan platform untuk mendukung
kedua gaya melalui jendela migrasi.
Transisi
Transisi Starlark mengubah
bagian grafik build Anda. Jika project Anda menggunakan transisi yang menetapkan --cpu
, --crossstool_top
, atau flag lama lainnya, aturan yang membaca --platforms
tidak akan melihat perubahan ini.
Saat memigrasikan project ke platform, Anda harus mengonversi perubahan seperti
return { "//command_line_option:cpu": "arm" }
menjadi return {
"//command_line_option:platforms": "//:my_arm_platform" }
atau menggunakan pemetaan
platform untuk mendukung kedua gaya selama periode
migrasi.
Cara menggunakan platform saat ini
Jika hanya ingin membuat atau mengompilasi silang project, Anda harus mengikuti dokumentasi resmi project. Pengelola bahasa dan project yang akan menentukan cara dan waktu integrasi dengan platform, serta nilai yang ditawarkan.
Jika Anda adalah pengelola project, bahasa, atau toolchain dan build Anda tidak menggunakan platform secara default, Anda memiliki tiga opsi (selain menunggu migrasi global):
Aktifkan tanda "gunakan platform" untuk bahasa project Anda (jika memiliki satu) dan lakukan pengujian apa pun yang diperlukan untuk melihat apakah project yang Anda minati berfungsi.
Jika project yang Anda minati masih bergantung pada tanda lama seperti
--cpu
dan--crosstool_top
, gunakan tanda ini bersama dengan--platforms
:bazel build //:my_mixed_project --platforms==//:myplatform --cpu=... --crosstool_top=...
Hal ini memiliki biaya pemeliharaan (Anda harus memastikan setelan cocok secara manual). Namun, hal ini akan berfungsi tanpa adanya transisi yang tidak diinginkan.
Tulis pemetaan platform untuk mendukung kedua gaya dengan memetakan setelan gaya
--cpu
ke platform yang sesuai dan sebaliknya.
Pemetaan platform
Pemetaan platform adalah API sementara yang memungkinkan logika yang didukung platform dan logika yang didukung versi lama berjalan bersama dalam build yang sama selama periode penghentian penggunaan versi lama.
Pemetaan platform adalah peta platform()
ke set flag lama yang sesuai atau sebaliknya. Contoh:
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 menggunakannya untuk menjamin semua setelan, baik berbasis platform maupun lama, diterapkan secara konsisten di seluruh build, termasuk melalui transisi.
Secara default, Bazel membaca pemetaan dari file platform_mappings
di root ruang kerja Anda. Anda juga dapat menetapkan
--platform_mappings=//:my_custom_mapping
.
Lihat di sini untuk mengetahui detail selengkapnya.
Pertanyaan
Untuk dukungan umum dan pertanyaan tentang jadwal migrasi, hubungi bazel-discuss@googlegroups.com atau pemilik aturan yang sesuai.
Untuk diskusi tentang desain dan evolusi API platform/toolchain, hubungi bazel-dev@googlegroups.com.