Bermigrasi ke Platform

Laporkan masalah Lihat sumber

Bazel memiliki dukungan canggih untuk pemodelan platform dan toolchain untuk multi-arsitektur dan build yang dikompilasi silang.

Halaman ini merangkum status dukungan ini.

Lihat juga:

Status

C++

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

Ini berarti Anda dapat mengonfigurasi project C++ dengan:

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

bukan yang lama:

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

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

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

Java

Aturan Java menggunakan platform untuk memilih toolchain.

Ini menggantikan tanda 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.

Ini berarti Anda dapat mengonfigurasi project Android dengan:

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

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

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

Untuk menguji project Android Anda dengan platform, lihat Memigrasi Project.

Apel

Aturan Apple tidak mendukung platform dan belum dijadwalkan untuk dukungan.

Anda masih 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 yang berbeda dan mengompilasi silang.

Cara ini terinspirasi oleh pengamatan bahwa pengelola bahasa sudah melakukan ini secara khusus dan tidak kompatibel. Misalnya, aturan C++ menggunakan --cpu dan --crosstool_top untuk mendeklarasikan CPU dan toolchain target. Tak satu pun dari ini yang memodelkan "platform" dengan benar. Hal ini menghasilkan build yang canggung dan salah.

Java, Android, dan bahasa lain mengembangkan flagnya sendiri untuk tujuan serupa, tidak ada yang saling bekerja sama. Hal ini membuat build lintas bahasa membingungkan dan rumit.

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

Perlu migrasi

Upgrade ke API yang baru memerlukan dua upaya: merilis API dan mengupgrade logika aturan agar dapat menggunakannya.

Tugas yang pertama sudah selesai, tetapi yang kedua sedang 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 API baru, bukan flag lama.

Pekerjaan ini mudah dilakukan, tetapi memerlukan upaya yang berbeda untuk setiap bahasa, ditambah peringatan yang wajar bagi pemilik project untuk melakukan pengujian terhadap perubahan mendatang.

Itulah sebabnya mengapa proses ini adalah migrasi berkelanjutan.

Sasaran

Migrasi ini selesai ketika semua project di-build dengan formulir:

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

Hal ini menyiratkan:

  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 dari 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 repositori project Anda jika platform tersebut unik untuk project Anda, atau di beberapa tempat umum yang dapat ditemukan oleh semua project yang menggunakannya

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

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

Memigrasikan project Anda

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 detail selengkapnya.

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

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

  1. //:myplatform harus ada. Umumnya pemilik proyek bertanggung jawab untuk menentukan platform karena proyek yang berbeda menargetkan komputer 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 sendiri, Anda perlu register dalam file MODULE.bazel atau dengan --extra_toolchains.

  3. select() dan transisi konfigurasi harus diselesaikan dengan benar. Lihat select() dan Transitions.

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

Jika Anda masih mengalami masalah, hubungi dukungan.

Platform default

Pemilik project harus menentukan platform eksplisit untuk mendeskripsikan arsitektur yang ingin mereka bangun. Hal ini kemudian dipicu dengan --platforms.

Jika --platforms tidak ditetapkan, Bazel akan ditetapkan secara default ke platform yang mewakili mesin build lokal. Nama ini dibuat secara otomatis di @local_config_platform//:host sehingga tidak perlu menentukannya secara eksplisit. Fungsi ini memetakan OS dan CPU komputer lokal dengan constraint_value yang dideklarasikan di @platforms.

select()

Project dapat select() pada 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 ada alasan yang lebih spesifik.

Untuk memilih di satu atau beberapa constraint_value, gunakan:

config_setting(
    name = "is_arm",
    constraint_values = [
        "@platforms//cpu:arm",
    ],
)

Hal ini sama 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 menjadi constraint_values atau menggunakan pemetaan platform untuk mendukung kedua gaya selama migrasi.

Transisi

Perubahan Transisi Starlark akan menandai bagian-bagian grafik build Anda ke bawah. Jika project Anda menggunakan transisi yang menetapkan --cpu, --crossstool_top, atau tanda 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 migrasi.

Memigrasikan kumpulan aturan

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

  1. Meminta logika aturan menyelesaikan toolchain dengan API toolchain. Lihat Toolkit API (ctx.toolchains).

  2. Opsional: tentukan tanda --incompatible_enable_platforms_for_my_language sehingga logika aturan akan secara alternatif menyelesaikan toolchain melalui API baru atau flag lama seperti --crosstool_top selama pengujian migrasi.

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

  4. Tentukan toolchain standar dan buat agar 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 sulit untuk project multibahasa (yang mungkin akan 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 umum seperti OS dan CPU harus dideklarasikan di @platforms. Hal ini mendorong aktivitas berbagi, standardisasi, dan kompatibilitas lintas bahasa.

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

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

Pemetaan platform

Pemetaan platform adalah API sementara yang memungkinkan logika berbasis platform bercampur dengan logika lama dalam build yang sama. Alat ini adalah alat tumpul yang hanya dimaksudkan untuk menghaluskan inkompatibilitas dengan jangka waktu migrasi yang berbeda.

Pemetaan platform adalah peta platform() ke kumpulan tanda 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 menggunakan ini 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 constraint_value target:

platform(
    name = "myplatform",
    constraint_values = [
        "@platforms//os:linux",
        "@platforms//cpu:arm",
    ],
)

constraint_value adalah properti mesin. Nilai "jenis" yang sama dikelompokkan ke 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 di-build dengan alat ini.

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

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

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

Untuk informasi selengkapnya, lihat di sini.

Pertanyaan

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

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

Lihat juga