Bermigrasi ke Platform

Laporkan masalah Lihat sumber Nightly · 8.0 · 7.4 · 7.3 · 7.2 · 7.1 · 7.0 · 6.5

Bazel memiliki dukungan yang canggih untuk membuat model platform dan toolchain untuk build multi-arsitektur dan lintas kompilasi.

Halaman ini merangkum status dukungan ini.

Lihat juga:

Status

C++

Aturan C++ menggunakan platform untuk memilih toolchain saat --incompatible_enable_cc_toolchain_resolution ditetapkan.

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=...

Hal ini akan diaktifkan secara default di Bazel 7.0 (#7260).

Untuk menguji project C++ dengan platform, lihat Memigrasikan Project Anda dan Mengonfigurasi toolchain C++.

Java

Aturan Java menggunakan platform untuk memilih toolchain.

Ini menggantikan flag lama --java_toolchain, --host_java_toolchain, --javabase, dan --host_javabase.

Lihat Java dan Bazel untuk mengetahui detailnya.

Android

Aturan Android menggunakan platform untuk memilih toolchain saat --incompatible_enable_android_toolchain_resolution ditetapkan.

Artinya, Anda dapat mengonfigurasi project Android dengan:

bazel build //:my_android_project --android_platforms=//:my_android_platform

bukan dengan flag lama seperti --android_crosstool_top, --android_cpu, dan --fat_apk_cpu.

Fitur ini akan diaktifkan secara default di Bazel 7.0 (#16285).

Untuk menguji project Android dengan platform, lihat Memigrasikan Project.

Apple

Aturan Apple tidak mendukung platform dan belum dijadwalkan untuk dukungan.

Anda tetap dapat menggunakan API platform dengan build Apple (misalnya, saat mem-build dengan campuran aturan Apple dan C++ murni) dengan pemetaan platform.

Bahasa lainnya

Jika Anda memiliki kumpulan aturan bahasa, lihat Memigrasikan kumpulan aturan untuk menambahkan dukungan.

Latar belakang

Platform dan toolchain diperkenalkan untuk menstandarkan cara project software menargetkan arsitektur dan melakukan cross-compile yang berbeda.

Hal 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 mendeklarasikan CPU dan toolchain target. Tidak satu pun dari kedua hal ini yang membuat model "platform" dengan benar. Hal ini menghasilkan build yang canggung dan salah.

Java, Android, dan bahasa lainnya mengembangkan flag mereka sendiri untuk tujuan serupa, dan tidak ada yang saling berinteraksi. Hal ini membuat build lintas bahasa menjadi membingungkan dan rumit.

Bazel ditujukan untuk project multi-platform, multi-bahasa, dan besar. Hal ini memerlukan dukungan yang lebih mendasar untuk konsep ini, termasuk API standar yang jelas.

Kebutuhan migrasi

Mengupgrade ke API baru memerlukan dua upaya: merilis API dan mengupgrade logika aturan untuk menggunakannya.

Yang pertama sudah selesai, tetapi yang kedua masih berlangsung. Hal ini terdiri dari memastikan platform dan toolchain khusus bahasa ditentukan, logika bahasa membaca toolchain melalui API baru, bukan flag lama seperti --crosstool_top, dan config_setting memilih pada API baru, bukan flag lama.

Pekerjaan ini mudah, tetapi memerlukan upaya yang berbeda untuk setiap bahasa, serta peringatan yang adil bagi pemilik project untuk menguji perubahan mendatang.

Itulah sebabnya migrasi ini masih berlangsung.

Sasaran

Migrasi ini selesai saat semua project di-build dengan bentuk:

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

Hal ini berarti:

  1. Aturan project Anda memilih toolchain yang tepat untuk //:myplatform.
  2. Dependensi project Anda memilih toolchain yang tepat untuk //:myplatform.
  3. //:myplatform mereferensikan deklarasi umum CPU, OS, dan properti umum lainnya yang tidak bergantung pada bahasa
  4. Semua select() yang relevan cocok dengan //:myplatform.
  5. //:myplatform ditentukan di tempat yang jelas dan dapat diakses: di repo project Anda jika platform tersebut unik untuk project Anda, atau beberapa tempat umum yang dapat ditemukan oleh semua project yang menggunakannya

Flag lama seperti --cpu, --crosstool_top, dan --fat_apk_cpu akan tidak digunakan lagi dan dihapus segera setelah aman untuk melakukannya.

Pada akhirnya, ini akan menjadi cara satu-satunya untuk mengonfigurasi arsitektur.

Memigrasikan project

Jika Anda mem-build dengan bahasa yang mendukung platform, build Anda seharusnya sudah berfungsi dengan pemanggilan seperti:

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

Lihat Status dan dokumentasi bahasa Anda untuk mengetahui detail yang akurat.

Jika bahasa memerlukan flag untuk mengaktifkan dukungan platform, Anda juga perlu menetapkan flag tersebut. Lihat Status untuk mengetahui detailnya.

Agar project dapat di-build, Anda perlu memeriksa hal berikut:

  1. //:myplatform harus ada. Umumnya, pemilik project bertanggung jawab untuk menentukan platform karena project yang berbeda menargetkan mesin yang berbeda. Lihat Platform default.

  2. toolchain yang ingin Anda gunakan harus ada. Jika menggunakan toolchain stok, pemilik bahasa harus menyertakan petunjuk cara mendaftarkannya. Jika menulis toolchain kustom Anda sendiri, Anda harus mendaftarkannya dalam file MODULE.bazel atau dengan --extra_toolchains.

  3. select() dan transisi konfigurasi harus di-resolve dengan benar. Lihat select() dan Transisi.

  4. Jika build Anda menggabungkan bahasa yang mendukung dan tidak mendukung platform, Anda mungkin memerlukan pemetaan platform untuk membantu bahasa lama berfungsi dengan API baru. Lihat Pemetaan platform untuk mengetahui detailnya.

Jika Anda masih mengalami masalah, hubungi kami untuk mendapatkan dukungan.

Platform default

Pemilik project harus menentukan platform eksplisit untuk mendeskripsikan arsitektur yang ingin mereka buat. Kemudian, fungsi ini dipicu dengan --platforms.

Jika --platforms tidak ditetapkan, Bazel akan ditetapkan secara default ke platform yang mewakili mesin build lokal. Ini dibuat secara otomatis di @platforms//host (alias sebagai @bazel_tools//tools:host_platform) sehingga Anda tidak perlu menentukannya secara eksplisit. Fungsi ini memetakan OS dan CPU mesin lokal dengan constraint_value yang dideklarasikan di @platforms.

select()

Project dapat select() di target constraint_value, tetapi tidak dapat menyelesaikan platform. Hal ini disengaja agar select() mendukung berbagai mesin sebanyak mungkin. Library dengan sumber khusus ARM harus mendukung semua mesin yang didukung ARM, kecuali jika 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 tersebut selama migrasi.

Transisi

Transisi Starlark mengubah tanda di 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" } ke return { "//command_line_option:platforms": "//:my_arm_platform" } atau menggunakan pemetaan platform untuk mendukung kedua gaya selama periode migrasi.

Memigrasikan kumpulan aturan

Jika Anda memiliki kumpulan aturan dan ingin mendukung platform, Anda harus:

  1. Meminta logika aturan me-resolve toolchain dengan toolchain API. Lihat toolchain API (ctx.toolchains).

  2. Opsional: tentukan tanda --incompatible_enable_platforms_for_my_language sehingga logika aturan secara bergantian me-resolve toolchain melalui API baru atau tanda lama seperti --crosstool_top selama pengujian migrasi.

  3. Tentukan properti yang relevan yang membentuk komponen platform. Lihat Properti platform umum

  4. Tentukan toolchain standar dan buat toolchain tersebut dapat diakses oleh pengguna melalui petunjuk pendaftaran aturan Anda (detail)

  5. Pastikan select() dan transisi konfigurasi mendukung platform. Ini adalah tantangan terbesar. Hal ini sangat menantang untuk project multibahasa (yang dapat gagal jika semua bahasa tidak dapat membaca --platforms).

Jika perlu menggabungkan dengan aturan yang tidak mendukung platform, Anda mungkin memerlukan pemetaan platform untuk menjembatani kesenjangan tersebut.

Properti platform umum

Properti platform lintas bahasa yang umum seperti OS dan CPU harus dideklarasikan di @platforms. Hal ini mendorong pembagian, standardisasi, dan kompatibilitas lintas bahasa.

Properti yang unik untuk aturan Anda harus dideklarasikan di repo aturan. Hal ini memungkinkan Anda mempertahankan kepemilikan yang jelas atas konsep tertentu yang menjadi tanggung jawab aturan Anda.

Jika aturan Anda menggunakan OS atau CPU tujuan khusus, aturan tersebut harus dideklarasikan di repo aturan vs. @platforms.

Pemetaan platform

Pemetaan platform adalah API sementara yang memungkinkan logika berbasis platform digabungkan dengan logika lama dalam build yang sama. Ini adalah alat yang tidak efektif yang hanya ditujukan untuk memperlancar ketidakcocokan dengan jangka waktu migrasi yang berbeda.

Pemetaan platform adalah peta platform() ke kumpulan flag lama yang sesuai atau sebaliknya. Contoh:

platforms:
  # Maps "--platforms=//platforms:ios" to "--ios_multi_cpus=x86_64 --apple_platform_type=ios".
  //platforms:ios
    --ios_multi_cpus=x86_64
    --apple_platform_type=ios

flags:
  # Maps "--ios_multi_cpus=x86_64 --apple_platform_type=ios" to "--platforms=//platforms:ios".
  --ios_multi_cpus=x86_64
  --apple_platform_type=ios
    //platforms:ios

  # Maps "--cpu=darwin_x86_64 --apple_platform_type=macos" to "//platform:macos".
  --cpu=darwin_x86_64
  --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 desain pemetaan platform untuk mengetahui detailnya.

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 umum:

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"). Penyedia-nya meneruskan informasi ini ke aturan yang perlu dibuat dengan alat ini.

Toolchain mendeklarasikan constraint_value mesin yang dapat ditargetkan (target_compatible_with = ["@platforms//os:linux"]) dan mesin yang dapat dijalankan (exec_compatible_with = ["@platforms//os:mac"]) oleh alat mereka.

Saat mem-build $ bazel build //:myproject --platforms=//:myplatform, Bazel otomatis memilih toolchain yang dapat berjalan di mesin build dan mem-build biner untuk //:myplatform. Hal ini dikenal sebagai resolusi toolchain.

Kumpulan toolchain yang tersedia dapat didaftarkan dalam file MODULE.bazel dengan register_toolchains atau di command line dengan --extra_toolchains.

Untuk informasi selengkapnya, lihat di sini.

Pertanyaan

Untuk dukungan umum dan pertanyaan tentang linimasa migrasi, hubungi bazel-discuss atau pemilik aturan yang sesuai.

Untuk diskusi tentang desain dan evolusi API platform/toolchain, hubungi bazel-dev.

Lihat juga