Bazel dapat mem-build dan menguji kode pada berbagai hardware, sistem operasi, dan konfigurasi sistem, menggunakan berbagai versi alat build seperti linker dan compiler. Untuk membantu mengelola kompleksitas ini, Bazel memiliki konsep batasan dan platform. Batasan adalah dimensi yang membedakan lingkungan build atau produksi, seperti arsitektur CPU, keberadaan atau ketiadaan GPU, atau versi compiler yang diinstal oleh sistem. Platform adalah kumpulan pilihan bernama untuk batasan ini, yang mewakili resource tertentu yang tersedia di beberapa lingkungan.
Pemodelan lingkungan sebagai platform membantu Bazel otomatis memilih Toolchain yang sesuai untuk tindakan build. Platform juga dapat digunakan bersama dengan aturan config_setting untuk menulis atribut yang dapat dikonfigurasi.
Bazel menyadari tiga peran yang dapat dilayani oleh platform:
- Host - platform tempat Bazel itu sendiri berjalan.
- Execution - platform tempat alat build mengeksekusi tindakan build untuk menghasilkan output menengah dan akhir.
- Target - platform tempat output akhir berada dan dieksekusi.
Bazel mendukung skenario build terkait platform berikut:
Build satu platform (default) - host, eksekusi, dan platform target sama. Misalnya, mem-build file Linux yang dapat dieksekusi di Ubuntu yang berjalan pada CPU Intel x64.
Build lintas kompilasi - platform host dan eksekusi sama, tetapi platform target berbeda. Misalnya, mem-build aplikasi iOS di macOS yang berjalan di MacBook Pro.
Build multi-platform - platform host, eksekusi, dan target berbeda.
Menentukan batasan dan platform
Ruang kemungkinan pilihan untuk platform ditentukan dengan menggunakan aturan constraint_setting
dan constraint_value
dalam file BUILD
. constraint_setting
membuat dimensi baru, sementara constraint_value
membuat nilai baru untuk dimensi tertentu; bersama-sama keduanya
menentukan enum dan nilai yang memungkinkan secara efektif. Misalnya, cuplikan
file BUILD
berikut memperkenalkan batasan untuk versi glibc sistem
dengan dua kemungkinan nilai.
constraint_setting(name = "glibc_version")
constraint_value(
name = "glibc_2_25",
constraint_setting = ":glibc_version",
)
constraint_value(
name = "glibc_2_26",
constraint_setting = ":glibc_version",
)
Batasan dan nilainya dapat ditentukan di berbagai paket dalam ruang kerja. Keduanya direferensikan menurut label dan tunduk pada kontrol visibilitas biasa. Jika visibilitas memungkinkan, Anda dapat memperluas setelan batasan yang ada dengan menentukan nilai Anda sendiri.
Aturan platform
memperkenalkan platform baru dengan
pilihan nilai batasan tertentu. Berikut
akan membuat platform bernama linux_x86
, dan mengatakan bahwa lingkungan tersebut
menjalankan lingkungan apa pun yang menjalankan sistem operasi Linux pada arsitektur x86_64 dengan
versi glibc 2.25. (Lihat di bawah untuk informasi selengkapnya tentang batasan bawaan Bazel.)
platform(
name = "linux_x86",
constraint_values = [
"@platforms//os:linux",
"@platforms//cpu:x86_64",
":glibc_2_25",
],
)
Batasan dan platform yang umumnya berguna
Agar ekosistem tetap konsisten, tim Bazel mengelola repositori dengan definisi batasan untuk arsitektur dan sistem operasi CPU yang paling populer. Semua referensi tersebut ada di https://github.com/bazelbuild/platforms.
Bazel dikirimkan dengan definisi platform khusus berikut:
@local_config_platform//:host
. Ini adalah nilai platform host yang terdeteksi otomatis -
mewakili platform yang terdeteksi otomatis untuk sistem yang dijalankan oleh Bazel.
Menentukan platform untuk build
Anda dapat menentukan platform host dan target untuk build menggunakan tanda command line berikut:
--host_platform
- ditetapkan secara default ke@bazel_tools//platforms:host_platform
--platforms
- ditetapkan secara default ke@bazel_tools//platforms:target_platform
Melewati target yang tidak kompatibel
Saat membuat aplikasi untuk platform target tertentu, Anda sebaiknya melewati target yang tidak akan pernah berfungsi di platform tersebut. Misalnya, driver perangkat Windows Anda
mungkin akan menghasilkan banyak error compiler saat mem-build pada
mesin Linux dengan //...
. Gunakan atribut
target_compatible_with
untuk memberi tahu Bazel batasan platform target yang dimiliki kode Anda.
Penggunaan atribut ini yang paling sederhana membatasi target ke satu platform.
Target tidak akan dibuat untuk platform apa pun yang tidak memenuhi semua
batasan. Contoh berikut membatasi win_driver_lib.cc
ke Windows
64-bit.
cc_library(
name = "win_driver_lib",
srcs = ["win_driver_lib.cc"],
target_compatible_with = [
"@platforms//cpu:x86_64",
"@platforms//os:windows",
],
)
:win_driver_lib
hanya kompatibel untuk mem-build aplikasi dengan Windows 64-bit dan tidak kompatibel dengan Windows lainnya. Inkompatibilitas bersifat transitif. Setiap target
yang secara transitif bergantung pada target yang tidak kompatibel akan dianggap
tidak kompatibel.
Kapan target dilewati?
Target akan dilewati jika dianggap tidak kompatibel dan disertakan dalam build sebagai bagian dari perluasan pola target. Misalnya, dua panggilan berikut akan melewati target yang tidak kompatibel yang ditemukan dalam perluasan pola target.
$ bazel build --platforms=//:myplatform //...
$ bazel build --platforms=//:myplatform //:all
Pengujian yang tidak kompatibel di test_suite
juga
dilewati jika test_suite
ditentukan pada command line dengan
--expand_test_suites
.
Dengan kata lain, target test_suite
pada command line berperilaku seperti :all
dan
...
. Penggunaan --noexpand_test_suites
akan mencegah perluasan dan menyebabkan target test_suite
dengan pengujian yang tidak kompatibel juga tidak kompatibel.
Menentukan target yang tidak kompatibel secara eksplisit pada command line akan menghasilkan pesan error dan build gagal.
$ bazel build --platforms=//:myplatform //:target_incompatible_with_myplatform
...
ERROR: Target //:target_incompatible_with_myplatform is incompatible and cannot be built, but was explicitly requested.
...
FAILED: Build did NOT complete successfully
Target eksplisit yang tidak kompatibel akan dilewati secara diam-diam jika --skip_incompatible_explicit_targets
diaktifkan.
Batasan lebih ekspresif
Untuk fleksibilitas yang lebih tinggi dalam mengekspresikan batasan, gunakan
@platforms//:incompatible
constraint_value
yang tidak memiliki kepuasan
platform.
Gunakan select()
bersama dengan
@platforms//:incompatible
untuk mengekspresikan batasan yang lebih rumit. Misalnya, gunakan untuk mengimplementasikan logika OR dasar. Baris berikut menandai library
yang kompatibel dengan macOS dan Linux, tetapi tidak memiliki platform lain.
cc_library(
name = "unixish_lib",
srcs = ["unixish_lib.cc"],
target_compatible_with = select({
"@platforms//os:osx": [],
"@platforms//os:linux": [],
"//conditions:default": ["@platforms//:incompatible"],
}),
)
Hal di atas dapat ditafsirkan sebagai berikut:
- Saat menargetkan macOS, target tidak memiliki batasan.
- Ketika menargetkan Linux, target tidak memiliki batasan.
- Jika tidak, target memiliki batasan
@platforms//:incompatible
. Karena@platforms//:incompatible
bukan bagian dari platform apa pun, targetnya dianggap tidak kompatibel.
Agar batasan Anda lebih mudah dibaca, gunakan
selects.with_or()
skylib.
Anda dapat mengekspresikan kompatibilitas terbalik dengan cara yang sama. Contoh berikut menjelaskan library yang kompatibel dengan semuanya kecuali untuk ARM.
cc_library(
name = "non_arm_lib",
srcs = ["non_arm_lib.cc"],
target_compatible_with = select({
"@platforms//cpu:arm": ["@platforms//:incompatible"],
"//conditions:default": [],
}),
)
Mendeteksi target yang tidak kompatibel menggunakan bazel cquery
Anda dapat menggunakan
IncompatiblePlatformProvider
dalam format output
Starlark bazel cquery
untuk membedakan
target yang tidak kompatibel dengan target yang kompatibel.
Ini dapat digunakan untuk memfilter target yang tidak kompatibel. Contoh di bawah hanya akan mencetak label untuk target yang kompatibel. Target yang tidak kompatibel tidak akan dicetak.
$ cat example.cquery
def format(target):
if "IncompatiblePlatformProvider" not in providers(target):
return target.label
return ""
$ bazel cquery //... --output=starlark --starlark:file=example.cquery
Masalah Umum
Target yang tidak kompatibel mengabaikan pembatasan visibilitas.